Remove unused 3rdparty library

This commit is contained in:
andrea reale
2022-02-17 12:20:32 +01:00
committed by wmayer
parent 7dffaf1955
commit 84626aaab9
122 changed files with 0 additions and 77040 deletions

View File

@@ -1,364 +0,0 @@
# Microsoft Developer Studio Project File - Name="CxImage" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=CxImage - Win32 Unicode 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 "cximage.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 "cximage.mak" CFG="CxImage - Win32 Unicode Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "CxImage - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "CxImage - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "CxImage - Win32 Unicode Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "CxImage - Win32 Unicode Release" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "CxImage - 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 2
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\jpeg" /I "..\png" /I "..\zlib" /I "..\mng" /I "..\tiff" /I "..\j2k" /I "..\jasper\include" /D "WIN32" /D "_DEBUG" /D "_LIB" /D "JAS_WIN_MSVC_BUILD" /D "_CRT_SECURE_NO_DEPRECATE" /FD /GZ /c
# SUBTRACT CPP /Fr /YX
# ADD BASE RSC /l 0x410 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "CxImage - 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 2
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\jpeg" /I "..\png" /I "..\zlib" /I "..\mng" /I "..\tiff" /I "..\j2k" /I "..\jasper\include" /D "WIN32" /D "NDEBUG" /D "_LIB" /D "JAS_WIN_MSVC_BUILD" /D "_CRT_SECURE_NO_DEPRECATE" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x410 /d "NDEBUG"
# ADD RSC /l 0x809 /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)" == "CxImage - Win32 Unicode Debug"
# PROP BASE Use_MFC 2
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "CxImage___Win32_Unicode_Debug"
# PROP BASE Intermediate_Dir "CxImage___Win32_Unicode_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 2
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Unicode_Debug"
# PROP Intermediate_Dir "Unicode_Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\jpeg" /I "..\png" /I "..\zlib" /I "..\mng" /I "..\tiff" /I "..\j2k" /I "..\jasper\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "_AFXDLL" /D "JAS_WIN_MSVC_BUILD" /FD /GZ /c
# SUBTRACT BASE CPP /Fr /YX
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\jpeg" /I "..\png" /I "..\zlib" /I "..\mng" /I "..\tiff" /I "..\j2k" /I "..\jasper\include" /D "_LIB" /D "JAS_WIN_MSVC_BUILD" /D "WIN32" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NON_CONFORMING_SWPRINTFS" /FD /GZ /c
# SUBTRACT CPP /Fr /YX
# ADD BASE RSC /l 0x410 /d "_DEBUG" /d "_AFXDLL"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "CxImage - Win32 Unicode Release"
# PROP BASE Use_MFC 2
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "CxImage___Win32_Unicode_Release"
# PROP BASE Intermediate_Dir "CxImage___Win32_Unicode_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 2
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Unicode_Release"
# PROP Intermediate_Dir "Unicode_Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "..\jpeg" /I "..\png" /I "..\zlib" /I "..\mng" /I "..\tiff" /I "..\j2k" /I "..\jasper\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "_AFXDLL" /D "JAS_WIN_MSVC_BUILD" /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\jpeg" /I "..\png" /I "..\zlib" /I "..\mng" /I "..\tiff" /I "..\j2k" /I "..\jasper\include" /D "_LIB" /D "JAS_WIN_MSVC_BUILD" /D "WIN32" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NON_CONFORMING_SWPRINTFS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x410 /d "NDEBUG" /d "_AFXDLL"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "CxImage - Win32 Debug"
# Name "CxImage - Win32 Release"
# Name "CxImage - Win32 Unicode Debug"
# Name "CxImage - Win32 Unicode Release"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\tif_xfile.cpp
# End Source File
# Begin Source File
SOURCE=.\ximabmp.cpp
# End Source File
# Begin Source File
SOURCE=.\ximadsp.cpp
# End Source File
# Begin Source File
SOURCE=.\ximaenc.cpp
# End Source File
# Begin Source File
SOURCE=.\ximaexif.cpp
# End Source File
# Begin Source File
SOURCE=.\xImage.cpp
# End Source File
# Begin Source File
SOURCE=.\ximagif.cpp
# End Source File
# Begin Source File
SOURCE=.\ximahist.cpp
# End Source File
# Begin Source File
SOURCE=.\ximaico.cpp
# End Source File
# Begin Source File
SOURCE=.\ximainfo.cpp
# End Source File
# Begin Source File
SOURCE=.\ximaint.cpp
# End Source File
# Begin Source File
SOURCE=.\ximajas.cpp
# End Source File
# Begin Source File
SOURCE=.\ximajbg.cpp
# End Source File
# Begin Source File
SOURCE=.\ximajpg.cpp
# End Source File
# Begin Source File
SOURCE=.\ximalpha.cpp
# End Source File
# Begin Source File
SOURCE=.\ximalyr.cpp
# End Source File
# Begin Source File
SOURCE=.\ximamng.cpp
# End Source File
# Begin Source File
SOURCE=.\ximapal.cpp
# End Source File
# Begin Source File
SOURCE=.\ximapcx.cpp
# End Source File
# Begin Source File
SOURCE=.\ximapng.cpp
# End Source File
# Begin Source File
SOURCE=.\ximaraw.cpp
# End Source File
# Begin Source File
SOURCE=.\ximasel.cpp
# End Source File
# Begin Source File
SOURCE=.\ximaska.cpp
# End Source File
# Begin Source File
SOURCE=.\ximatga.cpp
# End Source File
# Begin Source File
SOURCE=.\ximath.cpp
# End Source File
# Begin Source File
SOURCE=.\ximatif.cpp
# End Source File
# Begin Source File
SOURCE=.\ximatran.cpp
# End Source File
# Begin Source File
SOURCE=.\ximawbmp.cpp
# End Source File
# Begin Source File
SOURCE=.\ximawmf.cpp
# End Source File
# Begin Source File
SOURCE=.\ximawnd.cpp
# End Source File
# Begin Source File
SOURCE=.\xmemfile.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\xfile.h
# End Source File
# Begin Source File
SOURCE=.\ximabmp.h
# End Source File
# Begin Source File
SOURCE=.\ximacfg.h
# End Source File
# Begin Source File
SOURCE=.\ximadef.h
# End Source File
# Begin Source File
SOURCE=.\ximage.h
# End Source File
# Begin Source File
SOURCE=.\ximagif.h
# End Source File
# Begin Source File
SOURCE=.\ximaico.h
# End Source File
# Begin Source File
SOURCE=.\ximaiter.h
# End Source File
# Begin Source File
SOURCE=.\ximajas.h
# End Source File
# Begin Source File
SOURCE=.\ximajbg.h
# End Source File
# Begin Source File
SOURCE=.\ximajpg.h
# End Source File
# Begin Source File
SOURCE=.\ximamng.h
# End Source File
# Begin Source File
SOURCE=.\ximapcx.h
# End Source File
# Begin Source File
SOURCE=.\ximapng.h
# End Source File
# Begin Source File
SOURCE=.\ximaraw.h
# End Source File
# Begin Source File
SOURCE=.\ximaska.h
# End Source File
# Begin Source File
SOURCE=.\ximatga.h
# End Source File
# Begin Source File
SOURCE=.\ximath.h
# End Source File
# Begin Source File
SOURCE=.\ximatif.h
# End Source File
# Begin Source File
SOURCE=.\ximawbmp.h
# End Source File
# Begin Source File
SOURCE=.\ximawmf.h
# End Source File
# Begin Source File
SOURCE=.\xiofile.h
# End Source File
# Begin Source File
SOURCE=.\xmemfile.h
# End Source File
# End Group
# End Target
# End Project

View File

@@ -1,29 +0,0 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "CxImage"=.\CxImage.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

File diff suppressed because it is too large Load Diff

View File

@@ -1,48 +0,0 @@
This copy of the CxImage notices is provided for your convenience. In case of
any discrepancy between this copy and the notices in the file ximage.h that is
included in the CxImage distribution, the latter shall prevail.
If you modify CxImage you may insert additional notices immediately following
this sentence.
--------------------------------------------------------------------------------
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
CxImage version 6.0.0 02/Feb/2008
CxImage : Copyright (C) 2001 - 2008, Davide Pizzolato
Original CImage and CImageIterator implementation are:
Copyright (C) 1995, Alejandro Aguilar Sierra (asierra(at)servidor(dot)unam(dot)mx)
Covered code is provided under this license on an "as is" basis, without warranty
of any kind, either expressed or implied, including, without limitation, warranties
that the covered code is free of defects, merchantable, fit for a particular purpose
or non-infringing. The entire risk as to the quality and performance of the covered
code is with you. Should any covered code prove defective in any respect, you (not
the initial developer or any other contributor) assume the cost of any necessary
servicing, repair or correction. This disclaimer of warranty constitutes an essential
part of this license. No use of any covered code is authorized hereunder except under
this disclaimer.
Permission is hereby granted to use, copy, modify, and distribute this
source code, or portions hereof, for any purpose, including commercial applications,
freely and without fee, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
--------------------------------------------------------------------------------
Other information: about CxImage, and the latest version, can be found at the
CxImage home page: http://www.xdp.it
--------------------------------------------------------------------------------

View File

@@ -1,218 +0,0 @@
/*
* TIFF file IO, using CxFile.
*/
#ifdef WIN32
#include <windows.h>
#endif
#include <stdio.h>
#include "ximage.h"
#if CXIMAGE_SUPPORT_TIF
#include "../tiff/tiffiop.h"
#include "xfile.h"
static tsize_t
_tiffReadProcEx(thandle_t fd, tdata_t buf, tsize_t size)
{
return (tsize_t)((CxFile*)fd)->Read(buf, 1, size);
}
static tsize_t
_tiffWriteProcEx(thandle_t fd, tdata_t buf, tsize_t size)
{
return (tsize_t)((CxFile*)fd)->Write(buf, 1, size);
}
static toff_t
_tiffSeekProcEx(thandle_t fd, toff_t off, int whence)
{
if ( off == 0xFFFFFFFF )
return 0xFFFFFFFF;
if (!((CxFile*)fd)->Seek(off, whence))
return 0xFFFFFFFF;
if (whence == SEEK_SET)
return off;
return (toff_t)((CxFile*)fd)->Tell();
}
// Return nonzero if error
static int
_tiffCloseProcEx(thandle_t /*fd*/)
{
// return !((CxFile*)fd)->Close(); // "//" needed for memory files <DP>
return 0;
}
#include <sys/stat.h>
static toff_t
_tiffSizeProcEx(thandle_t fd)
{
return ((CxFile*)fd)->Size();
}
static int
_tiffMapProcEx(thandle_t /*fd*/, tdata_t* /*pbase*/, toff_t* /*psize*/)
{
return (0);
}
static void
_tiffUnmapProcEx(thandle_t /*fd*/, tdata_t /*base*/, toff_t /*size*/)
{
}
// Open a TIFF file descriptor for read/writing.
/*
TIFF*
TIFFOpen(const char* name, const char* mode)
{
static const char module[] = "TIFFOpen";
FILE* stream = fopen(name, mode);
if (stream == NULL)
{
TIFFError(module, "%s: Cannot open", name);
return NULL;
}
return (TIFFFdOpen((int)stream, name, mode));
}
*/
TIFF*
_TIFFFdOpen(void* fd, const char* name, const char* mode)
{
TIFF* tif;
tif = TIFFClientOpen(name, mode,
(thandle_t) fd,
_tiffReadProcEx, _tiffWriteProcEx, _tiffSeekProcEx, _tiffCloseProcEx,
_tiffSizeProcEx, _tiffMapProcEx, _tiffUnmapProcEx);
if (tif)
tif->tif_fd = fd;
return (tif);
}
extern "C" TIFF* _TIFFOpenEx(CxFile* stream, const char* mode)
{
return (_TIFFFdOpen(stream, "TIFF IMAGE", mode));
}
#ifdef __GNUC__
extern char* malloc();
extern char* realloc();
#else
#include <malloc.h>
#endif
tdata_t
_TIFFmalloc(tsize_t s)
{
return (malloc((size_t) s));
}
void
_TIFFfree(tdata_t p)
{
free(p);
}
tdata_t
_TIFFrealloc(tdata_t p, tsize_t s)
{
return (realloc(p, (size_t) s));
}
void
_TIFFmemset(tdata_t p, int v, tsize_t c)
{
memset(p, v, (size_t) c);
}
void
_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c)
{
memcpy(d, s, (size_t) c);
}
int
_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
{
return (memcmp(p1, p2, (size_t) c));
}
#ifndef UNICODE
#define DbgPrint wvsprintf
#define DbgPrint2 wsprintf
#define DbgMsgBox MessageBox
#else
#define DbgPrint wvsprintfA
#define DbgPrint2 wsprintfA
#define DbgMsgBox MessageBoxA
#endif
static void
Win32WarningHandler(const char* module, const char* fmt, va_list ap)
{
#ifdef _DEBUG
#if (!defined(_CONSOLE) && !defined(_WIN32_WCE) && defined(WIN32))
LPSTR szTitle;
LPSTR szTmp;
LPCSTR szTitleText = "%s Warning";
LPCSTR szDefaultModule = "TIFFLIB";
szTmp = (module == NULL) ? (LPSTR)szDefaultModule : (LPSTR)module;
if ((szTitle = (LPSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmp) +
strlen(szTitleText) + strlen(fmt) + 128))) == NULL)
return;
DbgPrint2(szTitle, szTitleText, szTmp);
szTmp = szTitle + (strlen(szTitle)+2);
DbgPrint(szTmp, fmt, ap);
DbgMsgBox(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONINFORMATION);
LocalFree(szTitle);
return;
#else
if (module != NULL)
fprintf(stderr, "%s: ", module);
fprintf(stderr, "Warning, ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, ".\n");
#endif
#endif
}
TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler;
static void
Win32ErrorHandler(const char* module, const char* fmt, va_list ap)
{
#ifdef _DEBUG
#if (!defined(_CONSOLE) && !defined(_WIN32_WCE) && defined(WIN32))
LPSTR szTitle;
LPSTR szTmp;
LPCSTR szTitleText = "%s Error";
LPCSTR szDefaultModule = "TIFFLIB";
szTmp = (module == NULL) ? (LPSTR)szDefaultModule : (LPSTR)module;
if ((szTitle = (LPSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmp) +
strlen(szTitleText) + strlen(fmt) + 128))) == NULL)
return;
DbgPrint2(szTitle, szTitleText, szTmp);
szTmp = szTitle + (strlen(szTitle)+2);
DbgPrint(szTmp, fmt, ap);
DbgMsgBox(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONEXCLAMATION);
LocalFree(szTitle);
return;
#else
if (module != NULL)
fprintf(stderr, "%s: ", module);
vfprintf(stderr, fmt, ap);
fprintf(stderr, ".\n");
#endif
#endif
}
TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler;
#endif

View File

@@ -1,79 +0,0 @@
/*
* File: xfile.h
* Purpose: General Purpose File Class
*/
/*
--------------------------------------------------------------------------------
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
CxFile (c) 11/May/2002 Davide Pizzolato - www.xdp.it
CxFile version 2.00 23/Aug/2002
CxFile version 2.10 16/Dec/2007
Special thanks to Chris Shearer Cooper for new features, enhancements and bugfixes
Covered code is provided under this license on an "as is" basis, without warranty
of any kind, either expressed or implied, including, without limitation, warranties
that the covered code is free of defects, merchantable, fit for a particular purpose
or non-infringing. The entire risk as to the quality and performance of the covered
code is with you. Should any covered code prove defective in any respect, you (not
the initial developer or any other contributor) assume the cost of any necessary
servicing, repair or correction. This disclaimer of warranty constitutes an essential
part of this license. No use of any covered code is authorized hereunder except under
this disclaimer.
Permission is hereby granted to use, copy, modify, and distribute this
source code, or portions hereof, for any purpose, including commercial applications,
freely and without fee, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
--------------------------------------------------------------------------------
*/
#if !defined(__xfile_h)
#define __xfile_h
#if defined (WIN32) || defined (_WIN32_WCE)
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include "ximadef.h"
class DLL_EXP CxFile
{
public:
CxFile(void) { };
virtual ~CxFile() { };
virtual bool Close() = 0;
virtual size_t Read(void *buffer, size_t size, size_t count) = 0;
virtual size_t Write(const void *buffer, size_t size, size_t count) = 0;
virtual bool Seek(long offset, int origin) = 0;
virtual long Tell() = 0;
virtual long Size() = 0;
virtual bool Flush() = 0;
virtual bool Eof() = 0;
virtual long Error() = 0;
virtual bool PutC(unsigned char c)
{
// Default implementation
size_t nWrote = Write(&c, 1, 1);
return (bool)(nWrote == 1);
}
virtual long GetC() = 0;
virtual char * GetS(char *string, int n) = 0;
virtual long Scanf(const char *format, void* output) = 0;
};
#endif //__xfile_h

View File

@@ -1,444 +0,0 @@
/*
* File: ximabmp.cpp
* Purpose: Platform Independent BMP Image Class Loader and Writer
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximabmp.h"
#if CXIMAGE_SUPPORT_BMP
#include "ximaiter.h"
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageBMP::Encode(CxFile * hFile)
{
if (EncodeSafeCheck(hFile)) return false;
BITMAPFILEHEADER hdr;
hdr.bfType = 0x4d42; // 'BM' WINDOWS_BITMAP_SIGNATURE
hdr.bfSize = GetSize() + 14 /*sizeof(BITMAPFILEHEADER)*/;
hdr.bfReserved1 = hdr.bfReserved2 = 0;
hdr.bfOffBits = 14 /*sizeof(BITMAPFILEHEADER)*/ + head.biSize + GetPaletteSize();
hdr.bfType = ntohs(hdr.bfType);
hdr.bfSize = ntohl(hdr.bfSize);
hdr.bfOffBits = ntohl(hdr.bfOffBits);
#if CXIMAGE_SUPPORT_ALPHA
if (GetNumColors()==0 && AlphaIsValid()){
BITMAPINFOHEADER infohdr;
memcpy(&infohdr,&head,sizeof(BITMAPINFOHEADER));
infohdr.biCompression = BI_RGB;
infohdr.biBitCount = 32;
DWORD dwEffWidth = ((((infohdr.biBitCount * infohdr.biWidth) + 31) / 32) * 4);
infohdr.biSizeImage = dwEffWidth * infohdr.biHeight;
hdr.bfSize = infohdr.biSize + infohdr.biSizeImage + 14 /*sizeof(BITMAPFILEHEADER)*/;
hdr.bfSize = ntohl(hdr.bfSize);
bihtoh(&infohdr);
// Write the file header
hFile->Write(&hdr,min(14,sizeof(BITMAPFILEHEADER)),1);
hFile->Write(&infohdr,sizeof(BITMAPINFOHEADER),1);
//and DIB+ALPHA interlaced
BYTE *srcalpha = AlphaGetPointer();
for(long y = 0; y < infohdr.biHeight; ++y){
BYTE *srcdib = GetBits(y);
for(long x = 0; x < infohdr.biWidth; ++x){
hFile->Write(srcdib,3,1);
hFile->Write(srcalpha,1,1);
srcdib += 3;
++srcalpha;
}
}
} else
#endif //CXIMAGE_SUPPORT_ALPHA
{
// Write the file header
hFile->Write(&hdr,min(14,sizeof(BITMAPFILEHEADER)),1);
//copy attributes
memcpy(pDib,&head,sizeof(BITMAPINFOHEADER));
bihtoh((BITMAPINFOHEADER*)pDib);
// Write the DIB header and the pixels
hFile->Write(pDib,GetSize(),1);
bihtoh((BITMAPINFOHEADER*)pDib);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageBMP::Decode(CxFile * hFile)
{
if (hFile == NULL) return false;
BITMAPFILEHEADER bf;
DWORD off = hFile->Tell(); //<CSC>
cx_try {
if (hFile->Read(&bf,min(14,sizeof(bf)),1)==0) cx_throw("Not a BMP");
bf.bfSize = ntohl(bf.bfSize);
bf.bfOffBits = ntohl(bf.bfOffBits);
if (bf.bfType != BFT_BITMAP) { //do we have a RC HEADER?
bf.bfOffBits = 0L;
hFile->Seek(off,SEEK_SET);
}
BITMAPINFOHEADER bmpHeader;
if (!DibReadBitmapInfo(hFile,&bmpHeader)) cx_throw("Error reading BMP info");
DWORD dwCompression=bmpHeader.biCompression;
DWORD dwBitCount=bmpHeader.biBitCount; //preserve for BI_BITFIELDS compression <Thomas Ernst>
bool bIsOldBmp = bmpHeader.biSize == sizeof(BITMAPCOREHEADER);
bool bTopDownDib = bmpHeader.biHeight<0; //<Flanders> check if it's a top-down bitmap
if (bTopDownDib) bmpHeader.biHeight=-bmpHeader.biHeight;
if (info.nEscape == -1) {
// Return output dimensions only
head.biWidth = bmpHeader.biWidth;
head.biHeight = bmpHeader.biHeight;
info.dwType = CXIMAGE_FORMAT_BMP;
cx_throw("output dimensions returned");
}
if (!Create(bmpHeader.biWidth,bmpHeader.biHeight,bmpHeader.biBitCount,CXIMAGE_FORMAT_BMP))
cx_throw("");
SetXDPI((long) floor(bmpHeader.biXPelsPerMeter * 254.0 / 10000.0 + 0.5));
SetYDPI((long) floor(bmpHeader.biYPelsPerMeter * 254.0 / 10000.0 + 0.5));
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
RGBQUAD *pRgb = GetPalette();
if (pRgb){
if (bIsOldBmp){
// convert a old color table (3 byte entries) to a new
// color table (4 byte entries)
hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBTRIPLE),1);
for (int i=DibNumColors(&head)-1; i>=0; i--){
pRgb[i].rgbRed = ((RGBTRIPLE *)pRgb)[i].rgbtRed;
pRgb[i].rgbBlue = ((RGBTRIPLE *)pRgb)[i].rgbtBlue;
pRgb[i].rgbGreen = ((RGBTRIPLE *)pRgb)[i].rgbtGreen;
pRgb[i].rgbReserved = (BYTE)0;
}
} else {
hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBQUAD),1);
//force rgbReserved=0, to avoid problems with some WinXp bitmaps
for (unsigned int i=0; i<head.biClrUsed; i++) pRgb[i].rgbReserved=0;
}
}
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
switch (dwBitCount) {
case 32 :
DWORD bfmask[3];
if (dwCompression == BI_BITFIELDS)
{
hFile->Read(bfmask, 12, 1);
} else {
bfmask[0]=0x00FF0000;
bfmask[1]=0x0000FF00;
bfmask[2]=0x000000FF;
}
if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
if (dwCompression == BI_BITFIELDS || dwCompression == BI_RGB){
long imagesize=4*head.biHeight*head.biWidth;
BYTE* buff32=(BYTE*)malloc(imagesize);
if (buff32){
hFile->Read(buff32, imagesize,1); // read in the pixels
#if CXIMAGE_SUPPORT_ALPHA
if (dwCompression == BI_RGB){
AlphaCreate();
if (AlphaIsValid()){
bool bAlphaOk = false;
BYTE* p;
for (long y=0; y<head.biHeight; y++){
p = buff32 + 3 + head.biWidth * 4 * y;
for (long x=0; x<head.biWidth; x++){
if (*p) bAlphaOk = true;
AlphaSet(x,y,*p);
p+=4;
}
}
// fix if alpha pixels are all zero
if (!bAlphaOk) AlphaInvert();
}
}
#endif //CXIMAGE_SUPPORT_ALPHA
Bitfield2RGB(buff32,bfmask[0],bfmask[1],bfmask[2],32);
free(buff32);
} else cx_throw("can't allocate memory");
} else cx_throw("unknown compression");
break;
case 24 :
if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
if (dwCompression == BI_RGB){
hFile->Read(info.pImage, head.biSizeImage,1); // read in the pixels
} else cx_throw("unknown compression");
break;
case 16 :
{
DWORD bfmask[3];
if (dwCompression == BI_BITFIELDS)
{
hFile->Read(bfmask, 12, 1);
} else {
bfmask[0]=0x7C00; bfmask[1]=0x3E0; bfmask[2]=0x1F; //RGB555
}
// bf.bfOffBits required after the bitfield mask <Cui Ying Jie>
if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
// read in the pixels
hFile->Read(info.pImage, head.biHeight*((head.biWidth+1)/2)*4,1);
// transform into RGB
Bitfield2RGB(info.pImage,bfmask[0],bfmask[1],bfmask[2],16);
break;
}
case 8 :
case 4 :
case 1 :
if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
switch (dwCompression) {
case BI_RGB :
hFile->Read(info.pImage, head.biSizeImage,1); // read in the pixels
break;
case BI_RLE4 :
{
BYTE status_byte = 0;
BYTE second_byte = 0;
int scanline = 0;
int bits = 0;
BOOL low_nibble = FALSE;
CImageIterator iter(this);
for (BOOL bContinue = TRUE; bContinue && hFile->Read(&status_byte, sizeof(BYTE), 1);) {
switch (status_byte) {
case RLE_COMMAND :
hFile->Read(&status_byte, sizeof(BYTE), 1);
switch (status_byte) {
case RLE_ENDOFLINE :
bits = 0;
scanline++;
low_nibble = FALSE;
break;
case RLE_ENDOFBITMAP :
bContinue=FALSE;
break;
case RLE_DELTA :
{
// read the delta values
BYTE delta_x;
BYTE delta_y;
hFile->Read(&delta_x, sizeof(BYTE), 1);
hFile->Read(&delta_y, sizeof(BYTE), 1);
// apply them
bits += delta_x / 2;
scanline += delta_y;
break;
}
default :
hFile->Read(&second_byte, sizeof(BYTE), 1);
BYTE *sline = iter.GetRow(scanline);
for (int i = 0; i < status_byte; i++) {
if ((BYTE*)(sline+bits) < (BYTE*)(info.pImage+head.biSizeImage)){
if (low_nibble) {
if (i&1)
*(sline + bits) |= (second_byte & 0x0f);
else
*(sline + bits) |= (second_byte & 0xf0)>>4;
bits++;
} else {
if (i&1)
*(sline + bits) = (BYTE)(second_byte & 0x0f)<<4;
else
*(sline + bits) = (BYTE)(second_byte & 0xf0);
}
}
if ((i & 1) && (i != (status_byte - 1)))
hFile->Read(&second_byte, sizeof(BYTE), 1);
low_nibble = !low_nibble;
}
if ((((status_byte+1) >> 1) & 1 ) == 1)
hFile->Read(&second_byte, sizeof(BYTE), 1);
break;
};
break;
default :
{
BYTE *sline = iter.GetRow(scanline);
hFile->Read(&second_byte, sizeof(BYTE), 1);
for (unsigned i = 0; i < status_byte; i++) {
if ((BYTE*)(sline+bits) < (BYTE*)(info.pImage+head.biSizeImage)){
if (low_nibble) {
if (i&1)
*(sline + bits) |= (second_byte & 0x0f);
else
*(sline + bits) |= (second_byte & 0xf0)>>4;
bits++;
} else {
if (i&1)
*(sline + bits) = (BYTE)(second_byte & 0x0f)<<4;
else
*(sline + bits) = (BYTE)(second_byte & 0xf0);
}
}
low_nibble = !low_nibble;
}
}
break;
};
}
break;
}
case BI_RLE8 :
{
BYTE status_byte = 0;
BYTE second_byte = 0;
int scanline = 0;
int bits = 0;
CImageIterator iter(this);
for (BOOL bContinue = TRUE; bContinue && hFile->Read(&status_byte, sizeof(BYTE), 1);) {
switch (status_byte) {
case RLE_COMMAND :
hFile->Read(&status_byte, sizeof(BYTE), 1);
switch (status_byte) {
case RLE_ENDOFLINE :
bits = 0;
scanline++;
break;
case RLE_ENDOFBITMAP :
bContinue=FALSE;
break;
case RLE_DELTA :
{
// read the delta values
BYTE delta_x;
BYTE delta_y;
hFile->Read(&delta_x, sizeof(BYTE), 1);
hFile->Read(&delta_y, sizeof(BYTE), 1);
// apply them
bits += delta_x;
scanline += delta_y;
break;
}
default :
hFile->Read((void *)(iter.GetRow(scanline) + bits), sizeof(BYTE) * status_byte, 1);
// align run length to even number of bytes
if ((status_byte & 1) == 1)
hFile->Read(&second_byte, sizeof(BYTE), 1);
bits += status_byte;
break;
};
break;
default :
BYTE *sline = iter.GetRow(scanline);
hFile->Read(&second_byte, sizeof(BYTE), 1);
for (unsigned i = 0; i < status_byte; i++) {
if ((DWORD)bits<info.dwEffWidth){
*(sline + bits) = second_byte;
bits++;
} else {
break;
}
}
break;
};
}
break;
}
default :
cx_throw("compression type not supported");
}
}
if (bTopDownDib) Flip(); //<Flanders>
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_BMP) return true;
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/* ReadDibBitmapInfo()
*
* Will read a file in DIB format and return a global HANDLE to its
* BITMAPINFO. This function will work with both "old" and "new"
* bitmap formats, but will always return a "new" BITMAPINFO.
*/
bool CxImageBMP::DibReadBitmapInfo(CxFile* fh, BITMAPINFOHEADER *pdib)
{
if ((fh==NULL)||(pdib==NULL)) return false;
if (fh->Read(pdib,sizeof(BITMAPINFOHEADER),1)==0) return false;
bihtoh(pdib);
switch (pdib->biSize) // what type of bitmap info is this?
{
case sizeof(BITMAPINFOHEADER):
break;
case 64: //sizeof(OS2_BMP_HEADER):
fh->Seek((long)(64 - sizeof(BITMAPINFOHEADER)),SEEK_CUR);
break;
case sizeof(BITMAPCOREHEADER):
{
BITMAPCOREHEADER bc = *(BITMAPCOREHEADER*)pdib;
pdib->biSize = bc.bcSize;
pdib->biWidth = (DWORD)bc.bcWidth;
pdib->biHeight = (DWORD)bc.bcHeight;
pdib->biPlanes = bc.bcPlanes;
pdib->biBitCount = bc.bcBitCount;
pdib->biCompression = BI_RGB;
pdib->biSizeImage = 0;
pdib->biXPelsPerMeter = 0;
pdib->biYPelsPerMeter = 0;
pdib->biClrUsed = 0;
pdib->biClrImportant = 0;
fh->Seek((long)(sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER)), SEEK_CUR);
}
break;
default:
//give a last chance
if (pdib->biSize>(sizeof(BITMAPINFOHEADER))&&
(pdib->biSizeImage>=(unsigned long)(pdib->biHeight*((((pdib->biBitCount*pdib->biWidth)+31)/32)*4)))&&
(pdib->biPlanes==1)&&(pdib->biClrUsed==0))
{
if (pdib->biCompression==BI_RGB)
fh->Seek((long)(pdib->biSize - sizeof(BITMAPINFOHEADER)),SEEK_CUR);
break;
}
return false;
}
FixBitmapInfo(pdib);
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_BMP
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,79 +0,0 @@
/*
* File: ximabmp.h
* Purpose: BMP Image Class Loader and Writer
*/
/* ==========================================================
* CxImageBMP (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
*
* Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
*
* original CImageBMP and CImageIterator implementation are:
* Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
*
* ==========================================================
*/
#if !defined(__ximaBMP_h)
#define __ximaBMP_h
#include "ximage.h"
const int RLE_COMMAND = 0;
const int RLE_ENDOFLINE = 0;
const int RLE_ENDOFBITMAP = 1;
const int RLE_DELTA = 2;
#if !defined(BI_RLE8)
#define BI_RLE8 1L
#endif
#if !defined(BI_RLE4)
#define BI_RLE4 2L
#endif
#if CXIMAGE_SUPPORT_BMP
class CxImageBMP: public CxImage
{
public:
CxImageBMP(): CxImage(CXIMAGE_FORMAT_BMP) {};
bool Decode(CxFile * hFile);
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile);
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
#endif // CXIMAGE_SUPPORT_ENCODE
protected:
bool DibReadBitmapInfo(CxFile* fh, BITMAPINFOHEADER *pdib);
};
#define BFT_ICON 0x4349 /* 'IC' */
#define BFT_BITMAP 0x4d42 /* 'BM' */
#define BFT_CURSOR 0x5450 /* 'PT' */
#ifndef WIDTHBYTES
#define WIDTHBYTES(i) ((unsigned)((i+31)&(~31))/8) /* ULONG aligned ! */
#endif
#endif
#define DibWidthBytesN(lpbi, n) (UINT)WIDTHBYTES((UINT)(lpbi)->biWidth * (UINT)(n))
#define DibWidthBytes(lpbi) DibWidthBytesN(lpbi, (lpbi)->biBitCount)
#define DibSizeImage(lpbi) ((lpbi)->biSizeImage == 0 \
? ((DWORD)(UINT)DibWidthBytes(lpbi) * (DWORD)(UINT)(lpbi)->biHeight) \
: (lpbi)->biSizeImage)
#define DibNumColors(lpbi) ((lpbi)->biClrUsed == 0 && (lpbi)->biBitCount <= 8 \
? (int)(1 << (int)(lpbi)->biBitCount) \
: (int)(lpbi)->biClrUsed)
#define FixBitmapInfo(lpbi) if ((lpbi)->biSizeImage == 0) \
(lpbi)->biSizeImage = DibSizeImage(lpbi); \
if ((lpbi)->biClrUsed == 0) \
(lpbi)->biClrUsed = DibNumColors(lpbi); \
#endif

View File

@@ -1,57 +0,0 @@
#if !defined(__ximaCFG_h)
#define __ximaCFG_h
/////////////////////////////////////////////////////////////////////////////
// CxImage supported features
#define CXIMAGE_SUPPORT_ALPHA 1
#define CXIMAGE_SUPPORT_SELECTION 1
#define CXIMAGE_SUPPORT_TRANSFORMATION 1
#define CXIMAGE_SUPPORT_DSP 1
#define CXIMAGE_SUPPORT_LAYERS 1
#define CXIMAGE_SUPPORT_INTERPOLATION 1
#define CXIMAGE_SUPPORT_DECODE 1
#define CXIMAGE_SUPPORT_ENCODE 1 //<vho><T.Peck>
#define CXIMAGE_SUPPORT_WINDOWS 1
/////////////////////////////////////////////////////////////////////////////
// CxImage supported formats
#define CXIMAGE_SUPPORT_BMP 0
#define CXIMAGE_SUPPORT_GIF 0
#define CXIMAGE_SUPPORT_JPG 0
#define CXIMAGE_SUPPORT_PNG 1
#define CXIMAGE_SUPPORT_ICO 0
#define CXIMAGE_SUPPORT_TIF 0
#define CXIMAGE_SUPPORT_TGA 0
#define CXIMAGE_SUPPORT_PCX 0
#define CXIMAGE_SUPPORT_WBMP 0
#define CXIMAGE_SUPPORT_WMF 0
#define CXIMAGE_SUPPORT_JP2 0
#define CXIMAGE_SUPPORT_JPC 0
#define CXIMAGE_SUPPORT_PGX 0
#define CXIMAGE_SUPPORT_PNM 0
#define CXIMAGE_SUPPORT_RAS 0
#define CXIMAGE_SUPPORT_JBG 0 // GPL'd see ../jbig/copying.txt & ../jbig/patents.htm
#define CXIMAGE_SUPPORT_MNG 0
#define CXIMAGE_SUPPORT_SKA 0
#define CXIMAGE_SUPPORT_RAW 0
/////////////////////////////////////////////////////////////////////////////
#define CXIMAGE_MAX_MEMORY 268435456
#define CXIMAGE_DEFAULT_DPI 96
#define CXIMAGE_ERR_NOFILE "null file handler"
#define CXIMAGE_ERR_NOIMAGE "null image!!!"
#define CXIMAGE_SUPPORT_EXCEPTION_HANDLING 1
/////////////////////////////////////////////////////////////////////////////
//color to grey mapping <H. Muelner> <jurgene>
//#define RGB2GRAY(r,g,b) (((b)*114 + (g)*587 + (r)*299)/1000)
#define RGB2GRAY(r,g,b) (((b)*117 + (g)*601 + (r)*306) >> 10)
#endif

View File

@@ -1,206 +0,0 @@
#if !defined(__ximadefs_h)
#define __ximadefs_h
#include "ximacfg.h"
#if defined(_AFXDLL)||defined(_USRDLL)
#define DLL_EXP __declspec(dllexport)
#elif defined(_MSC_VER)&&(_MSC_VER<1200)
#define DLL_EXP __declspec(dllimport)
#else
#define DLL_EXP
#endif
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
#define cx_try try
#define cx_throw(message) throw(message)
#define cx_catch catch (const char *message)
#else
#define cx_try bool cx_error=false;
#define cx_throw(message) {cx_error=true; if(strcmp(message,"")) strncpy(info.szLastError,message,255); goto cx_error_catch;}
#define cx_catch cx_error_catch: char message[]=""; if(cx_error)
#endif
#if CXIMAGE_SUPPORT_JP2 || CXIMAGE_SUPPORT_JPC || CXIMAGE_SUPPORT_PGX || CXIMAGE_SUPPORT_PNM || CXIMAGE_SUPPORT_RAS
#define CXIMAGE_SUPPORT_JASPER 1
#else
#define CXIMAGE_SUPPORT_JASPER 0
#endif
#if CXIMAGE_SUPPORT_DSP
#undef CXIMAGE_SUPPORT_TRANSFORMATION
#define CXIMAGE_SUPPORT_TRANSFORMATION 1
#endif
#if CXIMAGE_SUPPORT_TRANSFORMATION || CXIMAGE_SUPPORT_TIF || CXIMAGE_SUPPORT_TGA || CXIMAGE_SUPPORT_BMP || CXIMAGE_SUPPORT_WINDOWS
#define CXIMAGE_SUPPORT_BASICTRANSFORMATIONS 1
#endif
#if CXIMAGE_SUPPORT_DSP || CXIMAGE_SUPPORT_TRANSFORMATION
#undef CXIMAGE_SUPPORT_INTERPOLATION
#define CXIMAGE_SUPPORT_INTERPOLATION 1
#endif
#if defined (_WIN32_WCE)
#undef CXIMAGE_SUPPORT_WMF
#define CXIMAGE_SUPPORT_WMF 0
#endif
#if !defined(WIN32) && !defined(_WIN32_WCE)
#undef CXIMAGE_SUPPORT_WINDOWS
#define CXIMAGE_SUPPORT_WINDOWS 0
#endif
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef max
#define max(a,b) (((a)>(b))?(a):(b))
#endif
#ifndef PI
#define PI 3.141592653589793f
#endif
#if defined(WIN32) || defined(_WIN32_WCE)
#include <windows.h>
#include <tchar.h>
#endif
#include <stdio.h>
#include <math.h>
#ifdef __BORLANDC__
#ifndef _COMPLEX_DEFINED
typedef struct tagcomplex {
double x,y;
} _complex;
#endif
#define _cabs(c) sqrt(c.x*c.x+c.y*c.y)
#endif
#if !defined(WIN32) && !defined(_WIN32_WCE)
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef unsigned int UINT;
typedef DWORD COLORREF;
typedef unsigned int HANDLE;
typedef void* HRGN;
#ifndef BOOL
#define BOOL bool
#endif
#ifndef TRUE
#define TRUE true
#endif
#ifndef FALSE
#define FALSE false
#endif
#ifndef TCHAR
#define TCHAR char
#define _T
#endif
typedef struct tagRECT
{
long left;
long top;
long right;
long bottom;
} RECT;
typedef struct tagPOINT
{
long x;
long y;
} POINT;
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
#pragma pack(1)
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
long biWidth;
long biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
long biXPelsPerMeter;
long biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPCOREHEADER {
DWORD bcSize;
WORD bcWidth;
WORD bcHeight;
WORD bcPlanes;
WORD bcBitCount;
} BITMAPCOREHEADER;
typedef struct tagRGBTRIPLE {
BYTE rgbtBlue;
BYTE rgbtGreen;
BYTE rgbtRed;
} RGBTRIPLE;
#pragma pack()
#define BI_RGB 0L
#define BI_RLE8 1L
#define BI_RLE4 2L
#define BI_BITFIELDS 3L
#define GetRValue(rgb) ((BYTE)(rgb))
#define GetGValue(rgb) ((BYTE)(((WORD)(rgb)) >> 8))
#define GetBValue(rgb) ((BYTE)((rgb)>>16))
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
#ifndef _COMPLEX_DEFINED
typedef struct tagcomplex {
double x,y;
} _complex;
#endif
#define _cabs(c) sqrt(c.x*c.x+c.y*c.y)
#endif
#endif //__ximadefs

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,878 +0,0 @@
/*
* File: ximaexif.cpp
* Purpose: EXIF reader
* 18/Aug/2002 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
* based on jhead-1.8 by Matthias Wandel <mwandel(at)rim(dot)net>
*/
#include "ximajpg.h"
#if CXIMAGEJPG_SUPPORT_EXIF
////////////////////////////////////////////////////////////////////////////////
CxImageJPG::CxExifInfo::CxExifInfo(EXIFINFO* info)
{
if (info) {
m_exifinfo = info;
freeinfo = false;
} else {
m_exifinfo = new EXIFINFO;
memset(m_exifinfo,0,sizeof(EXIFINFO));
freeinfo = true;
}
m_szLastError[0]='\0';
ExifImageWidth = MotorolaOrder = 0;
SectionsRead=0;
memset(&Sections, 0, MAX_SECTIONS * sizeof(Section_t));
}
////////////////////////////////////////////////////////////////////////////////
CxImageJPG::CxExifInfo::~CxExifInfo()
{
for(int i=0;i<MAX_SECTIONS;i++) if(Sections[i].Data) free(Sections[i].Data);
if (freeinfo) delete m_exifinfo;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImageJPG::CxExifInfo::DecodeExif(CxFile * hFile, int nReadMode)
{
int a;
int HaveCom = FALSE;
a = hFile->GetC();
if (a != 0xff || hFile->GetC() != M_SOI){
return FALSE;
}
for(;;){
int itemlen;
int marker = 0;
int ll,lh, got;
BYTE * Data;
if (SectionsRead >= MAX_SECTIONS){
strcpy(m_szLastError,"Too many sections in jpg file");
return false;
}
for (a=0;a<7;a++){
marker = hFile->GetC();
if (marker != 0xff) break;
if (a >= 6){
printf("too many padding bytes\n");
return false;
}
}
if (marker == 0xff){
// 0xff is legal padding, but if we get that many, something's wrong.
strcpy(m_szLastError,"too many padding bytes!");
return false;
}
Sections[SectionsRead].Type = marker;
// Read the length of the section.
lh = hFile->GetC();
ll = hFile->GetC();
itemlen = (lh << 8) | ll;
if (itemlen < 2){
strcpy(m_szLastError,"invalid marker");
return false;
}
Sections[SectionsRead].Size = itemlen;
Data = (BYTE *)malloc(itemlen);
if (Data == NULL){
strcpy(m_szLastError,"Could not allocate memory");
return false;
}
Sections[SectionsRead].Data = Data;
// Store first two pre-read bytes.
Data[0] = (BYTE)lh;
Data[1] = (BYTE)ll;
got = hFile->Read(Data+2, 1, itemlen-2); // Read the whole section.
if (got != itemlen-2){
strcpy(m_szLastError,"Premature end of file?");
return false;
}
SectionsRead += 1;
switch(marker){
case M_SOS: // stop before hitting compressed data
// If reading entire image is requested, read the rest of the data.
if (nReadMode & EXIF_READ_IMAGE){
int cp, ep, size;
// Determine how much file is left.
cp = hFile->Tell();
hFile->Seek(0, SEEK_END);
ep = hFile->Tell();
hFile->Seek(cp, SEEK_SET);
size = ep-cp;
Data = (BYTE *)malloc(size);
if (Data == NULL){
strcpy(m_szLastError,"could not allocate data for entire image");
return false;
}
got = hFile->Read(Data, 1, size);
if (got != size){
strcpy(m_szLastError,"could not read the rest of the image");
return false;
}
Sections[SectionsRead].Data = Data;
Sections[SectionsRead].Size = size;
Sections[SectionsRead].Type = PSEUDO_IMAGE_MARKER;
SectionsRead ++;
}
return true;
case M_EOI: // in case it's a tables-only JPEG stream
printf("No image in jpeg!\n");
return FALSE;
case M_COM: // Comment section
if (HaveCom || ((nReadMode & EXIF_READ_EXIF) == 0)){
// Discard this section.
free(Sections[--SectionsRead].Data);
Sections[SectionsRead].Data=0;
}else{
process_COM(Data, itemlen);
HaveCom = TRUE;
}
break;
case M_JFIF:
// Regular jpegs always have this tag, exif images have the exif
// marker instead, althogh ACDsee will write images with both markers.
// this program will re-create this marker on absence of exif marker.
// hence no need to keep the copy from the file.
free(Sections[--SectionsRead].Data);
Sections[SectionsRead].Data=0;
break;
case M_EXIF:
// Seen files from some 'U-lead' software with Vivitar scanner
// that uses marker 31 for non exif stuff. Thus make sure
// it says 'Exif' in the section before treating it as exif.
if ((nReadMode & EXIF_READ_EXIF) && memcmp(Data+2, "Exif", 4) == 0){
m_exifinfo->IsExif = process_EXIF((BYTE *)Data+2, itemlen);
}else{
// Discard this section.
free(Sections[--SectionsRead].Data);
Sections[SectionsRead].Data=0;
}
break;
case M_SOF0:
case M_SOF1:
case M_SOF2:
case M_SOF3:
case M_SOF5:
case M_SOF6:
case M_SOF7:
case M_SOF9:
case M_SOF10:
case M_SOF11:
case M_SOF13:
case M_SOF14:
case M_SOF15:
process_SOFn(Data, marker);
break;
default:
// Skip any other sections.
//if (ShowTags) printf("Jpeg section marker 0x%02x size %d\n",marker, itemlen);
break;
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/*--------------------------------------------------------------------------
Process a EXIF marker
Describes all the drivel that most digital cameras include...
--------------------------------------------------------------------------*/
bool CxImageJPG::CxExifInfo::process_EXIF(unsigned char * CharBuf, unsigned int length)
{
m_exifinfo->FlashUsed = 0;
/* If it's from a digicam, and it used flash, it says so. */
m_exifinfo->Comments[0] = '\0'; /* Initial value - null string */
ExifImageWidth = 0;
{ /* Check the EXIF header component */
static const unsigned char ExifHeader[] = "Exif\0\0";
if (memcmp(CharBuf+0, ExifHeader,6)){
strcpy(m_szLastError,"Incorrect Exif header");
return false;
}
}
if (memcmp(CharBuf+6,"II",2) == 0){
MotorolaOrder = 0;
}else{
if (memcmp(CharBuf+6,"MM",2) == 0){
MotorolaOrder = 1;
}else{
strcpy(m_szLastError,"Invalid Exif alignment marker.");
return false;
}
}
/* Check the next two values for correctness. */
if (Get16u(CharBuf+8) != 0x2a){
strcpy(m_szLastError,"Invalid Exif start (1)");
return false;
}
int FirstOffset = Get32u(CharBuf+10);
/* <Richard Collins>
if (FirstOffset < 8 || FirstOffset > 16){
// I used to ensure this was set to 8 (website I used indicated its 8)
// but PENTAX Optio 230 has it set differently, and uses it as offset. (Sept 11 2002)
strcpy(m_szLastError,"Suspicious offset of first IFD value");
return false;
}*/
unsigned char * LastExifRefd = CharBuf;
/* First directory starts 16 bytes in. Offsets start at 8 bytes in. */
if (!ProcessExifDir(CharBuf+14, CharBuf+6, length-6, m_exifinfo, &LastExifRefd))
return false;
/* <Richard Collins> give a chance for a second directory */
if (FirstOffset > 8) {
if (!ProcessExifDir(CharBuf+14+FirstOffset-8, CharBuf+6, length-6, m_exifinfo, &LastExifRefd))
return false;
}
/* This is how far the interesting (non thumbnail) part of the exif went. */
// int ExifSettingsLength = LastExifRefd - CharBuf;
/* Compute the CCD width, in milimeters. */
if (m_exifinfo->FocalplaneXRes != 0){
m_exifinfo->CCDWidth = (float)(ExifImageWidth * m_exifinfo->FocalplaneUnits / m_exifinfo->FocalplaneXRes);
}
return true;
}
//--------------------------------------------------------------------------
// Get 16 bits motorola order (always) for jpeg header stuff.
//--------------------------------------------------------------------------
int CxImageJPG::CxExifInfo::Get16m(void * Short)
{
return (((unsigned char *)Short)[0] << 8) | ((unsigned char *)Short)[1];
}
////////////////////////////////////////////////////////////////////////////////
/*--------------------------------------------------------------------------
Convert a 16 bit unsigned value from file's native byte order
--------------------------------------------------------------------------*/
int CxImageJPG::CxExifInfo::Get16u(void * Short)
{
if (MotorolaOrder){
return (((unsigned char *)Short)[0] << 8) | ((unsigned char *)Short)[1];
}else{
return (((unsigned char *)Short)[1] << 8) | ((unsigned char *)Short)[0];
}
}
////////////////////////////////////////////////////////////////////////////////
/*--------------------------------------------------------------------------
Convert a 32 bit signed value from file's native byte order
--------------------------------------------------------------------------*/
long CxImageJPG::CxExifInfo::Get32s(void * Long)
{
if (MotorolaOrder){
return ((( char *)Long)[0] << 24) | (((unsigned char *)Long)[1] << 16)
| (((unsigned char *)Long)[2] << 8 ) | (((unsigned char *)Long)[3] << 0 );
}else{
return ((( char *)Long)[3] << 24) | (((unsigned char *)Long)[2] << 16)
| (((unsigned char *)Long)[1] << 8 ) | (((unsigned char *)Long)[0] << 0 );
}
}
////////////////////////////////////////////////////////////////////////////////
/*--------------------------------------------------------------------------
Convert a 32 bit unsigned value from file's native byte order
--------------------------------------------------------------------------*/
unsigned long CxImageJPG::CxExifInfo::Get32u(void * Long)
{
return (unsigned long)Get32s(Long) & 0xffffffff;
}
////////////////////////////////////////////////////////////////////////////////
/* Describes format descriptor */
static const int BytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8};
#define NUM_FORMATS 12
#define FMT_BYTE 1
#define FMT_STRING 2
#define FMT_USHORT 3
#define FMT_ULONG 4
#define FMT_URATIONAL 5
#define FMT_SBYTE 6
#define FMT_UNDEFINED 7
#define FMT_SSHORT 8
#define FMT_SLONG 9
#define FMT_SRATIONAL 10
#define FMT_SINGLE 11
#define FMT_DOUBLE 12
/* Describes tag values */
#define TAG_EXIF_VERSION 0x9000
#define TAG_EXIF_OFFSET 0x8769
#define TAG_INTEROP_OFFSET 0xa005
#define TAG_MAKE 0x010F
#define TAG_MODEL 0x0110
#define TAG_ORIENTATION 0x0112
#define TAG_XRESOLUTION 0x011A
#define TAG_YRESOLUTION 0x011B
#define TAG_RESOLUTIONUNIT 0x0128
#define TAG_EXPOSURETIME 0x829A
#define TAG_FNUMBER 0x829D
#define TAG_SHUTTERSPEED 0x9201
#define TAG_APERTURE 0x9202
#define TAG_BRIGHTNESS 0x9203
#define TAG_MAXAPERTURE 0x9205
#define TAG_FOCALLENGTH 0x920A
#define TAG_DATETIME_ORIGINAL 0x9003
#define TAG_USERCOMMENT 0x9286
#define TAG_SUBJECT_DISTANCE 0x9206
#define TAG_FLASH 0x9209
#define TAG_FOCALPLANEXRES 0xa20E
#define TAG_FOCALPLANEYRES 0xa20F
#define TAG_FOCALPLANEUNITS 0xa210
#define TAG_EXIF_IMAGEWIDTH 0xA002
#define TAG_EXIF_IMAGELENGTH 0xA003
/* the following is added 05-jan-2001 vcs */
#define TAG_EXPOSURE_BIAS 0x9204
#define TAG_WHITEBALANCE 0x9208
#define TAG_METERING_MODE 0x9207
#define TAG_EXPOSURE_PROGRAM 0x8822
#define TAG_ISO_EQUIVALENT 0x8827
#define TAG_COMPRESSION_LEVEL 0x9102
#define TAG_THUMBNAIL_OFFSET 0x0201
#define TAG_THUMBNAIL_LENGTH 0x0202
/*--------------------------------------------------------------------------
Process one of the nested EXIF directories.
--------------------------------------------------------------------------*/
bool CxImageJPG::CxExifInfo::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength,
EXIFINFO * const m_exifinfo, unsigned char ** const LastExifRefdP, int NestingLevel)
{
int de;
int a;
int NumDirEntries;
unsigned ThumbnailOffset = 0;
unsigned ThumbnailSize = 0;
if (NestingLevel > 4){
strcpy(m_szLastError,"Maximum directory nesting exceeded (corrupt exif header)");
return false;
}
NumDirEntries = Get16u(DirStart);
if ((DirStart+2+NumDirEntries*12) > (OffsetBase+ExifLength)){
strcpy(m_szLastError,"Illegally sized directory");
return false;
}
for (de=0;de<NumDirEntries;de++){
int Tag, Format, Components;
unsigned char * ValuePtr;
/* This actually can point to a variety of things; it must be
cast to other types when used. But we use it as a byte-by-byte
cursor, so we declare it as a pointer to a generic byte here.
*/
int ByteCount;
unsigned char * DirEntry;
DirEntry = DirStart+2+12*de;
Tag = Get16u(DirEntry);
Format = Get16u(DirEntry+2);
Components = Get32u(DirEntry+4);
if ((Format-1) >= NUM_FORMATS) {
/* (-1) catches illegal zero case as unsigned underflows to positive large */
strcpy(m_szLastError,"Illegal format code in EXIF dir");
return false;
}
ByteCount = Components * BytesPerFormat[Format];
if (ByteCount > 4){
unsigned OffsetVal;
OffsetVal = Get32u(DirEntry+8);
/* If its bigger than 4 bytes, the dir entry contains an offset.*/
if (OffsetVal+ByteCount > ExifLength){
/* Bogus pointer offset and / or bytecount value */
strcpy(m_szLastError,"Illegal pointer offset value in EXIF.");
return false;
}
ValuePtr = OffsetBase+OffsetVal;
}else{
/* 4 bytes or less and value is in the dir entry itself */
ValuePtr = DirEntry+8;
}
if (*LastExifRefdP < ValuePtr+ByteCount){
/* Keep track of last byte in the exif header that was
actually referenced. That way, we know where the
discardable thumbnail data begins.
*/
*LastExifRefdP = ValuePtr+ByteCount;
}
/* Extract useful components of tag */
switch(Tag){
case TAG_MAKE:
strncpy(m_exifinfo->CameraMake, (char*)ValuePtr, 31);
break;
case TAG_MODEL:
strncpy(m_exifinfo->CameraModel, (char*)ValuePtr, 39);
break;
case TAG_EXIF_VERSION:
strncpy(m_exifinfo->Version,(char*)ValuePtr, 4);
break;
case TAG_DATETIME_ORIGINAL:
strncpy(m_exifinfo->DateTime, (char*)ValuePtr, 19);
break;
case TAG_USERCOMMENT:
// Olympus has this padded with trailing spaces. Remove these first.
for (a=ByteCount;;){
a--;
if (((char*)ValuePtr)[a] == ' '){
((char*)ValuePtr)[a] = '\0';
}else{
break;
}
if (a == 0) break;
}
/* Copy the comment */
if (memcmp(ValuePtr, "ASCII",5) == 0){
for (a=5;a<10;a++){
char c;
c = ((char*)ValuePtr)[a];
if (c != '\0' && c != ' '){
strncpy(m_exifinfo->Comments, (char*)ValuePtr+a, 199);
break;
}
}
}else{
strncpy(m_exifinfo->Comments, (char*)ValuePtr, 199);
}
break;
case TAG_FNUMBER:
/* Simplest way of expressing aperture, so I trust it the most.
(overwrite previously computd value if there is one)
*/
m_exifinfo->ApertureFNumber = (float)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_APERTURE:
case TAG_MAXAPERTURE:
/* More relevant info always comes earlier, so only
use this field if we don't have appropriate aperture
information yet.
*/
if (m_exifinfo->ApertureFNumber == 0){
m_exifinfo->ApertureFNumber = (float)exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0f)*0.5);
}
break;
case TAG_BRIGHTNESS:
m_exifinfo->Brightness = (float)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_FOCALLENGTH:
/* Nice digital cameras actually save the focal length
as a function of how farthey are zoomed in.
*/
m_exifinfo->FocalLength = (float)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_SUBJECT_DISTANCE:
/* Inidcates the distacne the autofocus camera is focused to.
Tends to be less accurate as distance increases.
*/
m_exifinfo->Distance = (float)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_EXPOSURETIME:
/* Simplest way of expressing exposure time, so I
trust it most. (overwrite previously computd value
if there is one)
*/
m_exifinfo->ExposureTime =
(float)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_SHUTTERSPEED:
/* More complicated way of expressing exposure time,
so only use this value if we don't already have it
from somewhere else.
*/
if (m_exifinfo->ExposureTime == 0){
m_exifinfo->ExposureTime = (float)
(1/exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0f)));
}
break;
case TAG_FLASH:
if ((int)ConvertAnyFormat(ValuePtr, Format) & 7){
m_exifinfo->FlashUsed = 1;
}else{
m_exifinfo->FlashUsed = 0;
}
break;
case TAG_ORIENTATION:
m_exifinfo->Orientation = (int)ConvertAnyFormat(ValuePtr, Format);
if (m_exifinfo->Orientation < 1 || m_exifinfo->Orientation > 8){
strcpy(m_szLastError,"Undefined rotation value");
m_exifinfo->Orientation = 0;
}
break;
case TAG_EXIF_IMAGELENGTH:
case TAG_EXIF_IMAGEWIDTH:
/* Use largest of height and width to deal with images
that have been rotated to portrait format.
*/
a = (int)ConvertAnyFormat(ValuePtr, Format);
if (ExifImageWidth < a) ExifImageWidth = a;
break;
case TAG_FOCALPLANEXRES:
m_exifinfo->FocalplaneXRes = (float)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_FOCALPLANEYRES:
m_exifinfo->FocalplaneYRes = (float)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_RESOLUTIONUNIT:
switch((int)ConvertAnyFormat(ValuePtr, Format)){
case 1: m_exifinfo->ResolutionUnit = 1.0f; break; /* 1 inch */
case 2: m_exifinfo->ResolutionUnit = 1.0f; break;
case 3: m_exifinfo->ResolutionUnit = 0.3937007874f; break; /* 1 centimeter*/
case 4: m_exifinfo->ResolutionUnit = 0.03937007874f; break; /* 1 millimeter*/
case 5: m_exifinfo->ResolutionUnit = 0.00003937007874f; /* 1 micrometer*/
}
break;
case TAG_FOCALPLANEUNITS:
switch((int)ConvertAnyFormat(ValuePtr, Format)){
case 1: m_exifinfo->FocalplaneUnits = 1.0f; break; /* 1 inch */
case 2: m_exifinfo->FocalplaneUnits = 1.0f; break;
case 3: m_exifinfo->FocalplaneUnits = 0.3937007874f; break; /* 1 centimeter*/
case 4: m_exifinfo->FocalplaneUnits = 0.03937007874f; break; /* 1 millimeter*/
case 5: m_exifinfo->FocalplaneUnits = 0.00003937007874f; /* 1 micrometer*/
}
break;
// Remaining cases contributed by: Volker C. Schoech <schoech(at)gmx(dot)de>
case TAG_EXPOSURE_BIAS:
m_exifinfo->ExposureBias = (float) ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_WHITEBALANCE:
m_exifinfo->Whitebalance = (int)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_METERING_MODE:
m_exifinfo->MeteringMode = (int)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_EXPOSURE_PROGRAM:
m_exifinfo->ExposureProgram = (int)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_ISO_EQUIVALENT:
m_exifinfo->ISOequivalent = (int)ConvertAnyFormat(ValuePtr, Format);
if ( m_exifinfo->ISOequivalent < 50 ) m_exifinfo->ISOequivalent *= 200;
break;
case TAG_COMPRESSION_LEVEL:
m_exifinfo->CompressionLevel = (int)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_XRESOLUTION:
m_exifinfo->Xresolution = (float)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_YRESOLUTION:
m_exifinfo->Yresolution = (float)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_THUMBNAIL_OFFSET:
ThumbnailOffset = (unsigned)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_THUMBNAIL_LENGTH:
ThumbnailSize = (unsigned)ConvertAnyFormat(ValuePtr, Format);
break;
}
if (Tag == TAG_EXIF_OFFSET || Tag == TAG_INTEROP_OFFSET){
unsigned char * SubdirStart;
unsigned Offset = Get32u(ValuePtr);
if (Offset>8){
SubdirStart = OffsetBase + Offset;
if (SubdirStart < OffsetBase ||
SubdirStart > OffsetBase+ExifLength){
strcpy(m_szLastError,"Illegal subdirectory link");
return false;
}
ProcessExifDir(SubdirStart, OffsetBase, ExifLength, m_exifinfo, LastExifRefdP, NestingLevel+1);
}
continue;
}
}
{
/* In addition to linking to subdirectories via exif tags,
there's also a potential link to another directory at the end
of each directory. This has got to be the result of a
committee!
*/
unsigned char * SubdirStart;
unsigned Offset;
Offset = Get16u(DirStart+2+12*NumDirEntries);
if (Offset){
SubdirStart = OffsetBase + Offset;
if (SubdirStart < OffsetBase
|| SubdirStart > OffsetBase+ExifLength){
strcpy(m_szLastError,"Illegal subdirectory link");
return false;
}
ProcessExifDir(SubdirStart, OffsetBase, ExifLength, m_exifinfo, LastExifRefdP, NestingLevel+1);
}
}
if (ThumbnailSize && ThumbnailOffset){
if (ThumbnailSize + ThumbnailOffset <= ExifLength){
/* The thumbnail pointer appears to be valid. Store it. */
m_exifinfo->ThumbnailPointer = OffsetBase + ThumbnailOffset;
m_exifinfo->ThumbnailSize = ThumbnailSize;
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/*--------------------------------------------------------------------------
Evaluate number, be it int, rational, or float from directory.
--------------------------------------------------------------------------*/
double CxImageJPG::CxExifInfo::ConvertAnyFormat(void * ValuePtr, int Format)
{
double Value;
Value = 0;
switch(Format){
case FMT_SBYTE: Value = *(signed char *)ValuePtr; break;
case FMT_BYTE: Value = *(unsigned char *)ValuePtr; break;
case FMT_USHORT: Value = Get16u(ValuePtr); break;
case FMT_ULONG: Value = Get32u(ValuePtr); break;
case FMT_URATIONAL:
case FMT_SRATIONAL:
{
int Num,Den;
Num = Get32s(ValuePtr);
Den = Get32s(4+(char *)ValuePtr);
if (Den == 0){
Value = 0;
}else{
Value = (double)Num/Den;
}
break;
}
case FMT_SSHORT: Value = (signed short)Get16u(ValuePtr); break;
case FMT_SLONG: Value = Get32s(ValuePtr); break;
/* Not sure if this is correct (never seen float used in Exif format)
*/
case FMT_SINGLE: Value = (double)*(float *)ValuePtr; break;
case FMT_DOUBLE: Value = *(double *)ValuePtr; break;
}
return Value;
}
////////////////////////////////////////////////////////////////////////////////
void CxImageJPG::CxExifInfo::process_COM (const BYTE * Data, int length)
{
int ch;
char Comment[MAX_COMMENT+1];
int nch;
int a;
nch = 0;
if (length > MAX_COMMENT) length = MAX_COMMENT; // Truncate if it won't fit in our structure.
for (a=2;a<length;a++){
ch = Data[a];
if (ch == '\r' && Data[a+1] == '\n') continue; // Remove cr followed by lf.
if (isprint(ch) || ch == '\n' || ch == '\t'){
Comment[nch++] = (char)ch;
}else{
Comment[nch++] = '?';
}
}
Comment[nch] = '\0'; // Null terminate
//if (ShowTags) printf("COM marker comment: %s\n",Comment);
strcpy(m_exifinfo->Comments,Comment);
}
////////////////////////////////////////////////////////////////////////////////
void CxImageJPG::CxExifInfo::process_SOFn (const BYTE * Data, int marker)
{
int data_precision, num_components;
data_precision = Data[2];
m_exifinfo->Height = Get16m((void*)(Data+3));
m_exifinfo->Width = Get16m((void*)(Data+5));
num_components = Data[7];
if (num_components == 3){
m_exifinfo->IsColor = 1;
}else{
m_exifinfo->IsColor = 0;
}
m_exifinfo->Process = marker;
//if (ShowTags) printf("JPEG image is %uw * %uh, %d color components, %d bits per sample\n",
// ImageInfo.Width, ImageInfo.Height, num_components, data_precision);
}
////////////////////////////////////////////////////////////////////////////////
/**
* this will work only on a CxImageJPG object, if the image originally has valid EXIF data
\verbatim
CxImageJPG jpg;
CxIOFile in,out;
in.Open("D:\\exif_in.jpg","rb");
out.Open("D:\\exif_out.jpg","w+b");
jpg.Decode(&in);
if (jpg.IsValid()){
jpg.RotateLeft();
jpg.Encode(&out);
}
\endverbatim
*/
bool CxImageJPG::CxExifInfo::EncodeExif(CxFile * hFile)
{
int a;
if (FindSection(M_SOS)==NULL){
strcpy(m_szLastError,"Can't write exif : didn't read all");
return false;
}
// Initial static jpeg marker.
hFile->PutC(0xff);
hFile->PutC(0xd8);
if (Sections[0].Type != M_EXIF && Sections[0].Type != M_JFIF){
// The image must start with an exif or jfif marker. If we threw those away, create one.
static BYTE JfifHead[18] = {
0xff, M_JFIF,
0x00, 0x10, 'J' , 'F' , 'I' , 'F' , 0x00, 0x01,
0x01, 0x01, 0x01, 0x2C, 0x01, 0x2C, 0x00, 0x00
};
hFile->Write(JfifHead, 18, 1);
}
// Write all the misc sections
for (a=0;a<SectionsRead-1;a++){
hFile->PutC(0xff);
hFile->PutC((unsigned char)(Sections[a].Type));
hFile->Write(Sections[a].Data, Sections[a].Size, 1);
}
// Write the remaining image data.
hFile->Write(Sections[a].Data, Sections[a].Size, 1);
return true;
}
////////////////////////////////////////////////////////////////////////////////
void CxImageJPG::CxExifInfo::DiscardAllButExif()
{
Section_t ExifKeeper;
Section_t CommentKeeper;
int a;
memset(&ExifKeeper, 0, sizeof(ExifKeeper));
memset(&CommentKeeper, 0, sizeof(ExifKeeper));
for (a=0;a<SectionsRead;a++){
if (Sections[a].Type == M_EXIF && ExifKeeper.Type == 0){
ExifKeeper = Sections[a];
}else if (Sections[a].Type == M_COM && CommentKeeper.Type == 0){
CommentKeeper = Sections[a];
}else{
free(Sections[a].Data);
Sections[a].Data = 0;
}
}
SectionsRead = 0;
if (ExifKeeper.Type){
Sections[SectionsRead++] = ExifKeeper;
}
if (CommentKeeper.Type){
Sections[SectionsRead++] = CommentKeeper;
}
}
////////////////////////////////////////////////////////////////////////////////
void* CxImageJPG::CxExifInfo::FindSection(int SectionType)
{
int a;
for (a=0;a<SectionsRead-1;a++){
if (Sections[a].Type == SectionType){
return &Sections[a];
}
}
// Could not be found.
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGEJPG_SUPPORT_EXIF

View File

@@ -1,537 +0,0 @@
// ximage.cpp : main implementation file
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximage.h"
////////////////////////////////////////////////////////////////////////////////
// CxImage
////////////////////////////////////////////////////////////////////////////////
/**
* Initialize the internal structures
*/
void CxImage::Startup(DWORD imagetype)
{
//init pointers
pDib = pSelection = pAlpha = NULL;
ppLayers = ppFrames = NULL;
//init structures
memset(&head,0,sizeof(BITMAPINFOHEADER));
memset(&info,0,sizeof(CXIMAGEINFO));
//init default attributes
info.dwType = imagetype;
info.fQuality = 90.0f;
info.nAlphaMax = 255;
info.nBkgndIndex = -1;
info.bEnabled = true;
SetXDPI(CXIMAGE_DEFAULT_DPI);
SetYDPI(CXIMAGE_DEFAULT_DPI);
short test = 1;
info.bLittleEndianHost = (*((char *) &test) == 1);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Empty image constructor
* \param imagetype: (optional) set the image format, see ENUM_CXIMAGE_FORMATS
*/
CxImage::CxImage(DWORD imagetype)
{
Startup(imagetype);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Call this function to destroy image pixels, alpha channel, selection and sub layers.
* - Attributes are not erased, but IsValid returns false.
*
* \return true if everything is freed, false if the image is a Ghost
*/
bool CxImage::Destroy()
{
//free this only if it's valid and it's not a ghost
if (info.pGhost==NULL){
if (ppLayers) {
for(long n=0; n<info.nNumLayers;n++){ delete ppLayers[n]; }
delete [] ppLayers; ppLayers=0; info.nNumLayers = 0;
}
if (pSelection) {free(pSelection); pSelection=0;}
if (pAlpha) {free(pAlpha); pAlpha=0;}
if (pDib) {free(pDib); pDib=0;}
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::DestroyFrames()
{
if (info.pGhost==NULL) {
if (ppFrames) {
for (long n=0; n<info.nNumFrames; n++) { delete ppFrames[n]; }
delete [] ppFrames; ppFrames = NULL; info.nNumFrames = 0;
}
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sized image constructor
* \param dwWidth: width
* \param dwHeight: height
* \param wBpp: bit per pixel, can be 1, 4, 8, 24
* \param imagetype: (optional) set the image format, see ENUM_CXIMAGE_FORMATS
*/
CxImage::CxImage(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD imagetype)
{
Startup(imagetype);
Create(dwWidth,dwHeight,wBpp,imagetype);
}
////////////////////////////////////////////////////////////////////////////////
/**
* image constructor from existing source
* \param src: source image.
* \param copypixels: copy the pixels from the source image into the new image.
* \param copyselection: copy the selection from source
* \param copyalpha: copy the alpha channel from source
* \sa Copy
*/
CxImage::CxImage(const CxImage &src, bool copypixels, bool copyselection, bool copyalpha)
{
Startup(src.GetType());
Copy(src,copypixels,copyselection,copyalpha);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Copies the image from an exsisting source
* \param src: source image.
* \param copypixels: copy the pixels from the source image into the new image.
* \param copyselection: copy the selection from source
* \param copyalpha: copy the alpha channel from source
*/
void CxImage::Copy(const CxImage &src, bool copypixels, bool copyselection, bool copyalpha)
{
// if the source is a ghost, the copy is still a ghost
if (src.info.pGhost){
Ghost(&src);
return;
}
//copy the attributes
memcpy(&info,&src.info,sizeof(CXIMAGEINFO));
memcpy(&head,&src.head,sizeof(BITMAPINFOHEADER)); // [andy] - fix for bitmap header DPI
//rebuild the image
Create(src.GetWidth(),src.GetHeight(),src.GetBpp(),src.GetType());
//copy the pixels and the palette, or at least copy the palette only.
if (copypixels && pDib && src.pDib) memcpy(pDib,src.pDib,GetSize());
else SetPalette(src.GetPalette());
long nSize = head.biWidth * head.biHeight;
//copy the selection
if (copyselection && src.pSelection){
if (pSelection) free(pSelection);
pSelection = (BYTE*)malloc(nSize);
memcpy(pSelection,src.pSelection,nSize);
}
//copy the alpha channel
if (copyalpha && src.pAlpha){
if (pAlpha) free(pAlpha);
pAlpha = (BYTE*)malloc(nSize);
memcpy(pAlpha,src.pAlpha,nSize);
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* Copies the image attributes from an existing image.
* - Works only on an empty image, and the image will be still empty.
* - <b> Use it before Create() </b>
*/
void CxImage::CopyInfo(const CxImage &src)
{
if (pDib==NULL) memcpy(&info,&src.info,sizeof(CXIMAGEINFO));
}
////////////////////////////////////////////////////////////////////////////////
/**
* \sa Copy
*/
CxImage& CxImage::operator = (const CxImage& isrc)
{
if (this != &isrc) Copy(isrc);
return *this;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Initializes or rebuilds the image.
* \param dwWidth: width
* \param dwHeight: height
* \param wBpp: bit per pixel, can be 1, 4, 8, 24
* \param imagetype: (optional) set the image format, see ENUM_CXIMAGE_FORMATS
* \return pointer to the internal pDib object; NULL if an error occurs.
*/
void* CxImage::Create(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD imagetype)
{
// destroy the existing image (if any)
if (!Destroy())
return NULL;
// prevent further actions if width or height are not vaild <Balabasnia>
if ((dwWidth == 0) || (dwHeight == 0)){
strcpy(info.szLastError,"CxImage::Create : width and height must be greater than zero");
return NULL;
}
// Make sure bits per pixel is valid
if (wBpp <= 1) wBpp = 1;
else if (wBpp <= 4) wBpp = 4;
else if (wBpp <= 8) wBpp = 8;
else wBpp = 24;
// limit memory requirements (and also a check for bad parameters)
if (((dwWidth*dwHeight*wBpp)>>3) > CXIMAGE_MAX_MEMORY ||
((dwWidth*dwHeight*wBpp)/wBpp) != (dwWidth*dwHeight))
{
strcpy(info.szLastError,"CXIMAGE_MAX_MEMORY exceeded");
return NULL;
}
// set the correct bpp value
switch (wBpp){
case 1:
head.biClrUsed = 2; break;
case 4:
head.biClrUsed = 16; break;
case 8:
head.biClrUsed = 256; break;
default:
head.biClrUsed = 0;
}
//set the common image informations
info.dwEffWidth = ((((wBpp * dwWidth) + 31) / 32) * 4);
info.dwType = imagetype;
// initialize BITMAPINFOHEADER
head.biSize = sizeof(BITMAPINFOHEADER); //<ralphw>
head.biWidth = dwWidth; // fill in width from parameter
head.biHeight = dwHeight; // fill in height from parameter
head.biPlanes = 1; // must be 1
head.biBitCount = (WORD)wBpp; // from parameter
head.biCompression = BI_RGB;
head.biSizeImage = info.dwEffWidth * dwHeight;
// head.biXPelsPerMeter = 0; See SetXDPI
// head.biYPelsPerMeter = 0; See SetYDPI
// head.biClrImportant = 0; See SetClrImportant
pDib = malloc(GetSize()); // alloc memory block to store our bitmap
if (!pDib){
strcpy(info.szLastError,"CxImage::Create can't allocate memory");
return NULL;
}
//clear the palette
RGBQUAD* pal=GetPalette();
if (pal) memset(pal,0,GetPaletteSize());
//Destroy the existing selection
#if CXIMAGE_SUPPORT_SELECTION
if (pSelection) SelectionDelete();
#endif //CXIMAGE_SUPPORT_SELECTION
//Destroy the existing alpha channel
#if CXIMAGE_SUPPORT_ALPHA
if (pAlpha) AlphaDelete();
#endif //CXIMAGE_SUPPORT_ALPHA
// use our bitmap info structure to fill in first part of
// our DIB with the BITMAPINFOHEADER
BITMAPINFOHEADER* lpbi;
lpbi = (BITMAPINFOHEADER*)(pDib);
*lpbi = head;
info.pImage=GetBits();
return pDib; //return handle to the DIB
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return pointer to the image pixels. <b> USE CAREFULLY </b>
*/
BYTE* CxImage::GetBits(DWORD row)
{
if (pDib){
if (row) {
if (row<(DWORD)head.biHeight){
return ((BYTE*)pDib + *(DWORD*)pDib + GetPaletteSize() + (info.dwEffWidth * row));
} else {
return NULL;
}
} else {
return ((BYTE*)pDib + *(DWORD*)pDib + GetPaletteSize());
}
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return the size in bytes of the internal pDib object
*/
long CxImage::GetSize()
{
return head.biSize + head.biSizeImage + GetPaletteSize();
}
////////////////////////////////////////////////////////////////////////////////
/**
* Checks if the coordinates are inside the image
* \return true if x and y are both inside the image
*/
bool CxImage::IsInside(long x, long y)
{
return (0<=y && y<head.biHeight && 0<=x && x<head.biWidth);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the image bits to the specified value
* - for indexed images, the output color is set by the palette entries.
* - for RGB images, the output color is a shade of gray.
*/
void CxImage::Clear(BYTE bval)
{
if (pDib == 0) return;
if (GetBpp() == 1){
if (bval > 0) bval = 255;
}
if (GetBpp() == 4){
bval = (BYTE)(17*(0x0F & bval));
}
memset(info.pImage,bval,head.biSizeImage);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Transfers the image from an existing source image. The source becomes empty.
* \return true if everything is ok
*/
bool CxImage::Transfer(CxImage &from, bool bTransferFrames /*=true*/)
{
if (!Destroy())
return false;
memcpy(&head,&from.head,sizeof(BITMAPINFOHEADER));
memcpy(&info,&from.info,sizeof(CXIMAGEINFO));
pDib = from.pDib;
pSelection = from.pSelection;
pAlpha = from.pAlpha;
ppLayers = from.ppLayers;
memset(&from.head,0,sizeof(BITMAPINFOHEADER));
memset(&from.info,0,sizeof(CXIMAGEINFO));
from.pDib = from.pSelection = from.pAlpha = NULL;
from.ppLayers = NULL;
if (bTransferFrames){
DestroyFrames();
ppFrames = from.ppFrames;
from.ppFrames = NULL;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* (this) points to the same pDib owned by (*from), the image remains in (*from)
* but (this) has the access to the pixels. <b>Use carefully !!!</b>
*/
void CxImage::Ghost(const CxImage *from)
{
if (from){
memcpy(&head,&from->head,sizeof(BITMAPINFOHEADER));
memcpy(&info,&from->info,sizeof(CXIMAGEINFO));
pDib = from->pDib;
pSelection = from->pSelection;
pAlpha = from->pAlpha;
ppLayers = from->ppLayers;
ppFrames = from->ppFrames;
info.pGhost=(CxImage *)from;
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* turns a 16 or 32 bit bitfield image into a RGB image
*/
void CxImage::Bitfield2RGB(BYTE *src, DWORD redmask, DWORD greenmask, DWORD bluemask, BYTE bpp)
{
switch (bpp){
case 16:
{
DWORD ns[3]={0,0,0};
// compute the number of shift for each mask
for (int i=0;i<16;i++){
if ((redmask>>i)&0x01) ns[0]++;
if ((greenmask>>i)&0x01) ns[1]++;
if ((bluemask>>i)&0x01) ns[2]++;
}
ns[1]+=ns[0]; ns[2]+=ns[1]; ns[0]=8-ns[0]; ns[1]-=8; ns[2]-=8;
// dword aligned width for 16 bit image
long effwidth2=(((head.biWidth + 1) / 2) * 4);
WORD w;
long y2,y3,x2,x3;
BYTE *p=info.pImage;
// scan the buffer in reverse direction to avoid reallocations
for (long y=head.biHeight-1; y>=0; y--){
y2=effwidth2*y;
y3=info.dwEffWidth*y;
for (long x=head.biWidth-1; x>=0; x--){
x2 = 2*x+y2;
x3 = 3*x+y3;
w = (WORD)(src[x2]+256*src[1+x2]);
p[ x3]=(BYTE)((w & bluemask)<<ns[0]);
p[1+x3]=(BYTE)((w & greenmask)>>ns[1]);
p[2+x3]=(BYTE)((w & redmask)>>ns[2]);
}
}
break;
}
case 32:
{
DWORD ns[3]={0,0,0};
// compute the number of shift for each mask
for (int i=8;i<32;i+=8){
if (redmask>>i) ns[0]++;
if (greenmask>>i) ns[1]++;
if (bluemask>>i) ns[2]++;
}
// dword aligned width for 32 bit image
long effwidth4 = head.biWidth * 4;
long y4,y3,x4,x3;
BYTE *p=info.pImage;
// scan the buffer in reverse direction to avoid reallocations
for (long y=head.biHeight-1; y>=0; y--){
y4=effwidth4*y;
y3=info.dwEffWidth*y;
for (long x=head.biWidth-1; x>=0; x--){
x4 = 4*x+y4;
x3 = 3*x+y3;
p[ x3]=src[ns[2]+x4];
p[1+x3]=src[ns[1]+x4];
p[2+x3]=src[ns[0]+x4];
}
}
}
}
return;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Creates an image from a generic buffer
* \param pArray: source memory buffer
* \param dwWidth: image width
* \param dwHeight: image height
* \param dwBitsperpixel: can be 1,4,8,24,32
* \param dwBytesperline: line alignment, in bytes, for a single row stored in pArray
* \param bFlipImage: tune this parameter if the image is upsidedown
* \return true if everything is ok
*/
bool CxImage::CreateFromArray(BYTE* pArray,DWORD dwWidth,DWORD dwHeight,DWORD dwBitsperpixel, DWORD dwBytesperline, bool bFlipImage)
{
if (pArray==NULL) return false;
if (!((dwBitsperpixel==1)||(dwBitsperpixel==4)||(dwBitsperpixel==8)||
(dwBitsperpixel==24)||(dwBitsperpixel==32))) return false;
if (!Create(dwWidth,dwHeight,dwBitsperpixel)) return false;
if (dwBitsperpixel<24) SetGrayPalette();
#if CXIMAGE_SUPPORT_ALPHA
if (dwBitsperpixel==32) AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA
BYTE *dst,*src;
for (DWORD y = 0; y<dwHeight; y++) {
dst = info.pImage + (bFlipImage?(dwHeight-1-y):y) * info.dwEffWidth;
src = pArray + y * dwBytesperline;
if (dwBitsperpixel==32){
for(DWORD x=0;x<dwWidth;x++){
*dst++=src[0];
*dst++=src[1];
*dst++=src[2];
#if CXIMAGE_SUPPORT_ALPHA
AlphaSet(x,(bFlipImage?(dwHeight-1-y):y),src[3]);
#endif //CXIMAGE_SUPPORT_ALPHA
src+=4;
}
} else {
memcpy(dst,src,min(info.dwEffWidth,dwBytesperline));
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \sa CreateFromArray
*/
bool CxImage::CreateFromMatrix(BYTE** ppMatrix,DWORD dwWidth,DWORD dwHeight,DWORD dwBitsperpixel, DWORD dwBytesperline, bool bFlipImage)
{
if (ppMatrix==NULL) return false;
if (!((dwBitsperpixel==1)||(dwBitsperpixel==4)||(dwBitsperpixel==8)||
(dwBitsperpixel==24)||(dwBitsperpixel==32))) return false;
if (!Create(dwWidth,dwHeight,dwBitsperpixel)) return false;
if (dwBitsperpixel<24) SetGrayPalette();
#if CXIMAGE_SUPPORT_ALPHA
if (dwBitsperpixel==32) AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA
BYTE *dst,*src;
for (DWORD y = 0; y<dwHeight; y++) {
dst = info.pImage + (bFlipImage?(dwHeight-1-y):y) * info.dwEffWidth;
src = ppMatrix[y];
if (src){
if (dwBitsperpixel==32){
for(DWORD x=0;x<dwWidth;x++){
*dst++=src[0];
*dst++=src[1];
*dst++=src[2];
#if CXIMAGE_SUPPORT_ALPHA
AlphaSet(x,(bFlipImage?(dwHeight-1-y):y),src[3]);
#endif //CXIMAGE_SUPPORT_ALPHA
src+=4;
}
} else {
memcpy(dst,src,min(info.dwEffWidth,dwBytesperline));
}
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return lightness difference between elem1 and elem2
*/
int CxImage::CompareColors(const void *elem1, const void *elem2)
{
RGBQUAD* c1 = (RGBQUAD*)elem1;
RGBQUAD* c2 = (RGBQUAD*)elem2;
int g1 = (int)RGB2GRAY(c1->rgbRed,c1->rgbGreen,c1->rgbBlue);
int g2 = (int)RGB2GRAY(c2->rgbRed,c2->rgbGreen,c2->rgbBlue);
return (g1-g2);
}
////////////////////////////////////////////////////////////////////////////////
/**
* simply calls "if (memblock) free(memblock);".
* Useful when calling Encode for a memory buffer,
* from a DLL compiled with different memory management options.
* CxImage::FreeMemory will use the same memory environment used by Encode.
* \author [livecn]
*/
void CxImage::FreeMemory(void* memblock)
{
if (memblock)
free(memblock);
}
////////////////////////////////////////////////////////////////////////////////
//EOF

View File

@@ -1,735 +0,0 @@
/*
* File: ximage.h
* Purpose: General Purpose Image Class
*/
/*
--------------------------------------------------------------------------------
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
CxImage version 6.0.0 02/Feb/2008
CxImage : Copyright (C) 2001 - 2008, Davide Pizzolato
Original CImage and CImageIterator implementation are:
Copyright (C) 1995, Alejandro Aguilar Sierra (asierra(at)servidor(dot)unam(dot)mx)
Covered code is provided under this license on an "as is" basis, without warranty
of any kind, either expressed or implied, including, without limitation, warranties
that the covered code is free of defects, merchantable, fit for a particular purpose
or non-infringing. The entire risk as to the quality and performance of the covered
code is with you. Should any covered code prove defective in any respect, you (not
the initial developer or any other contributor) assume the cost of any necessary
servicing, repair or correction. This disclaimer of warranty constitutes an essential
part of this license. No use of any covered code is authorized hereunder except under
this disclaimer.
Permission is hereby granted to use, copy, modify, and distribute this
source code, or portions hereof, for any purpose, including commercial applications,
freely and without fee, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
--------------------------------------------------------------------------------
Other information about CxImage, and the latest version, can be found at the
CxImage home page: http://www.xdp.it/cximage/
--------------------------------------------------------------------------------
*/
#if !defined(__CXIMAGE_H)
#define __CXIMAGE_H
#if _MSC_VER > 1000
#pragma once
#endif
/////////////////////////////////////////////////////////////////////////////
#include "xfile.h"
#include "xiofile.h"
#include "xmemfile.h"
#include "ximadef.h" //<vho> adjust some #define
/* see "ximacfg.h" for CxImage configuration options */
/////////////////////////////////////////////////////////////////////////////
// CxImage formats enumerator
enum ENUM_CXIMAGE_FORMATS{
CXIMAGE_FORMAT_UNKNOWN = 0,
#if CXIMAGE_SUPPORT_BMP
CXIMAGE_FORMAT_BMP = 1,
#endif
#if CXIMAGE_SUPPORT_GIF
CXIMAGE_FORMAT_GIF = 2,
#endif
#if CXIMAGE_SUPPORT_JPG
CXIMAGE_FORMAT_JPG = 3,
#endif
#if CXIMAGE_SUPPORT_PNG
CXIMAGE_FORMAT_PNG = 4,
#endif
#if CXIMAGE_SUPPORT_ICO
CXIMAGE_FORMAT_ICO = 5,
#endif
#if CXIMAGE_SUPPORT_TIF
CXIMAGE_FORMAT_TIF = 6,
#endif
#if CXIMAGE_SUPPORT_TGA
CXIMAGE_FORMAT_TGA = 7,
#endif
#if CXIMAGE_SUPPORT_PCX
CXIMAGE_FORMAT_PCX = 8,
#endif
#if CXIMAGE_SUPPORT_WBMP
CXIMAGE_FORMAT_WBMP = 9,
#endif
#if CXIMAGE_SUPPORT_WMF
CXIMAGE_FORMAT_WMF = 10,
#endif
#if CXIMAGE_SUPPORT_JP2
CXIMAGE_FORMAT_JP2 = 11,
#endif
#if CXIMAGE_SUPPORT_JPC
CXIMAGE_FORMAT_JPC = 12,
#endif
#if CXIMAGE_SUPPORT_PGX
CXIMAGE_FORMAT_PGX = 13,
#endif
#if CXIMAGE_SUPPORT_PNM
CXIMAGE_FORMAT_PNM = 14,
#endif
#if CXIMAGE_SUPPORT_RAS
CXIMAGE_FORMAT_RAS = 15,
#endif
#if CXIMAGE_SUPPORT_JBG
CXIMAGE_FORMAT_JBG = 16,
#endif
#if CXIMAGE_SUPPORT_MNG
CXIMAGE_FORMAT_MNG = 17,
#endif
#if CXIMAGE_SUPPORT_SKA
CXIMAGE_FORMAT_SKA = 18,
#endif
#if CXIMAGE_SUPPORT_RAW
CXIMAGE_FORMAT_RAW = 19,
#endif
CMAX_IMAGE_FORMATS = CXIMAGE_SUPPORT_BMP + CXIMAGE_SUPPORT_GIF + CXIMAGE_SUPPORT_JPG +
CXIMAGE_SUPPORT_PNG + CXIMAGE_SUPPORT_MNG + CXIMAGE_SUPPORT_ICO +
CXIMAGE_SUPPORT_TIF + CXIMAGE_SUPPORT_TGA + CXIMAGE_SUPPORT_PCX +
CXIMAGE_SUPPORT_WBMP+ CXIMAGE_SUPPORT_WMF +
CXIMAGE_SUPPORT_JBG + CXIMAGE_SUPPORT_JP2 + CXIMAGE_SUPPORT_JPC +
CXIMAGE_SUPPORT_PGX + CXIMAGE_SUPPORT_PNM + CXIMAGE_SUPPORT_RAS +
CXIMAGE_SUPPORT_SKA + CXIMAGE_SUPPORT_RAW + 1
};
/////////////////////////////////////////////////////////////////////////////
// CxImage class
/////////////////////////////////////////////////////////////////////////////
class DLL_EXP CxImage
{
//extensible information collector
typedef struct tagCxImageInfo {
DWORD dwEffWidth; ///< DWORD aligned scan line width
BYTE* pImage; ///< THE IMAGE BITS
CxImage* pGhost; ///< if this is a ghost, pGhost points to the body
CxImage* pParent; ///< if this is a layer, pParent points to the body
DWORD dwType; ///< original image format
char szLastError[256]; ///< debugging
long nProgress; ///< monitor
long nEscape; ///< escape
long nBkgndIndex; ///< used for GIF, PNG, MNG
RGBQUAD nBkgndColor; ///< used for RGB transparency
float fQuality; ///< used for JPEG, JPEG2000 (0.0f ... 100.0f)
BYTE nJpegScale; ///< used for JPEG [ignacio]
long nFrame; ///< used for TIF, GIF, MNG : actual frame
long nNumFrames; ///< used for TIF, GIF, MNG : total number of frames
DWORD dwFrameDelay; ///< used for GIF, MNG
long xDPI; ///< horizontal resolution
long yDPI; ///< vertical resolution
RECT rSelectionBox; ///< bounding rectangle
BYTE nAlphaMax; ///< max opacity (fade)
bool bAlphaPaletteEnabled; ///< true if alpha values in the palette are enabled.
bool bEnabled; ///< enables the painting functions
long xOffset;
long yOffset;
DWORD dwCodecOpt[CMAX_IMAGE_FORMATS]; ///< for GIF, TIF : 0=def.1=unc,2=fax3,3=fax4,4=pack,5=jpg
RGBQUAD last_c; ///< for GetNearestIndex optimization
BYTE last_c_index;
bool last_c_isvalid;
long nNumLayers;
DWORD dwFlags; ///< 0x??00000 = reserved, 0x00??0000 = blend mode, 0x0000???? = layer id - user flags
BYTE dispmeth;
bool bGetAllFrames;
bool bLittleEndianHost;
} CXIMAGEINFO;
public:
//public structures
struct rgb_color { BYTE r,g,b; };
#if CXIMAGE_SUPPORT_WINDOWS
// <VATI> text placement data
// members must be initialized with the InitTextInfo(&this) function.
typedef struct tagCxTextInfo
{
#if defined (_WIN32_WCE)
TCHAR text[256]; ///< text for windows CE
#else
TCHAR text[4096]; ///< text (char -> TCHAR for UNICODE [Cesar M])
#endif
LOGFONT lfont; ///< font and codepage data
COLORREF fcolor; ///< foreground color
long align; ///< DT_CENTER, DT_RIGHT, DT_LEFT aligment for multiline text
BYTE smooth; ///< text smoothing option. Default is false.
BYTE opaque; ///< text has background or hasn't. Default is true.
///< data for background (ignored if .opaque==FALSE)
COLORREF bcolor; ///< background color
float b_opacity; ///< opacity value for background between 0.0-1.0 Default is 0. (opaque)
BYTE b_outline; ///< outline width for background (zero: no outline)
BYTE b_round; ///< rounding radius for background rectangle. % of the height, between 0-50. Default is 10.
///< (backgr. always has a frame: width = 3 pixel + 10% of height by default.)
} CXTEXTINFO;
#endif
public:
/** \addtogroup Constructors */ //@{
CxImage(DWORD imagetype = 0);
CxImage(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD imagetype = 0);
CxImage(const CxImage &src, bool copypixels = true, bool copyselection = true, bool copyalpha = true);
CxImage(const TCHAR * filename, DWORD imagetype); // For UNICODE support: char -> TCHAR
CxImage(FILE * stream, DWORD imagetype);
CxImage(CxFile * stream, DWORD imagetype);
CxImage(BYTE * buffer, DWORD size, DWORD imagetype);
virtual ~CxImage() { DestroyFrames(); Destroy(); };
CxImage& operator = (const CxImage&);
//@}
/** \addtogroup Initialization */ //@{
void* Create(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD imagetype = 0);
bool Destroy();
bool DestroyFrames();
void Clear(BYTE bval=0);
void Copy(const CxImage &src, bool copypixels = true, bool copyselection = true, bool copyalpha = true);
bool Transfer(CxImage &from, bool bTransferFrames = true);
bool CreateFromArray(BYTE* pArray,DWORD dwWidth,DWORD dwHeight,DWORD dwBitsperpixel, DWORD dwBytesperline, bool bFlipImage);
bool CreateFromMatrix(BYTE** ppMatrix,DWORD dwWidth,DWORD dwHeight,DWORD dwBitsperpixel, DWORD dwBytesperline, bool bFlipImage);
void FreeMemory(void* memblock);
DWORD Dump(BYTE * dst);
DWORD UnDump(const BYTE * src);
DWORD DumpSize();
//@}
/** \addtogroup Attributes */ //@{
long GetSize();
BYTE* GetBits(DWORD row = 0);
BYTE GetColorType();
void* GetDIB() const;
DWORD GetHeight() const;
DWORD GetWidth() const;
DWORD GetEffWidth() const;
DWORD GetNumColors() const;
WORD GetBpp() const;
DWORD GetType() const;
const char* GetLastError();
static const TCHAR* GetVersion();
static const float GetVersionNumber();
DWORD GetFrameDelay() const;
void SetFrameDelay(DWORD d);
void GetOffset(long *x,long *y);
void SetOffset(long x,long y);
BYTE GetJpegQuality() const;
void SetJpegQuality(BYTE q);
float GetJpegQualityF() const;
void SetJpegQualityF(float q);
BYTE GetJpegScale() const;
void SetJpegScale(BYTE q);
long GetXDPI() const;
long GetYDPI() const;
void SetXDPI(long dpi);
void SetYDPI(long dpi);
DWORD GetClrImportant() const;
void SetClrImportant(DWORD ncolors = 0);
long GetProgress() const;
long GetEscape() const;
void SetProgress(long p);
void SetEscape(long i);
long GetTransIndex() const;
RGBQUAD GetTransColor();
void SetTransIndex(long idx);
void SetTransColor(RGBQUAD rgb);
bool IsTransparent() const;
DWORD GetCodecOption(DWORD imagetype = 0);
bool SetCodecOption(DWORD opt, DWORD imagetype = 0);
DWORD GetFlags() const;
void SetFlags(DWORD flags, bool bLockReservedFlags = true);
BYTE GetDisposalMethod() const;
void SetDisposalMethod(BYTE dm);
bool SetType(DWORD type);
static DWORD GetNumTypes();
static DWORD GetTypeIdFromName(const TCHAR* ext);
static DWORD GetTypeIdFromIndex(const DWORD index);
static DWORD GetTypeIndexFromId(const DWORD id);
bool GetRetreiveAllFrames() const;
void SetRetreiveAllFrames(bool flag);
CxImage * GetFrame(long nFrame) const;
//void* GetUserData() const {return info.pUserData;}
//void SetUserData(void* pUserData) {info.pUserData = pUserData;}
//@}
/** \addtogroup Palette
* These functions have no effects on RGB images and in this case the returned value is always 0.
* @{ */
bool IsGrayScale();
bool IsIndexed() const;
bool IsSamePalette(CxImage &img, bool bCheckAlpha = true);
DWORD GetPaletteSize();
RGBQUAD* GetPalette() const;
RGBQUAD GetPaletteColor(BYTE idx);
bool GetPaletteColor(BYTE i, BYTE* r, BYTE* g, BYTE* b);
BYTE GetNearestIndex(RGBQUAD c);
void BlendPalette(COLORREF cr,long perc);
void SetGrayPalette();
void SetPalette(DWORD n, BYTE *r, BYTE *g, BYTE *b);
void SetPalette(RGBQUAD* pPal,DWORD nColors=256);
void SetPalette(rgb_color *rgb,DWORD nColors=256);
void SetPaletteColor(BYTE idx, BYTE r, BYTE g, BYTE b, BYTE alpha=0);
void SetPaletteColor(BYTE idx, RGBQUAD c);
void SetPaletteColor(BYTE idx, COLORREF cr);
void SwapIndex(BYTE idx1, BYTE idx2);
void SwapRGB2BGR();
void SetStdPalette();
//@}
/** \addtogroup Pixel */ //@{
bool IsInside(long x, long y);
bool IsTransparent(long x,long y);
bool GetTransparentMask(CxImage* iDst = 0);
RGBQUAD GetPixelColor(long x,long y, bool bGetAlpha = true);
BYTE GetPixelIndex(long x,long y);
BYTE GetPixelGray(long x, long y);
void SetPixelColor(long x,long y,RGBQUAD c, bool bSetAlpha = false);
void SetPixelColor(long x,long y,COLORREF cr);
void SetPixelIndex(long x,long y,BYTE i);
void DrawLine(int StartX, int EndX, int StartY, int EndY, RGBQUAD color, bool bSetAlpha=false);
void DrawLine(int StartX, int EndX, int StartY, int EndY, COLORREF cr);
void BlendPixelColor(long x,long y,RGBQUAD c, float blend, bool bSetAlpha = false);
//@}
protected:
/** \addtogroup Protected */ //@{
BYTE BlindGetPixelIndex(const long x,const long y);
RGBQUAD BlindGetPixelColor(const long x,const long y, bool bGetAlpha = true);
void *BlindGetPixelPointer(const long x,const long y);
void BlindSetPixelColor(long x,long y,RGBQUAD c, bool bSetAlpha = false);
void BlindSetPixelIndex(long x,long y,BYTE i);
//@}
public:
#if CXIMAGE_SUPPORT_INTERPOLATION
/** \addtogroup Interpolation */ //@{
//overflow methods:
enum OverflowMethod {
OM_COLOR=1,
OM_BACKGROUND=2,
OM_TRANSPARENT=3,
OM_WRAP=4,
OM_REPEAT=5,
OM_MIRROR=6
};
void OverflowCoordinates(float &x, float &y, OverflowMethod const ofMethod);
void OverflowCoordinates(long &x, long &y, OverflowMethod const ofMethod);
RGBQUAD GetPixelColorWithOverflow(long x, long y, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0);
//interpolation methods:
enum InterpolationMethod {
IM_NEAREST_NEIGHBOUR=1,
IM_BILINEAR =2,
IM_BSPLINE =3,
IM_BICUBIC =4,
IM_BICUBIC2 =5,
IM_LANCZOS =6,
IM_BOX =7,
IM_HERMITE =8,
IM_HAMMING =9,
IM_SINC =10,
IM_BLACKMAN =11,
IM_BESSEL =12,
IM_GAUSSIAN =13,
IM_QUADRATIC =14,
IM_MITCHELL =15,
IM_CATROM =16,
IM_HANNING =17,
IM_POWER =18
};
RGBQUAD GetPixelColorInterpolated(float x,float y, InterpolationMethod const inMethod=IM_BILINEAR, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0);
RGBQUAD GetAreaColorInterpolated(float const xc, float const yc, float const w, float const h, InterpolationMethod const inMethod, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0);
//@}
protected:
/** \addtogroup Protected */ //@{
void AddAveragingCont(RGBQUAD const &color, float const surf, float &rr, float &gg, float &bb, float &aa);
//@}
/** \addtogroup Kernels */ //@{
public:
static float KernelBSpline(const float x);
static float KernelLinear(const float t);
static float KernelCubic(const float t);
static float KernelGeneralizedCubic(const float t, const float a=-1);
static float KernelLanczosSinc(const float t, const float r = 3);
static float KernelBox(const float x);
static float KernelHermite(const float x);
static float KernelHamming(const float x);
static float KernelSinc(const float x);
static float KernelBlackman(const float x);
static float KernelBessel_J1(const float x);
static float KernelBessel_P1(const float x);
static float KernelBessel_Q1(const float x);
static float KernelBessel_Order1(float x);
static float KernelBessel(const float x);
static float KernelGaussian(const float x);
static float KernelQuadratic(const float x);
static float KernelMitchell(const float x);
static float KernelCatrom(const float x);
static float KernelHanning(const float x);
static float KernelPower(const float x, const float a = 2);
//@}
#endif //CXIMAGE_SUPPORT_INTERPOLATION
/** \addtogroup Painting */ //@{
#if CXIMAGE_SUPPORT_WINDOWS
long Blt(HDC pDC, long x=0, long y=0);
HBITMAP MakeBitmap(HDC hdc = NULL);
HANDLE CopyToHandle();
bool CreateFromHANDLE(HANDLE hMem); //Windows objects (clipboard)
bool CreateFromHBITMAP(HBITMAP hbmp, HPALETTE hpal=0); //Windows resource
bool CreateFromHICON(HICON hico);
long Draw(HDC hdc, long x=0, long y=0, long cx = -1, long cy = -1, RECT* pClipRect = 0, bool bSmooth = false);
long Draw(HDC hdc, const RECT& rect, RECT* pClipRect=NULL, bool bSmooth = false);
long Stretch(HDC hdc, long xoffset, long yoffset, long xsize, long ysize, DWORD dwRop = SRCCOPY);
long Stretch(HDC hdc, const RECT& rect, DWORD dwRop = SRCCOPY);
long Tile(HDC hdc, RECT *rc);
long Draw2(HDC hdc, long x=0, long y=0, long cx = -1, long cy = -1);
long Draw2(HDC hdc, const RECT& rect);
//long DrawString(HDC hdc, long x, long y, const char* text, RGBQUAD color, const char* font, long lSize=0, long lWeight=400, BYTE bItalic=0, BYTE bUnderline=0, bool bSetAlpha=false);
long DrawString(HDC hdc, long x, long y, const TCHAR* text, RGBQUAD color, const TCHAR* font, long lSize=0, long lWeight=400, BYTE bItalic=0, BYTE bUnderline=0, bool bSetAlpha=false);
// <VATI> extensions
long DrawStringEx(HDC hdc, long x, long y, CXTEXTINFO *pTextType, bool bSetAlpha=false );
void InitTextInfo( CXTEXTINFO *txt );
#endif //CXIMAGE_SUPPORT_WINDOWS
//@}
// file operations
#if CXIMAGE_SUPPORT_DECODE
/** \addtogroup Decode */ //@{
#ifdef WIN32
//bool Load(LPCWSTR filename, DWORD imagetype=0);
bool LoadResource(HRSRC hRes, DWORD imagetype, HMODULE hModule=NULL);
#endif
// For UNICODE support: char -> TCHAR
bool Load(const TCHAR* filename, DWORD imagetype=0);
//bool Load(const char * filename, DWORD imagetype=0);
bool Decode(FILE * hFile, DWORD imagetype);
bool Decode(CxFile * hFile, DWORD imagetype);
bool Decode(BYTE * buffer, DWORD size, DWORD imagetype);
bool CheckFormat(CxFile * hFile, DWORD imagetype = 0);
bool CheckFormat(BYTE * buffer, DWORD size, DWORD imagetype = 0);
//@}
#endif //CXIMAGE_SUPPORT_DECODE
#if CXIMAGE_SUPPORT_ENCODE
protected:
/** \addtogroup Protected */ //@{
bool EncodeSafeCheck(CxFile *hFile);
//@}
public:
/** \addtogroup Encode */ //@{
#ifdef WIN32
//bool Save(LPCWSTR filename, DWORD imagetype=0);
#endif
// For UNICODE support: char -> TCHAR
bool Save(const TCHAR* filename, DWORD imagetype);
//bool Save(const char * filename, DWORD imagetype=0);
bool Encode(FILE * hFile, DWORD imagetype);
bool Encode(CxFile * hFile, DWORD imagetype);
bool Encode(CxFile * hFile, CxImage ** pImages, int pagecount, DWORD imagetype);
bool Encode(FILE *hFile, CxImage ** pImages, int pagecount, DWORD imagetype);
bool Encode(BYTE * &buffer, long &size, DWORD imagetype);
bool Encode2RGBA(CxFile *hFile, bool bFlipY = false);
bool Encode2RGBA(BYTE * &buffer, long &size, bool bFlipY = false);
//@}
#endif //CXIMAGE_SUPPORT_ENCODE
/** \addtogroup Attributes */ //@{
//misc.
bool IsValid() const;
bool IsEnabled() const;
void Enable(bool enable=true);
// frame operations
long GetNumFrames() const;
long GetFrame() const;
void SetFrame(long nFrame);
//@}
#if CXIMAGE_SUPPORT_BASICTRANSFORMATIONS
/** \addtogroup BasicTransformations */ //@{
bool GrayScale();
bool Flip(bool bFlipSelection = false, bool bFlipAlpha = true);
bool Mirror(bool bMirrorSelection = false, bool bMirrorAlpha = true);
bool Negative();
bool RotateLeft(CxImage* iDst = NULL);
bool RotateRight(CxImage* iDst = NULL);
//@}
#endif //CXIMAGE_SUPPORT_BASICTRANSFORMATIONS
#if CXIMAGE_SUPPORT_TRANSFORMATION
/** \addtogroup Transformations */ //@{
// image operations
bool Rotate(float angle, CxImage* iDst = NULL);
bool Rotate2(float angle, CxImage *iDst = NULL, InterpolationMethod inMethod=IM_BILINEAR,
OverflowMethod ofMethod=OM_BACKGROUND, RGBQUAD *replColor=0,
bool const optimizeRightAngles=true, bool const bKeepOriginalSize=false);
bool Rotate180(CxImage* iDst = NULL);
bool Resample(long newx, long newy, int mode = 1, CxImage* iDst = NULL);
bool Resample2(long newx, long newy, InterpolationMethod const inMethod=IM_BICUBIC2,
OverflowMethod const ofMethod=OM_REPEAT, CxImage* const iDst = NULL,
bool const disableAveraging=false);
bool DecreaseBpp(DWORD nbit, bool errordiffusion, RGBQUAD* ppal = 0, DWORD clrimportant = 0);
bool IncreaseBpp(DWORD nbit);
bool Dither(long method = 0);
bool Crop(long left, long top, long right, long bottom, CxImage* iDst = NULL);
bool Crop(const RECT& rect, CxImage* iDst = NULL);
bool CropRotatedRectangle( long topx, long topy, long width, long height, float angle, CxImage* iDst = NULL);
bool Skew(float xgain, float ygain, long xpivot=0, long ypivot=0, bool bEnableInterpolation = false);
bool Expand(long left, long top, long right, long bottom, RGBQUAD canvascolor, CxImage* iDst = 0);
bool Expand(long newx, long newy, RGBQUAD canvascolor, CxImage* iDst = 0);
bool Thumbnail(long newx, long newy, RGBQUAD canvascolor, CxImage* iDst = 0);
bool CircleTransform(int type,long rmax=0,float Koeff=1.0f);
bool RedEyeRemove(float strength = 0.8f);
bool QIShrink(long newx, long newy, CxImage* const iDst = NULL, bool bChangeBpp = false);
//@}
#endif //CXIMAGE_SUPPORT_TRANSFORMATION
#if CXIMAGE_SUPPORT_DSP
/** \addtogroup DSP */ //@{
bool Contour();
bool HistogramStretch(long method = 0, double threshold = 0);
bool HistogramEqualize();
bool HistogramNormalize();
bool HistogramRoot();
bool HistogramLog();
long Histogram(long* red, long* green = 0, long* blue = 0, long* gray = 0, long colorspace = 0);
bool Jitter(long radius=2);
bool Repair(float radius = 0.25f, long niterations = 1, long colorspace = 0);
bool Combine(CxImage* r,CxImage* g,CxImage* b,CxImage* a, long colorspace = 0);
bool FFT2(CxImage* srcReal, CxImage* srcImag, CxImage* dstReal, CxImage* dstImag, long direction = 1, bool bForceFFT = true, bool bMagnitude = true);
bool Noise(long level);
bool Median(long Ksize=3);
bool Gamma(float gamma);
bool GammaRGB(float gammaR, float gammaG, float gammaB);
bool ShiftRGB(long r, long g, long b);
bool Threshold(BYTE level);
bool Threshold(CxImage* pThresholdMask);
bool Threshold2(BYTE level, bool bDirection, RGBQUAD nBkgndColor, bool bSetAlpha = false);
bool Colorize(BYTE hue, BYTE sat, float blend = 1.0f);
bool Light(long brightness, long contrast = 0);
float Mean();
bool Filter(long* kernel, long Ksize, long Kfactor, long Koffset);
bool Erode(long Ksize=2);
bool Dilate(long Ksize=2);
bool Edge(long Ksize=2);
void HuePalette(float correction=1);
enum ImageOpType { OpAdd, OpAnd, OpXor, OpOr, OpMask, OpSrcCopy, OpDstCopy, OpSub, OpSrcBlend, OpScreen, OpAvg };
void Mix(CxImage & imgsrc2, ImageOpType op, long lXOffset = 0, long lYOffset = 0, bool bMixAlpha = false);
void MixFrom(CxImage & imagesrc2, long lXOffset, long lYOffset);
bool UnsharpMask(float radius = 5.0f, float amount = 0.5f, int threshold = 0);
bool Lut(BYTE* pLut);
bool Lut(BYTE* pLutR, BYTE* pLutG, BYTE* pLutB, BYTE* pLutA = 0);
bool GaussianBlur(float radius = 1.0f, CxImage* iDst = 0);
bool TextBlur(BYTE threshold = 100, BYTE decay = 2, BYTE max_depth = 5, bool bBlurHorizontal = true, bool bBlurVertical = true, CxImage* iDst = 0);
bool SelectiveBlur(float radius = 1.0f, BYTE threshold = 25, CxImage* iDst = 0);
bool Solarize(BYTE level = 128, bool bLinkedChannels = true);
bool FloodFill(const long xStart, const long yStart, const RGBQUAD cFillColor, const BYTE tolerance = 0,
BYTE nOpacity = 255, const bool bSelectFilledArea = false, const BYTE nSelectionLevel = 255);
bool Saturate(const long saturation, const long colorspace = 1);
bool ConvertColorSpace(const long dstColorSpace, const long srcColorSpace);
int OptimalThreshold(long method = 0, RECT * pBox = 0, CxImage* pContrastMask = 0);
bool AdaptiveThreshold(long method = 0, long nBoxSize = 64, CxImage* pContrastMask = 0, long nBias = 0, float fGlobalLocalBalance = 0.5f);
//@}
protected:
/** \addtogroup Protected */ //@{
bool IsPowerof2(long x);
bool FFT(int dir,int m,double *x,double *y);
bool DFT(int dir,long m,double *x1,double *y1,double *x2,double *y2);
bool RepairChannel(CxImage *ch, float radius);
// <nipper>
int gen_convolve_matrix (float radius, float **cmatrix_p);
float* gen_lookup_table (float *cmatrix, int cmatrix_length);
void blur_line (float *ctable, float *cmatrix, int cmatrix_length, BYTE* cur_col, BYTE* dest_col, int y, long bytes);
void blur_text (BYTE threshold, BYTE decay, BYTE max_depth, CxImage* iSrc, CxImage* iDst, BYTE bytes);
//@}
public:
/** \addtogroup ColorSpace */ //@{
bool SplitRGB(CxImage* r,CxImage* g,CxImage* b);
bool SplitYUV(CxImage* y,CxImage* u,CxImage* v);
bool SplitHSL(CxImage* h,CxImage* s,CxImage* l);
bool SplitYIQ(CxImage* y,CxImage* i,CxImage* q);
bool SplitXYZ(CxImage* x,CxImage* y,CxImage* z);
bool SplitCMYK(CxImage* c,CxImage* m,CxImage* y,CxImage* k);
static RGBQUAD HSLtoRGB(COLORREF cHSLColor);
static RGBQUAD RGBtoHSL(RGBQUAD lRGBColor);
static RGBQUAD HSLtoRGB(RGBQUAD lHSLColor);
static RGBQUAD YUVtoRGB(RGBQUAD lYUVColor);
static RGBQUAD RGBtoYUV(RGBQUAD lRGBColor);
static RGBQUAD YIQtoRGB(RGBQUAD lYIQColor);
static RGBQUAD RGBtoYIQ(RGBQUAD lRGBColor);
static RGBQUAD XYZtoRGB(RGBQUAD lXYZColor);
static RGBQUAD RGBtoXYZ(RGBQUAD lRGBColor);
#endif //CXIMAGE_SUPPORT_DSP
static RGBQUAD RGBtoRGBQUAD(COLORREF cr);
static COLORREF RGBQUADtoRGB (RGBQUAD c);
//@}
#if CXIMAGE_SUPPORT_SELECTION
/** \addtogroup Selection */ //@{
bool SelectionClear(BYTE level = 0);
bool SelectionCreate();
bool SelectionDelete();
bool SelectionInvert();
bool SelectionMirror();
bool SelectionFlip();
bool SelectionAddRect(RECT r, BYTE level = 255);
bool SelectionAddEllipse(RECT r, BYTE level = 255);
bool SelectionAddPolygon(POINT *points, long npoints, BYTE level = 255);
bool SelectionAddColor(RGBQUAD c, BYTE level = 255);
bool SelectionAddPixel(long x, long y, BYTE level = 255);
bool SelectionCopy(CxImage &from);
bool SelectionIsInside(long x, long y);
bool SelectionIsValid();
void SelectionGetBox(RECT& r);
bool SelectionToHRGN(HRGN& region);
bool SelectionSplit(CxImage *dest);
BYTE SelectionGet(const long x,const long y);
bool SelectionSet(CxImage &from);
void SelectionRebuildBox();
BYTE* SelectionGetPointer(const long x = 0,const long y = 0);
//@}
protected:
/** \addtogroup Protected */ //@{
bool BlindSelectionIsInside(long x, long y);
BYTE BlindSelectionGet(const long x,const long y);
void SelectionSet(const long x,const long y,const BYTE level);
//@}
public:
#endif //CXIMAGE_SUPPORT_SELECTION
#if CXIMAGE_SUPPORT_ALPHA
/** \addtogroup Alpha */ //@{
void AlphaClear();
bool AlphaCreate();
void AlphaDelete();
void AlphaInvert();
bool AlphaMirror();
bool AlphaFlip();
bool AlphaCopy(CxImage &from);
bool AlphaSplit(CxImage *dest);
void AlphaStrip();
void AlphaSet(BYTE level);
bool AlphaSet(CxImage &from);
void AlphaSet(const long x,const long y,const BYTE level);
BYTE AlphaGet(const long x,const long y);
BYTE AlphaGetMax() const;
void AlphaSetMax(BYTE nAlphaMax);
bool AlphaIsValid();
BYTE* AlphaGetPointer(const long x = 0,const long y = 0);
bool AlphaFromTransparency();
void AlphaPaletteClear();
void AlphaPaletteEnable(bool enable=true);
bool AlphaPaletteIsEnabled();
bool AlphaPaletteIsValid();
bool AlphaPaletteSplit(CxImage *dest);
//@}
protected:
/** \addtogroup Protected */ //@{
BYTE BlindAlphaGet(const long x,const long y);
//@}
#endif //CXIMAGE_SUPPORT_ALPHA
public:
#if CXIMAGE_SUPPORT_LAYERS
/** \addtogroup Layers */ //@{
bool LayerCreate(long position = -1);
bool LayerDelete(long position = -1);
void LayerDeleteAll();
CxImage* GetLayer(long position);
CxImage* GetParent() const;
long GetNumLayers() const;
long LayerDrawAll(HDC hdc, long x=0, long y=0, long cx = -1, long cy = -1, RECT* pClipRect = 0, bool bSmooth = false);
long LayerDrawAll(HDC hdc, const RECT& rect, RECT* pClipRect=NULL, bool bSmooth = false);
//@}
#endif //CXIMAGE_SUPPORT_LAYERS
protected:
/** \addtogroup Protected */ //@{
void Startup(DWORD imagetype = 0);
void CopyInfo(const CxImage &src);
void Ghost(const CxImage *src);
void RGBtoBGR(BYTE *buffer, int length);
static float HueToRGB(float n1,float n2, float hue);
void Bitfield2RGB(BYTE *src, DWORD redmask, DWORD greenmask, DWORD bluemask, BYTE bpp);
static int CompareColors(const void *elem1, const void *elem2);
short ntohs(const short word);
long ntohl(const long dword);
void bihtoh(BITMAPINFOHEADER* bih);
void* pDib; //contains the header, the palette, the pixels
BITMAPINFOHEADER head; //standard header
CXIMAGEINFO info; //extended information
BYTE* pSelection; //selected region
BYTE* pAlpha; //alpha channel
CxImage** ppLayers; //generic layers
CxImage** ppFrames;
//@}
};
////////////////////////////////////////////////////////////////////////////
#endif // !defined(__CXIMAGE_H)

File diff suppressed because it is too large Load Diff

View File

@@ -1,242 +0,0 @@
/*
* File: ximagif.h
* Purpose: GIF Image Class Loader and Writer
*/
/* ==========================================================
* CxImageGIF (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
*
* Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
*
* original CImageGIF and CImageIterator implementation are:
* Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
*
* 6/15/97 Randy Spann: Added GIF87a writing support
* R.Spann@ConnRiver.net
*
* DECODE.C - An LZW decoder for GIF
* Copyright (C) 1987, by Steven A. Bennett
* Copyright (C) 1994, C++ version by Alejandro Aguilar Sierra
*
* In accordance with the above, I want to credit Steve Wilhite who wrote
* the code which this is heavily inspired by...
*
* GIF and 'Graphics Interchange Format' are trademarks (tm) of
* Compuserve, Incorporated, an H&R Block Company.
*
* Release Notes: This file contains a decoder routine for GIF images
* which is similar, structurally, to the original routine by Steve Wilhite.
* It is, however, somewhat noticably faster in most cases.
*
* ==========================================================
*/
#if !defined(__ximaGIF_h)
#define __ximaGIF_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_GIF
typedef short int code_int;
/* Various error codes used by decoder */
#define OUT_OF_MEMORY -10
#define BAD_CODE_SIZE -20
#define READ_ERROR -1
#define WRITE_ERROR -2
#define OPEN_ERROR -3
#define CREATE_ERROR -4
#define MAX_CODES 4095
#define GIFBUFTAM 16383
#define TRANSPARENCY_CODE 0xF9
//LZW GIF Image compression
#define MAXBITSCODES 12
#define HSIZE 5003 /* 80% occupancy */
#define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1)
#define HashTabOf(i) htab[i]
#define CodeTabOf(i) codetab[i]
class CImageIterator;
class DLL_EXP CxImageGIF: public CxImage
{
#pragma pack(1)
typedef struct tag_gifgce{
BYTE flags; /*res:3|dispmeth:3|userinputflag:1|transpcolflag:1*/
WORD delaytime;
BYTE transpcolindex;
} struct_gifgce;
typedef struct tag_dscgif{ /* Logic Screen Descriptor */
char header[6]; /* Firma and version */
WORD scrwidth;
WORD scrheight;
char pflds;
char bcindx;
char pxasrat;
} struct_dscgif;
typedef struct tag_image{ /* Image Descriptor */
WORD l;
WORD t;
WORD w;
WORD h;
BYTE pf;
} struct_image;
typedef struct tag_TabCol{ /* Tabla de colores */
short colres; /* color resolution */
short sogct; /* size of global color table */
rgb_color paleta[256]; /* paleta */
} struct_TabCol;
typedef struct tag_RLE{
int rl_pixel;
int rl_basecode;
int rl_count;
int rl_table_pixel;
int rl_table_max;
int just_cleared;
int out_bits;
int out_bits_init;
int out_count;
int out_bump;
int out_bump_init;
int out_clear;
int out_clear_init;
int max_ocodes;
int code_clear;
int code_eof;
unsigned int obuf;
int obits;
unsigned char oblock[256];
int oblen;
} struct_RLE;
#pragma pack()
public:
CxImageGIF(): CxImage(CXIMAGE_FORMAT_GIF) {m_loops=0; info.dispmeth=0; m_comment[0]='\0';}
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_GIF);}
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_GIF);}
bool Decode(CxFile * fp);
bool Decode(FILE *fp) { CxIOFile file(fp); return Decode(&file); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * fp);
bool Encode(CxFile * fp, CxImage ** pImages, int pagecount, bool bLocalColorMap = false, bool bLocalDispMeth = false);
bool Encode(FILE *fp) { CxIOFile file(fp); return Encode(&file); }
bool Encode(FILE *fp, CxImage ** pImages, int pagecount, bool bLocalColorMap = false)
{ CxIOFile file(fp); return Encode(&file, pImages, pagecount, bLocalColorMap); }
#endif // CXIMAGE_SUPPORT_ENCODE
void SetLoops(int loops);
long GetLoops();
void SetComment(const char* sz_comment_in);
void GetComment(char* sz_comment_out);
protected:
bool DecodeExtension(CxFile *fp);
void EncodeHeader(CxFile *fp);
void EncodeLoopExtension(CxFile *fp);
void EncodeExtension(CxFile *fp);
void EncodeBody(CxFile *fp, bool bLocalColorMap = false);
void EncodeComment(CxFile *fp);
bool EncodeRGB(CxFile *fp);
void GifMix(CxImage & imgsrc2, struct_image & imgdesc);
struct_gifgce gifgce;
int curx, cury;
long CountDown;
unsigned long cur_accum;
int cur_bits;
int interlaced, iypos, istep, iheight, ipass;
int ibf;
int ibfmax;
BYTE buf[GIFBUFTAM + 1];
// Implementation
int GifNextPixel ();
void Putword (int w, CxFile* fp );
void compressNONE (int init_bits, CxFile* outfile);
void compressLZW (int init_bits, CxFile* outfile);
void output (code_int code );
void cl_hash (long hsize);
void char_out (int c);
void flush_char ();
short init_exp(short size);
short get_next_code(CxFile*);
short decoder(CxFile*, CImageIterator* iter, short linewidth, int &bad_code_count);
int get_byte(CxFile*);
int out_line(CImageIterator* iter, unsigned char *pixels, int linelen);
int get_num_frames(CxFile *f,struct_TabCol* TabColSrc,struct_dscgif* dscgif);
long seek_next_image(CxFile* fp, long position);
short curr_size; /* The current code size */
short clear; /* Value for a clear code */
short ending; /* Value for a ending code */
short newcodes; /* First available code */
short top_slot; /* Highest code for current size */
short slot; /* Last read code */
/* The following static variables are used
* for seperating out codes */
short navail_bytes; /* # bytes left in block */
short nbits_left; /* # bits left in current BYTE */
BYTE b1; /* Current BYTE */
BYTE byte_buff[257]; /* Current block */
BYTE *pbytes; /* Pointer to next BYTE in block */
/* The reason we have these seperated like this instead of using
* a structure like the original Wilhite code did, is because this
* stuff generally produces significantly faster code when compiled...
* This code is full of similar speedups... (For a good book on writing
* C for speed or for space optomisation, see Efficient C by Tom Plum,
* published by Plum-Hall Associates...)
*/
BYTE stack[MAX_CODES + 1]; /* Stack for storing pixels */
BYTE suffix[MAX_CODES + 1]; /* Suffix table */
WORD prefix[MAX_CODES + 1]; /* Prefix linked list */
//LZW GIF Image compression routines
long htab [HSIZE];
unsigned short codetab [HSIZE];
int n_bits; /* number of bits/code */
code_int maxcode; /* maximum code, given n_bits */
code_int free_ent; /* first unused entry */
int clear_flg;
int g_init_bits;
CxFile* g_outfile;
int ClearCode;
int EOFCode;
int a_count;
char accum[256];
char m_comment[256];
int m_loops;
//RLE compression routines
void compressRLE( int init_bits, CxFile* outfile);
void rle_clear(struct_RLE* rle);
void rle_flush(struct_RLE* rle);
void rle_flush_withtable(int count, struct_RLE* rle);
void rle_flush_clearorrep(int count, struct_RLE* rle);
void rle_flush_fromclear(int count,struct_RLE* rle);
void rle_output_plain(int c,struct_RLE* rle);
void rle_reset_out_clear(struct_RLE* rle);
unsigned int rle_compute_triangle_count(unsigned int count, unsigned int nrepcodes);
unsigned int rle_isqrt(unsigned int x);
void rle_write_block(struct_RLE* rle);
void rle_block_out(unsigned char c, struct_RLE* rle);
void rle_block_flush(struct_RLE* rle);
void rle_output(int val, struct_RLE* rle);
void rle_output_flush(struct_RLE* rle);
};
#endif
#endif

View File

@@ -1,627 +0,0 @@
// xImaHist.cpp : histogram functions
/* 28/01/2004 v1.00 - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximage.h"
#if CXIMAGE_SUPPORT_DSP
////////////////////////////////////////////////////////////////////////////////
long CxImage::Histogram(long* red, long* green, long* blue, long* gray, long colorspace)
{
if (!pDib) return 0;
RGBQUAD color;
if (red) memset(red,0,256*sizeof(long));
if (green) memset(green,0,256*sizeof(long));
if (blue) memset(blue,0,256*sizeof(long));
if (gray) memset(gray,0,256*sizeof(long));
long xmin,xmax,ymin,ymax;
if (pSelection){
xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
} else {
xmin = ymin = 0;
xmax = head.biWidth; ymax=head.biHeight;
}
for(long y=ymin; y<ymax; y++){
for(long x=xmin; x<xmax; x++){
#if CXIMAGE_SUPPORT_SELECTION
if (BlindSelectionIsInside(x,y))
#endif //CXIMAGE_SUPPORT_SELECTION
{
switch (colorspace){
case 1:
color = HSLtoRGB(BlindGetPixelColor(x,y));
break;
case 2:
color = YUVtoRGB(BlindGetPixelColor(x,y));
break;
case 3:
color = YIQtoRGB(BlindGetPixelColor(x,y));
break;
case 4:
color = XYZtoRGB(BlindGetPixelColor(x,y));
break;
default:
color = BlindGetPixelColor(x,y);
}
if (red) red[color.rgbRed]++;
if (green) green[color.rgbGreen]++;
if (blue) blue[color.rgbBlue]++;
if (gray) gray[(BYTE)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue)]++;
}
}
}
long n=0;
for (int i=0; i<256; i++){
if (red && red[i]>n) n=red[i];
if (green && green[i]>n) n=green[i];
if (blue && blue[i]>n) n=blue[i];
if (gray && gray[i]>n) n=gray[i];
}
return n;
}
////////////////////////////////////////////////////////////////////////////////
/**
* HistogramStretch
* \param method: 0 = luminance (default), 1 = linked channels , 2 = independent channels.
* \param threshold: minimum percentage level in the histogram to recognize it as meaningful. Range: 0.0 to 1.0; default = 0; typical = 0.005 (0.5%);
* \return true if everything is ok
* \author [dave] and [nipper]; changes [DP]
*/
bool CxImage::HistogramStretch(long method, double threshold)
{
if (!pDib) return false;
double dbScaler = 50.0/head.biHeight;
long x,y;
if ((head.biBitCount==8) && IsGrayScale()){
double p[256];
memset(p, 0, 256*sizeof(double));
for (y=0; y<head.biHeight; y++)
{
info.nProgress = (long)(y*dbScaler);
if (info.nEscape) break;
for (x=0; x<head.biWidth; x++) {
p[BlindGetPixelIndex(x, y)]++;
}
}
double maxh = 0;
for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
threshold *= maxh;
int minc = 0;
while (minc<255 && p[minc]<=threshold) minc++;
int maxc = 255;
while (maxc>0 && p[maxc]<=threshold) maxc--;
if (minc == 0 && maxc == 255) return true;
if (minc >= maxc) return true;
// calculate LUT
BYTE lut[256];
for (x = 0; x <256; x++){
lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
}
for (y=0; y<head.biHeight; y++) {
if (info.nEscape) break;
info.nProgress = (long)(50.0+y*dbScaler);
for (x=0; x<head.biWidth; x++)
{
BlindSetPixelIndex(x, y, lut[BlindGetPixelIndex(x, y)]);
}
}
} else {
switch(method){
case 1:
{ // <nipper>
double p[256];
memset(p, 0, 256*sizeof(double));
for (y=0; y<head.biHeight; y++)
{
info.nProgress = (long)(y*dbScaler);
if (info.nEscape) break;
for (x=0; x<head.biWidth; x++) {
RGBQUAD color = BlindGetPixelColor(x, y);
p[color.rgbRed]++;
p[color.rgbBlue]++;
p[color.rgbGreen]++;
}
}
double maxh = 0;
for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
threshold *= maxh;
int minc = 0;
while (minc<255 && p[minc]<=threshold) minc++;
int maxc = 255;
while (maxc>0 && p[maxc]<=threshold) maxc--;
if (minc == 0 && maxc == 255) return true;
if (minc >= maxc) return true;
// calculate LUT
BYTE lut[256];
for (x = 0; x <256; x++){
lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
}
// normalize image
for (y=0; y<head.biHeight; y++) {
if (info.nEscape) break;
info.nProgress = (long)(50.0+y*dbScaler);
for (x=0; x<head.biWidth; x++)
{
RGBQUAD color = BlindGetPixelColor(x, y);
color.rgbRed = lut[color.rgbRed];
color.rgbBlue = lut[color.rgbBlue];
color.rgbGreen = lut[color.rgbGreen];
BlindSetPixelColor(x, y, color);
}
}
}
break;
case 2:
{ // <nipper>
double pR[256];
memset(pR, 0, 256*sizeof(double));
double pG[256];
memset(pG, 0, 256*sizeof(double));
double pB[256];
memset(pB, 0, 256*sizeof(double));
for (y=0; y<head.biHeight; y++)
{
info.nProgress = (long)(y*dbScaler);
if (info.nEscape) break;
for (long x=0; x<head.biWidth; x++) {
RGBQUAD color = BlindGetPixelColor(x, y);
pR[color.rgbRed]++;
pB[color.rgbBlue]++;
pG[color.rgbGreen]++;
}
}
double maxh = 0;
for (y=0; y<255; y++) if (maxh < pR[y]) maxh = pR[y];
double threshold2 = threshold*maxh;
int minR = 0;
while (minR<255 && pR[minR]<=threshold2) minR++;
int maxR = 255;
while (maxR>0 && pR[maxR]<=threshold2) maxR--;
maxh = 0;
for (y=0; y<255; y++) if (maxh < pG[y]) maxh = pG[y];
threshold2 = threshold*maxh;
int minG = 0;
while (minG<255 && pG[minG]<=threshold2) minG++;
int maxG = 255;
while (maxG>0 && pG[maxG]<=threshold2) maxG--;
maxh = 0;
for (y=0; y<255; y++) if (maxh < pB[y]) maxh = pB[y];
threshold2 = threshold*maxh;
int minB = 0;
while (minB<255 && pB[minB]<=threshold2) minB++;
int maxB = 255;
while (maxB>0 && pB[maxB]<=threshold2) maxB--;
if (minR == 0 && maxR == 255 && minG == 0 && maxG == 255 && minB == 0 && maxB == 255)
return true;
// calculate LUT
BYTE lutR[256];
BYTE range = maxR - minR;
if (range != 0) {
for (x = 0; x <256; x++){
lutR[x] = (BYTE)max(0,min(255,(255 * (x - minR) / range)));
}
} else lutR[minR] = minR;
BYTE lutG[256];
range = maxG - minG;
if (range != 0) {
for (x = 0; x <256; x++){
lutG[x] = (BYTE)max(0,min(255,(255 * (x - minG) / range)));
}
} else lutG[minG] = minG;
BYTE lutB[256];
range = maxB - minB;
if (range != 0) {
for (x = 0; x <256; x++){
lutB[x] = (BYTE)max(0,min(255,(255 * (x - minB) / range)));
}
} else lutB[minB] = minB;
// normalize image
for (y=0; y<head.biHeight; y++)
{
info.nProgress = (long)(50.0+y*dbScaler);
if (info.nEscape) break;
for (x=0; x<head.biWidth; x++)
{
RGBQUAD color = BlindGetPixelColor(x, y);
color.rgbRed = lutR[color.rgbRed];
color.rgbBlue = lutB[color.rgbBlue];
color.rgbGreen = lutG[color.rgbGreen];
BlindSetPixelColor(x, y, color);
}
}
}
break;
default:
{ // <dave>
double p[256];
memset(p, 0, 256*sizeof(double));
for (y=0; y<head.biHeight; y++)
{
info.nProgress = (long)(y*dbScaler);
if (info.nEscape) break;
for (x=0; x<head.biWidth; x++) {
RGBQUAD color = BlindGetPixelColor(x, y);
p[RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue)]++;
}
}
double maxh = 0;
for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
threshold *= maxh;
int minc = 0;
while (minc<255 && p[minc]<=threshold) minc++;
int maxc = 255;
while (maxc>0 && p[maxc]<=threshold) maxc--;
if (minc == 0 && maxc == 255) return true;
if (minc >= maxc) return true;
// calculate LUT
BYTE lut[256];
for (x = 0; x <256; x++){
lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
}
for(y=0; y<head.biHeight; y++){
info.nProgress = (long)(50.0+y*dbScaler);
if (info.nEscape) break;
for(x=0; x<head.biWidth; x++){
RGBQUAD color = BlindGetPixelColor( x, y );
RGBQUAD yuvClr = RGBtoYUV(color);
yuvClr.rgbRed = lut[yuvClr.rgbRed];
color = YUVtoRGB(yuvClr);
BlindSetPixelColor( x, y, color );
}
}
}
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// HistogramEqualize function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramEqualize()
{
if (!pDib) return false;
int histogram[256];
int map[256];
int equalize_map[256];
int x, y, i, j;
RGBQUAD color;
RGBQUAD yuvClr;
unsigned int YVal, high, low;
memset( &histogram, 0, sizeof(int) * 256 );
memset( &map, 0, sizeof(int) * 256 );
memset( &equalize_map, 0, sizeof(int) * 256 );
// form histogram
for(y=0; y < head.biHeight; y++){
info.nProgress = (long)(50*y/head.biHeight);
if (info.nEscape) break;
for(x=0; x < head.biWidth; x++){
color = BlindGetPixelColor( x, y );
YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
histogram[YVal]++;
}
}
// integrate the histogram to get the equalization map.
j = 0;
for(i=0; i <= 255; i++){
j += histogram[i];
map[i] = j;
}
// equalize
low = map[0];
high = map[255];
if (low == high) return false;
for( i = 0; i <= 255; i++ ){
equalize_map[i] = (unsigned int)((((double)( map[i] - low ) ) * 255) / ( high - low ) );
}
// stretch the histogram
if(head.biClrUsed == 0){ // No Palette
for( y = 0; y < head.biHeight; y++ ){
info.nProgress = (long)(50+50*y/head.biHeight);
if (info.nEscape) break;
for( x = 0; x < head.biWidth; x++ ){
color = BlindGetPixelColor( x, y );
yuvClr = RGBtoYUV(color);
yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed];
color = YUVtoRGB(yuvClr);
BlindSetPixelColor( x, y, color );
}
}
} else { // Palette
for( i = 0; i < (int)head.biClrUsed; i++ ){
color = GetPaletteColor((BYTE)i);
yuvClr = RGBtoYUV(color);
yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed];
color = YUVtoRGB(yuvClr);
SetPaletteColor( (BYTE)i, color );
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// HistogramNormalize function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramNormalize()
{
if (!pDib) return false;
int histogram[256];
int threshold_intensity, intense;
int x, y, i;
unsigned int normalize_map[256];
unsigned int high, low, YVal;
RGBQUAD color;
RGBQUAD yuvClr;
memset( &histogram, 0, sizeof( int ) * 256 );
memset( &normalize_map, 0, sizeof( unsigned int ) * 256 );
// form histogram
for(y=0; y < head.biHeight; y++){
info.nProgress = (long)(50*y/head.biHeight);
if (info.nEscape) break;
for(x=0; x < head.biWidth; x++){
color = BlindGetPixelColor( x, y );
YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
histogram[YVal]++;
}
}
// find histogram boundaries by locating the 1 percent levels
threshold_intensity = ( head.biWidth * head.biHeight) / 100;
intense = 0;
for( low = 0; low < 255; low++ ){
intense += histogram[low];
if( intense > threshold_intensity ) break;
}
intense = 0;
for( high = 255; high != 0; high--){
intense += histogram[ high ];
if( intense > threshold_intensity ) break;
}
if ( low == high ){
// Unreasonable contrast; use zero threshold to determine boundaries.
threshold_intensity = 0;
intense = 0;
for( low = 0; low < 255; low++){
intense += histogram[low];
if( intense > threshold_intensity ) break;
}
intense = 0;
for( high = 255; high != 0; high-- ){
intense += histogram [high ];
if( intense > threshold_intensity ) break;
}
}
if( low == high ) return false; // zero span bound
// Stretch the histogram to create the normalized image mapping.
for(i = 0; i <= 255; i++){
if ( i < (int) low ){
normalize_map[i] = 0;
} else {
if(i > (int) high)
normalize_map[i] = 255;
else
normalize_map[i] = ( 255 - 1) * ( i - low) / ( high - low );
}
}
// Normalize
if( head.biClrUsed == 0 ){
for( y = 0; y < head.biHeight; y++ ){
info.nProgress = (long)(50+50*y/head.biHeight);
if (info.nEscape) break;
for( x = 0; x < head.biWidth; x++ ){
color = BlindGetPixelColor( x, y );
yuvClr = RGBtoYUV( color );
yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed];
color = YUVtoRGB( yuvClr );
BlindSetPixelColor( x, y, color );
}
}
} else {
for(i = 0; i < (int)head.biClrUsed; i++){
color = GetPaletteColor( (BYTE)i );
yuvClr = RGBtoYUV( color );
yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed];
color = YUVtoRGB( yuvClr );
SetPaletteColor( (BYTE)i, color );
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// HistogramLog function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramLog()
{
if (!pDib) return false;
//q(i,j) = 255/log(1 + |high|) * log(1 + |p(i,j)|);
int x, y, i;
RGBQUAD color;
RGBQUAD yuvClr;
unsigned int YVal, high = 1;
// Find Highest Luminance Value in the Image
if( head.biClrUsed == 0 ){ // No Palette
for(y=0; y < head.biHeight; y++){
info.nProgress = (long)(50*y/head.biHeight);
if (info.nEscape) break;
for(x=0; x < head.biWidth; x++){
color = BlindGetPixelColor( x, y );
YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
if (YVal > high ) high = YVal;
}
}
} else { // Palette
for(i = 0; i < (int)head.biClrUsed; i++){
color = GetPaletteColor((BYTE)i);
YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
if (YVal > high ) high = YVal;
}
}
// Logarithm Operator
double k = 255.0 / ::log( 1.0 + (double)high );
if( head.biClrUsed == 0 ){
for( y = 0; y < head.biHeight; y++ ){
info.nProgress = (long)(50+50*y/head.biHeight);
if (info.nEscape) break;
for( x = 0; x < head.biWidth; x++ ){
color = BlindGetPixelColor( x, y );
yuvClr = RGBtoYUV( color );
yuvClr.rgbRed = (BYTE)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );
color = YUVtoRGB( yuvClr );
BlindSetPixelColor( x, y, color );
}
}
} else {
for(i = 0; i < (int)head.biClrUsed; i++){
color = GetPaletteColor( (BYTE)i );
yuvClr = RGBtoYUV( color );
yuvClr.rgbRed = (BYTE)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );
color = YUVtoRGB( yuvClr );
SetPaletteColor( (BYTE)i, color );
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// HistogramRoot function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramRoot()
{
if (!pDib) return false;
//q(i,j) = sqrt(|p(i,j)|);
int x, y, i;
RGBQUAD color;
RGBQUAD yuvClr;
double dtmp;
unsigned int YVal, high = 1;
// Find Highest Luminance Value in the Image
if( head.biClrUsed == 0 ){ // No Palette
for(y=0; y < head.biHeight; y++){
info.nProgress = (long)(50*y/head.biHeight);
if (info.nEscape) break;
for(x=0; x < head.biWidth; x++){
color = BlindGetPixelColor( x, y );
YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
if (YVal > high ) high = YVal;
}
}
} else { // Palette
for(i = 0; i < (int)head.biClrUsed; i++){
color = GetPaletteColor((BYTE)i);
YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
if (YVal > high ) high = YVal;
}
}
// Root Operator
double k = 128.0 / ::log( 1.0 + (double)high );
if( head.biClrUsed == 0 ){
for( y = 0; y < head.biHeight; y++ ){
info.nProgress = (long)(50+50*y/head.biHeight);
if (info.nEscape) break;
for( x = 0; x < head.biWidth; x++ ){
color = BlindGetPixelColor( x, y );
yuvClr = RGBtoYUV( color );
dtmp = k * ::sqrt( (double)yuvClr.rgbRed );
if ( dtmp > 255.0 ) dtmp = 255.0;
if ( dtmp < 0 ) dtmp = 0;
yuvClr.rgbRed = (BYTE)dtmp;
color = YUVtoRGB( yuvClr );
BlindSetPixelColor( x, y, color );
}
}
} else {
for(i = 0; i < (int)head.biClrUsed; i++){
color = GetPaletteColor( (BYTE)i );
yuvClr = RGBtoYUV( color );
dtmp = k * ::sqrt( (double)yuvClr.rgbRed );
if ( dtmp > 255.0 ) dtmp = 255.0;
if ( dtmp < 0 ) dtmp = 0;
yuvClr.rgbRed = (BYTE)dtmp;
color = YUVtoRGB( yuvClr );
SetPaletteColor( (BYTE)i, color );
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -1,472 +0,0 @@
/*
* File: ximaico.cpp
* Purpose: Platform Independent ICON Image Class Loader and Writer (MS version)
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximaico.h"
#if CXIMAGE_SUPPORT_ICO
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageICO::Decode(CxFile *hFile)
{
if (hFile==NULL) return false;
DWORD off = hFile->Tell(); //<yuandi>
int page=info.nFrame; //internal icon structure indexes
// read the first part of the header
ICONHEADER icon_header;
hFile->Read(&icon_header,sizeof(ICONHEADER),1);
icon_header.idType = ntohs(icon_header.idType);
icon_header.idCount = ntohs(icon_header.idCount);
// check if it's an icon or a cursor
if ((icon_header.idReserved == 0) && ((icon_header.idType == 1)||(icon_header.idType == 2))) {
info.nNumFrames = icon_header.idCount;
// load the icon descriptions
ICONDIRENTRY *icon_list = (ICONDIRENTRY *)malloc(icon_header.idCount * sizeof(ICONDIRENTRY));
int c;
for (c = 0; c < icon_header.idCount; c++) {
hFile->Read(icon_list + c, sizeof(ICONDIRENTRY), 1);
icon_list[c].wPlanes = ntohs(icon_list[c].wPlanes);
icon_list[c].wBitCount = ntohs(icon_list[c].wBitCount);
icon_list[c].dwBytesInRes = ntohl(icon_list[c].dwBytesInRes);
icon_list[c].dwImageOffset = ntohl(icon_list[c].dwImageOffset);
}
if ((page>=0)&&(page<icon_header.idCount)){
if (info.nEscape == -1) {
// Return output dimensions only
head.biWidth = icon_list[page].bWidth;
head.biHeight = icon_list[page].bHeight;
#if CXIMAGE_SUPPORT_PNG
if (head.biWidth==0 && head.biHeight==0)
{ // Vista icon support
hFile->Seek(off + icon_list[page].dwImageOffset, SEEK_SET);
CxImage png;
png.SetEscape(-1);
if (png.Decode(hFile,CXIMAGE_FORMAT_PNG)){
Transfer(png);
info.nNumFrames = icon_header.idCount;
}
}
#endif //CXIMAGE_SUPPORT_PNG
free(icon_list);
info.dwType = CXIMAGE_FORMAT_ICO;
return true;
}
// get the bit count for the colors in the icon <CoreyRLucier>
BITMAPINFOHEADER bih;
hFile->Seek(off + icon_list[page].dwImageOffset, SEEK_SET);
if (icon_list[page].bWidth==0 && icon_list[page].bHeight==0)
{ // Vista icon support
#if CXIMAGE_SUPPORT_PNG
CxImage png;
if (png.Decode(hFile,CXIMAGE_FORMAT_PNG)){
Transfer(png);
info.nNumFrames = icon_header.idCount;
}
SetType(CXIMAGE_FORMAT_ICO);
#endif //CXIMAGE_SUPPORT_PNG
}
else
{ // standard icon
hFile->Read(&bih,sizeof(BITMAPINFOHEADER),1);
bihtoh(&bih);
c = bih.biBitCount;
// allocate memory for one icon
Create(icon_list[page].bWidth,icon_list[page].bHeight, c, CXIMAGE_FORMAT_ICO); //image creation
// read the palette
RGBQUAD pal[256];
if (bih.biClrUsed)
hFile->Read(pal,bih.biClrUsed*sizeof(RGBQUAD), 1);
else
hFile->Read(pal,head.biClrUsed*sizeof(RGBQUAD), 1);
SetPalette(pal,head.biClrUsed); //palette assign
//read the icon
if (c<=24){
hFile->Read(info.pImage, head.biSizeImage, 1);
} else { // 32 bit icon
BYTE* buf=(BYTE*)malloc(4*head.biHeight*head.biWidth);
BYTE* src = buf;
hFile->Read(buf, 4*head.biHeight*head.biWidth, 1);
#if CXIMAGE_SUPPORT_ALPHA
if (!AlphaIsValid()) AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA
for (long y = 0; y < head.biHeight; y++) {
BYTE* dst = GetBits(y);
for(long x=0;x<head.biWidth;x++){
*dst++=src[0];
*dst++=src[1];
*dst++=src[2];
#if CXIMAGE_SUPPORT_ALPHA
AlphaSet(x,y,src[3]);
#endif //CXIMAGE_SUPPORT_ALPHA
src+=4;
}
}
free(buf);
}
// apply the AND and XOR masks
int maskwdt = ((head.biWidth+31) / 32) * 4; //line width of AND mask (always 1 Bpp)
int masksize = head.biHeight * maskwdt; //size of mask
BYTE *mask = (BYTE *)malloc(masksize);
if (hFile->Read(mask, masksize, 1)){
bool bGoodMask=false;
for (int im=0;im<masksize;im++){
if (mask[im]!=255){
bGoodMask=true;
break;
}
}
if (bGoodMask){
#if CXIMAGE_SUPPORT_ALPHA
bool bNeedAlpha = false;
if (!AlphaIsValid()){
AlphaCreate();
} else {
bNeedAlpha=true; //32bit icon
}
int x,y;
for (y = 0; y < head.biHeight; y++) {
for (x = 0; x < head.biWidth; x++) {
if (((mask[y*maskwdt+(x>>3)]>>(7-x%8))&0x01)){
AlphaSet(x,y,0);
bNeedAlpha=true;
}
}
}
if (!bNeedAlpha) AlphaDelete();
#endif //CXIMAGE_SUPPORT_ALPHA
//check if there is only one transparent color
RGBQUAD cc,ct;
long* pcc = (long*)&cc;
long* pct = (long*)&ct;
int nTransColors=0;
int nTransIndex=0;
for (y = 0; y < head.biHeight; y++){
for (x = 0; x < head.biWidth; x++){
if (((mask[y*maskwdt+(x>>3)] >> (7-x%8)) & 0x01)){
cc = GetPixelColor(x,y,false);
if (nTransColors==0){
nTransIndex = GetPixelIndex(x,y);
nTransColors++;
ct = cc;
} else {
if (*pct!=*pcc){
nTransColors++;
}
}
}
}
}
if (nTransColors==1){
SetTransColor(ct);
SetTransIndex(nTransIndex);
#if CXIMAGE_SUPPORT_ALPHA
AlphaDelete(); //because we have a unique transparent color in the image
#endif //CXIMAGE_SUPPORT_ALPHA
}
// <vho> - Transparency support w/o Alpha support
if (c <= 8){ // only for icons with less than 256 colors (XP icons need alpha).
// find a color index, which is not used in the image
// it is almost sure to find one, bcs. nobody uses all possible colors for an icon
BYTE colorsUsed[256];
memset(colorsUsed, 0, sizeof(colorsUsed));
for (y = 0; y < head.biHeight; y++){
for (x = 0; x < head.biWidth; x++){
colorsUsed[BlindGetPixelIndex(x,y)] = 1;
}
}
int iTransIdx = -1;
for (x = (int)(head.biClrUsed-1); x>=0 ; x--){
if (colorsUsed[x] == 0){
iTransIdx = x; // this one is not in use. we may use it as transparent color
break;
}
}
// Go thru image and set unused color as transparent index if needed
if (iTransIdx >= 0){
bool bNeedTrans = false;
for (y = 0; y < head.biHeight; y++){
for (x = 0; x < head.biWidth; x++){
// AND mask (Each Byte represents 8 Pixels)
if (((mask[y*maskwdt+(x>>3)] >> (7-x%8)) & 0x01)){
// AND mask is set (!=0). This is a transparent part
SetPixelIndex(x, y, (BYTE)iTransIdx);
bNeedTrans = true;
}
}
}
// set transparent index if needed
if (bNeedTrans) SetTransIndex(iTransIdx);
#if CXIMAGE_SUPPORT_ALPHA
AlphaDelete(); //because we have a transparent color in the palette
#endif //CXIMAGE_SUPPORT_ALPHA
}
}
} else {
SetTransIndex(0); //empty mask, set black as transparent color
Negative();
}
}
free(mask);
}
free(icon_list);
// icon has been loaded successfully!
return true;
}
free(icon_list);
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
// Thanks to <Alas>
bool CxImageICO::Encode(CxFile * hFile, CxImage ** pImages, int nPageCount)
{
cx_try
{
if (hFile==NULL) cx_throw("invalid file pointer");
if (pImages==NULL || nPageCount<=0) cx_throw("multipage ICO, no images!");
int i;
for (i=0; i<nPageCount; i++){
if (pImages[i]==NULL)
cx_throw("Bad image pointer");
if (!(pImages[i]->IsValid()))
cx_throw("Empty image");
}
CxImageICO ghost;
for (i=0; i<nPageCount; i++){ //write headers
ghost.Ghost(pImages[i]);
ghost.info.nNumFrames = nPageCount;
if (i==0) {
if (!ghost.Encode(hFile,false,nPageCount))
cx_throw("Error writing ICO file header");
}
if (!ghost.Encode(hFile,true,nPageCount))
cx_throw("Error saving ICO image header");
}
for (i=0; i<nPageCount; i++){ //write bodies
ghost.Ghost(pImages[i]);
ghost.info.nNumFrames = nPageCount;
if (!ghost.Encode(hFile,true,i))
cx_throw("Error saving ICO body");
}
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImageICO::Encode(CxFile * hFile, bool bAppend, int nPageCount)
{
if (EncodeSafeCheck(hFile)) return false;
#if CXIMAGE_SUPPORT_PNG == 0
//check format limits
if ((head.biWidth>255)||(head.biHeight>255)){
strcpy(info.szLastError,"Can't save this image as icon");
return false;
}
#endif
//prepare the palette struct
RGBQUAD* pal=GetPalette();
if (head.biBitCount<=8 && pal==NULL) return false;
int maskwdt=((head.biWidth+31)/32)*4; //mask line width
int masksize=head.biHeight * maskwdt; //size of mask
int bitcount=head.biBitCount;
int imagesize=head.biSizeImage;
#if CXIMAGE_SUPPORT_ALPHA
if (AlphaIsValid() && head.biClrUsed==0){
bitcount=32;
imagesize=4*head.biHeight*head.biWidth;
}
#endif
//fill the icon headers
int nPages = nPageCount;
if (nPages<1) nPages = 1;
ICONHEADER icon_header={0,1,nPages};
if (!bAppend)
m_dwImageOffset = sizeof(ICONHEADER) + nPages * sizeof(ICONDIRENTRY);
DWORD dwBytesInRes = sizeof(BITMAPINFOHEADER)+head.biClrUsed*sizeof(RGBQUAD)+imagesize+masksize;
ICONDIRENTRY icon_list={
(BYTE)head.biWidth,
(BYTE)head.biHeight,
(BYTE)head.biClrUsed,
0, 0,
(WORD)bitcount,
dwBytesInRes,
m_dwImageOffset
};
BITMAPINFOHEADER bi={
sizeof(BITMAPINFOHEADER),
head.biWidth,
2*head.biHeight,
1,
(WORD)bitcount,
0, imagesize,
0, 0, 0, 0
};
#if CXIMAGE_SUPPORT_PNG // Vista icon support
CxImage png(*this);
CxMemFile memfile;
if (head.biWidth>255 || head.biHeight>255){
icon_list.bWidth = icon_list.bHeight = 0;
memfile.Open();
png.Encode(&memfile,CXIMAGE_FORMAT_PNG);
icon_list.dwBytesInRes = dwBytesInRes = memfile.Size();
}
#endif //CXIMAGE_SUPPORT_PNG
if (!bAppend){
icon_header.idType = ntohs(icon_header.idType);
icon_header.idCount = ntohs(icon_header.idCount);
hFile->Write(&icon_header,sizeof(ICONHEADER),1); //write the file header
icon_header.idType = ntohs(icon_header.idType);
icon_header.idCount = ntohs(icon_header.idCount);
}
if ((bAppend && nPageCount==info.nNumFrames) || (!bAppend && nPageCount==0)){
icon_list.wPlanes = ntohs(icon_list.wPlanes);
icon_list.wBitCount = ntohs(icon_list.wBitCount);
icon_list.dwBytesInRes = ntohl(icon_list.dwBytesInRes);
icon_list.dwImageOffset = ntohl(icon_list.dwImageOffset);
hFile->Write(&icon_list,sizeof(ICONDIRENTRY),1); //write the image entry
icon_list.wPlanes = ntohs(icon_list.wPlanes);
icon_list.wBitCount = ntohs(icon_list.wBitCount);
icon_list.dwBytesInRes = ntohl(icon_list.dwBytesInRes);
icon_list.dwImageOffset = ntohl(icon_list.dwImageOffset);
m_dwImageOffset += dwBytesInRes; //update offset for next header
}
if ((bAppend && nPageCount<info.nNumFrames) || (!bAppend && nPageCount==0))
{
#if CXIMAGE_SUPPORT_PNG
if (icon_list.bWidth==0 && icon_list.bHeight==0) { // Vista icon support
hFile->Write(memfile.GetBuffer(false),dwBytesInRes,1);
} else
#endif //CXIMAGE_SUPPORT_PNG
{ // standard icon
bihtoh(&bi);
hFile->Write(&bi,sizeof(BITMAPINFOHEADER),1); //write the image header
bihtoh(&bi);
bool bTransparent = info.nBkgndIndex >= 0;
RGBQUAD ct = GetTransColor();
if (pal){
if (bTransparent) SetPaletteColor((BYTE)info.nBkgndIndex,0,0,0,0);
hFile->Write(pal,head.biClrUsed*sizeof(RGBQUAD),1); //write palette
if (bTransparent) SetPaletteColor((BYTE)info.nBkgndIndex,ct);
}
#if CXIMAGE_SUPPORT_ALPHA
if (AlphaIsValid() && head.biClrUsed==0){
BYTE* buf=(BYTE*)malloc(imagesize);
BYTE* dst = buf;
for (long y = 0; y < head.biHeight; y++) {
BYTE* src = GetBits(y);
for(long x=0;x<head.biWidth;x++){
*dst++=*src++;
*dst++=*src++;
*dst++=*src++;
*dst++=AlphaGet(x,y);
}
}
hFile->Write(buf,imagesize, 1);
free(buf);
} else {
hFile->Write(info.pImage,imagesize,1); //write image
}
#else
hFile->Write(info.pImage,imagesize,1); //write image
#endif
//save transparency mask
BYTE* mask=(BYTE*)calloc(masksize,1); //create empty AND/XOR masks
if (!mask) return false;
//prepare the variables to build the mask
BYTE* iDst;
int pos,i;
RGBQUAD c={0,0,0,0};
long* pc = (long*)&c;
long* pct= (long*)&ct;
#if CXIMAGE_SUPPORT_ALPHA
bool bAlphaPaletteIsValid = AlphaPaletteIsValid();
bool bAlphaIsValid = AlphaIsValid();
#endif
//build the mask
for (int y = 0; y < head.biHeight; y++) {
for (int x = 0; x < head.biWidth; x++) {
i=0;
#if CXIMAGE_SUPPORT_ALPHA
if (bAlphaIsValid && AlphaGet(x,y)==0) i=1;
if (bAlphaPaletteIsValid && BlindGetPixelColor(x,y).rgbReserved==0) i=1;
#endif
c=GetPixelColor(x,y,false);
if (bTransparent && *pc==*pct) i=1;
iDst = mask + y*maskwdt + (x>>3);
pos = 7-x%8;
*iDst &= ~(0x01<<pos);
*iDst |= ((i & 0x01)<<pos);
}
}
//write AND/XOR masks
hFile->Write(mask,masksize,1);
free(mask);
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ICO

View File

@@ -1,58 +0,0 @@
/*
* File: ximaico.h
* Purpose: ICON Image Class Loader and Writer
*/
/* ==========================================================
* CxImageICO (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
* ==========================================================
*/
#if !defined(__ximaICO_h)
#define __ximaICO_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_ICO
class CxImageICO: public CxImage
{
typedef struct tagIconDirectoryEntry {
BYTE bWidth;
BYTE bHeight;
BYTE bColorCount;
BYTE bReserved;
WORD wPlanes;
WORD wBitCount;
DWORD dwBytesInRes;
DWORD dwImageOffset;
} ICONDIRENTRY;
typedef struct tagIconDir {
WORD idReserved;
WORD idType;
WORD idCount;
} ICONHEADER;
public:
CxImageICO(): CxImage(CXIMAGE_FORMAT_ICO) {m_dwImageOffset=0;}
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_ICO);}
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_ICO);}
bool Decode(CxFile * hFile);
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile, bool bAppend=false, int nPageCount=0);
bool Encode(CxFile * hFile, CxImage ** pImages, int nPageCount);
bool Encode(FILE *hFile, bool bAppend=false, int nPageCount=0)
{ CxIOFile file(hFile); return Encode(&file,bAppend,nPageCount); }
bool Encode(FILE *hFile, CxImage ** pImages, int nPageCount)
{ CxIOFile file(hFile); return Encode(&file, pImages, nPageCount); }
#endif // CXIMAGE_SUPPORT_ENCODE
protected:
DWORD m_dwImageOffset;
};
#endif
#endif

View File

@@ -1,917 +0,0 @@
// ximainfo.cpp : main attributes
/* 03/10/2004 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximage.h"
////////////////////////////////////////////////////////////////////////////////
/**
* \return the color used for transparency, and/or for background color
*/
RGBQUAD CxImage::GetTransColor()
{
if (head.biBitCount<24 && info.nBkgndIndex>=0) return GetPaletteColor((BYTE)info.nBkgndIndex);
return info.nBkgndColor;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Gets the index used for transparency. Returns -1 for no transparancy.
*/
long CxImage::GetTransIndex() const
{
return info.nBkgndIndex;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the index used for transparency with 1, 4 and 8 bpp images. Set to -1 to remove the effect.
*/
void CxImage::SetTransIndex(long idx)
{
if (idx<(long)head.biClrUsed)
info.nBkgndIndex = idx;
else
info.nBkgndIndex = 0;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the color used for transparency with 24 bpp images.
* You must call SetTransIndex(0) to enable the effect, SetTransIndex(-1) to disable it.
*/
void CxImage::SetTransColor(RGBQUAD rgb)
{
rgb.rgbReserved=0;
info.nBkgndColor = rgb;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::IsTransparent() const
{
return info.nBkgndIndex>=0; // <vho>
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns true if the image has 256 colors or less.
*/
bool CxImage::IsIndexed() const
{
return head.biClrUsed!=0;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return 1 = indexed, 2 = RGB, 4 = RGBA
*/
BYTE CxImage::GetColorType()
{
BYTE b = (BYTE)((head.biBitCount>8) ? 2 /*COLORTYPE_COLOR*/ : 1 /*COLORTYPE_PALETTE*/);
#if CXIMAGE_SUPPORT_ALPHA
if (AlphaIsValid()) b = 4 /*COLORTYPE_ALPHA*/;
#endif //CXIMAGE_SUPPORT_ALPHA
return b;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return Resolution for TIFF, JPEG, PNG and BMP formats.
*/
long CxImage::GetXDPI() const
{
return info.xDPI;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return Resolution for TIFF, JPEG, PNG and BMP formats.
*/
long CxImage::GetYDPI() const
{
return info.yDPI;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Set resolution for TIFF, JPEG, PNG and BMP formats.
*/
void CxImage::SetXDPI(long dpi)
{
if (dpi<=0) dpi = CXIMAGE_DEFAULT_DPI;
info.xDPI = dpi;
head.biXPelsPerMeter = (long) floor(dpi * 10000.0 / 254.0 + 0.5);
if (pDib) ((BITMAPINFOHEADER*)pDib)->biXPelsPerMeter = head.biXPelsPerMeter;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Set resolution for TIFF, JPEG, PNG and BMP formats.
*/
void CxImage::SetYDPI(long dpi)
{
if (dpi<=0) dpi = CXIMAGE_DEFAULT_DPI;
info.yDPI = dpi;
head.biYPelsPerMeter = (long) floor(dpi * 10000.0 / 254.0 + 0.5);
if (pDib) ((BITMAPINFOHEADER*)pDib)->biYPelsPerMeter = head.biYPelsPerMeter;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \sa SetFlags
*/
DWORD CxImage::GetFlags() const
{
return info.dwFlags;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Image flags, for future use
* \param flags
* - 0x??00000 = reserved for 16 bit, CMYK, multilayer
* - 0x00??0000 = blend modes
* - 0x0000???? = layer id or user flags
*
* \param bLockReservedFlags protects the "reserved" and "blend modes" flags
*/
void CxImage::SetFlags(DWORD flags, bool bLockReservedFlags)
{
if (bLockReservedFlags) info.dwFlags = flags & 0x0000ffff;
else info.dwFlags = flags;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \sa SetCodecOption
*/
DWORD CxImage::GetCodecOption(DWORD imagetype)
{
imagetype = GetTypeIndexFromId(imagetype);
if (imagetype==0){
imagetype = GetTypeIndexFromId(GetType());
}
return info.dwCodecOpt[imagetype];
}
////////////////////////////////////////////////////////////////////////////////
/**
* Encode option for GIF, TIF and JPG.
* - GIF : 0 = LZW (default), 1 = none, 2 = RLE.
* - TIF : 0 = automatic (default), or a valid compression code as defined in "tiff.h" (COMPRESSION_NONE = 1, COMPRESSION_CCITTRLE = 2, ...)
* - JPG : valid values stored in enum CODEC_OPTION ( ENCODE_BASELINE = 0x01, ENCODE_PROGRESSIVE = 0x10, ...)
* - RAW : valid values stored in enum CODEC_OPTION ( DECODE_QUALITY_LIN = 0x00, DECODE_QUALITY_VNG = 0x01, ...)
*
* \return true if everything is ok
*/
bool CxImage::SetCodecOption(DWORD opt, DWORD imagetype)
{
imagetype = GetTypeIndexFromId(imagetype);
if (imagetype==0){
imagetype = GetTypeIndexFromId(GetType());
}
info.dwCodecOpt[imagetype] = opt;
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return internal hDib object..
*/
void* CxImage::GetDIB() const
{
return pDib;
}
////////////////////////////////////////////////////////////////////////////////
DWORD CxImage::GetHeight() const
{
return head.biHeight;
}
////////////////////////////////////////////////////////////////////////////////
DWORD CxImage::GetWidth() const
{
return head.biWidth;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return DWORD aligned width of the image.
*/
DWORD CxImage::GetEffWidth() const
{
return info.dwEffWidth;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return 2, 16, 256; 0 for RGB images.
*/
DWORD CxImage::GetNumColors() const
{
return head.biClrUsed;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return: 1, 4, 8, 24.
*/
WORD CxImage::GetBpp() const
{
return head.biBitCount;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return original image format
* \sa ENUM_CXIMAGE_FORMATS.
*/
DWORD CxImage::GetType() const
{
return info.dwType;
}
////////////////////////////////////////////////////////////////////////////////
/**
* change image format identifier
* \sa ENUM_CXIMAGE_FORMATS.
*/
bool CxImage::SetType(DWORD type)
{
switch (type){
#if CXIMAGE_SUPPORT_BMP
case CXIMAGE_FORMAT_BMP:
#endif
#if CXIMAGE_SUPPORT_GIF
case CXIMAGE_FORMAT_GIF:
#endif
#if CXIMAGE_SUPPORT_JPG
case CXIMAGE_FORMAT_JPG:
#endif
#if CXIMAGE_SUPPORT_PNG
case CXIMAGE_FORMAT_PNG:
#endif
#if CXIMAGE_SUPPORT_MNG
case CXIMAGE_FORMAT_MNG:
#endif
#if CXIMAGE_SUPPORT_ICO
case CXIMAGE_FORMAT_ICO:
#endif
#if CXIMAGE_SUPPORT_TIF
case CXIMAGE_FORMAT_TIF:
#endif
#if CXIMAGE_SUPPORT_TGA
case CXIMAGE_FORMAT_TGA:
#endif
#if CXIMAGE_SUPPORT_PCX
case CXIMAGE_FORMAT_PCX:
#endif
#if CXIMAGE_SUPPORT_WBMP
case CXIMAGE_FORMAT_WBMP:
#endif
#if CXIMAGE_SUPPORT_WMF
case CXIMAGE_FORMAT_WMF:
#endif
#if CXIMAGE_SUPPORT_JBG
case CXIMAGE_FORMAT_JBG:
#endif
#if CXIMAGE_SUPPORT_JP2
case CXIMAGE_FORMAT_JP2:
#endif
#if CXIMAGE_SUPPORT_JPC
case CXIMAGE_FORMAT_JPC:
#endif
#if CXIMAGE_SUPPORT_PGX
case CXIMAGE_FORMAT_PGX:
#endif
#if CXIMAGE_SUPPORT_PNM
case CXIMAGE_FORMAT_PNM:
#endif
#if CXIMAGE_SUPPORT_RAS
case CXIMAGE_FORMAT_RAS:
#endif
#if CXIMAGE_SUPPORT_SKA
case CXIMAGE_FORMAT_SKA:
#endif
#if CXIMAGE_SUPPORT_RAW
case CXIMAGE_FORMAT_RAW:
#endif
info.dwType = type;
return true;
}
info.dwType = CXIMAGE_FORMAT_UNKNOWN;
return false;
}
////////////////////////////////////////////////////////////////////////////////
DWORD CxImage::GetNumTypes()
{
return CMAX_IMAGE_FORMATS-1;
}
////////////////////////////////////////////////////////////////////////////////
DWORD CxImage::GetTypeIdFromName(const TCHAR* ext)
{
#if CXIMAGE_SUPPORT_BMP
if (_tcsnicmp(ext,_T("bmp"),3)==0 ) return CXIMAGE_FORMAT_BMP;
#endif
#if CXIMAGE_SUPPORT_JPG
if (_tcsnicmp(ext,_T("jpg"),3)==0 ||
_tcsnicmp(ext,_T("jpe"),3)==0 ||
_tcsnicmp(ext,_T("jfi"),3)==0 ) return CXIMAGE_FORMAT_JPG;
#endif
#if CXIMAGE_SUPPORT_GIF
if (_tcsnicmp(ext,_T("gif"),3)==0 ) return CXIMAGE_FORMAT_GIF;
#endif
#if CXIMAGE_SUPPORT_PNG
if (_tcsnicmp(ext,_T("png"),3)==0 ) return CXIMAGE_FORMAT_PNG;
#endif
#if CXIMAGE_SUPPORT_ICO
if (_tcsnicmp(ext,_T("ico"),3)==0 ||
_tcsnicmp(ext,_T("cur"),3)==0 ) return CXIMAGE_FORMAT_ICO;
#endif
#if CXIMAGE_SUPPORT_TIF
if (_tcsnicmp(ext,_T("tif"),3)==0 ) return CXIMAGE_FORMAT_TIF;
#endif
#if CXIMAGE_SUPPORT_TGA
if (_tcsnicmp(ext,_T("tga"),3)==0 ) return CXIMAGE_FORMAT_TGA;
#endif
#if CXIMAGE_SUPPORT_PCX
if (_tcsnicmp(ext,_T("pcx"),3)==0 ) return CXIMAGE_FORMAT_PCX;
#endif
#if CXIMAGE_SUPPORT_WBMP
if (_tcsnicmp(ext,_T("wbm"),3)==0 ) return CXIMAGE_FORMAT_WBMP;
#endif
#if CXIMAGE_SUPPORT_WMF
if (_tcsnicmp(ext,_T("wmf"),3)==0 ||
_tcsnicmp(ext,_T("emf"),3)==0 ) return CXIMAGE_FORMAT_WMF;
#endif
#if CXIMAGE_SUPPORT_JP2
if (_tcsnicmp(ext,_T("jp2"),3)==0 ||
_tcsnicmp(ext,_T("j2k"),3)==0 ) return CXIMAGE_FORMAT_JP2;
#endif
#if CXIMAGE_SUPPORT_JPC
if (_tcsnicmp(ext,_T("jpc"),3)==0 ||
_tcsnicmp(ext,_T("j2c"),3)==0 ) return CXIMAGE_FORMAT_JPC;
#endif
#if CXIMAGE_SUPPORT_PGX
if (_tcsnicmp(ext,_T("pgx"),3)==0 ) return CXIMAGE_FORMAT_PGX;
#endif
#if CXIMAGE_SUPPORT_RAS
if (_tcsnicmp(ext,_T("ras"),3)==0 ) return CXIMAGE_FORMAT_RAS;
#endif
#if CXIMAGE_SUPPORT_PNM
if (_tcsnicmp(ext,_T("pnm"),3)==0 ||
_tcsnicmp(ext,_T("pgm"),3)==0 ||
_tcsnicmp(ext,_T("ppm"),3)==0 ) return CXIMAGE_FORMAT_PNM;
#endif
#if CXIMAGE_SUPPORT_JBG
if (_tcsnicmp(ext,_T("jbg"),3)==0 ) return CXIMAGE_FORMAT_JBG;
#endif
#if CXIMAGE_SUPPORT_MNG
if (_tcsnicmp(ext,_T("mng"),3)==0 ||
_tcsnicmp(ext,_T("jng"),3)==0 ) return CXIMAGE_FORMAT_MNG;
#endif
#if CXIMAGE_SUPPORT_SKA
if (_tcsnicmp(ext,_T("ska"),3)==0 ) return CXIMAGE_FORMAT_SKA;
#endif
#if CXIMAGE_SUPPORT_RAW
if (_tcsnicmp(ext,_T("nef"),3)==0 ||
_tcsnicmp(ext,_T("crw"),3)==0 ||
_tcsnicmp(ext,_T("cr2"),3)==0 ||
_tcsnicmp(ext,_T("dng"),3)==0 ||
_tcsnicmp(ext,_T("arw"),3)==0 ||
_tcsnicmp(ext,_T("erf"),3)==0 ||
_tcsnicmp(ext,_T("3fr"),3)==0 ||
_tcsnicmp(ext,_T("dcr"),3)==0 ||
_tcsnicmp(ext,_T("raw"),3)==0 ||
_tcsnicmp(ext,_T("x3f"),3)==0 ||
_tcsnicmp(ext,_T("mef"),3)==0 ||
_tcsnicmp(ext,_T("raf"),3)==0 ||
_tcsnicmp(ext,_T("mrw"),3)==0 ||
_tcsnicmp(ext,_T("pef"),3)==0 ||
_tcsnicmp(ext,_T("sr2"),3)==0 ||
_tcsnicmp(ext,_T("orf"),3)==0 ) return CXIMAGE_FORMAT_RAW;
#endif
return CXIMAGE_FORMAT_UNKNOWN;
}
////////////////////////////////////////////////////////////////////////////////
DWORD CxImage::GetTypeIdFromIndex(const DWORD index)
{
DWORD n;
n=0; if (index == n) return CXIMAGE_FORMAT_UNKNOWN;
#if CXIMAGE_SUPPORT_BMP
n++; if (index == n) return CXIMAGE_FORMAT_BMP;
#endif
#if CXIMAGE_SUPPORT_GIF
n++; if (index == n) return CXIMAGE_FORMAT_GIF;
#endif
#if CXIMAGE_SUPPORT_JPG
n++; if (index == n) return CXIMAGE_FORMAT_JPG;
#endif
#if CXIMAGE_SUPPORT_PNG
n++; if (index == n) return CXIMAGE_FORMAT_PNG;
#endif
#if CXIMAGE_SUPPORT_ICO
n++; if (index == n) return CXIMAGE_FORMAT_ICO;
#endif
#if CXIMAGE_SUPPORT_TIF
n++; if (index == n) return CXIMAGE_FORMAT_TIF;
#endif
#if CXIMAGE_SUPPORT_TGA
n++; if (index == n) return CXIMAGE_FORMAT_TGA;
#endif
#if CXIMAGE_SUPPORT_PCX
n++; if (index == n) return CXIMAGE_FORMAT_PCX;
#endif
#if CXIMAGE_SUPPORT_WBMP
n++; if (index == n) return CXIMAGE_FORMAT_WBMP;
#endif
#if CXIMAGE_SUPPORT_WMF
n++; if (index == n) return CXIMAGE_FORMAT_WMF;
#endif
#if CXIMAGE_SUPPORT_JP2
n++; if (index == n) return CXIMAGE_FORMAT_JP2;
#endif
#if CXIMAGE_SUPPORT_JPC
n++; if (index == n) return CXIMAGE_FORMAT_JPC;
#endif
#if CXIMAGE_SUPPORT_PGX
n++; if (index == n) return CXIMAGE_FORMAT_PGX;
#endif
#if CXIMAGE_SUPPORT_PNM
n++; if (index == n) return CXIMAGE_FORMAT_PNM;
#endif
#if CXIMAGE_SUPPORT_RAS
n++; if (index == n) return CXIMAGE_FORMAT_RAS;
#endif
#if CXIMAGE_SUPPORT_JBG
n++; if (index == n) return CXIMAGE_FORMAT_JBG;
#endif
#if CXIMAGE_SUPPORT_MNG
n++; if (index == n) return CXIMAGE_FORMAT_MNG;
#endif
#if CXIMAGE_SUPPORT_SKA
n++; if (index == n) return CXIMAGE_FORMAT_SKA;
#endif
#if CXIMAGE_SUPPORT_RAW
n++; if (index == n) return CXIMAGE_FORMAT_RAW;
#endif
return CXIMAGE_FORMAT_UNKNOWN;
}
////////////////////////////////////////////////////////////////////////////////
DWORD CxImage::GetTypeIndexFromId(const DWORD id)
{
DWORD n;
n=0; if (id == CXIMAGE_FORMAT_UNKNOWN) return n;
#if CXIMAGE_SUPPORT_BMP
n++; if (id == CXIMAGE_FORMAT_BMP) return n;
#endif
#if CXIMAGE_SUPPORT_GIF
n++; if (id == CXIMAGE_FORMAT_GIF) return n;
#endif
#if CXIMAGE_SUPPORT_JPG
n++; if (id == CXIMAGE_FORMAT_JPG) return n;
#endif
#if CXIMAGE_SUPPORT_PNG
n++; if (id == CXIMAGE_FORMAT_PNG) return n;
#endif
#if CXIMAGE_SUPPORT_ICO
n++; if (id == CXIMAGE_FORMAT_ICO) return n;
#endif
#if CXIMAGE_SUPPORT_TIF
n++; if (id == CXIMAGE_FORMAT_TIF) return n;
#endif
#if CXIMAGE_SUPPORT_TGA
n++; if (id == CXIMAGE_FORMAT_TGA) return n;
#endif
#if CXIMAGE_SUPPORT_PCX
n++; if (id == CXIMAGE_FORMAT_PCX) return n;
#endif
#if CXIMAGE_SUPPORT_WBMP
n++; if (id == CXIMAGE_FORMAT_WBMP) return n;
#endif
#if CXIMAGE_SUPPORT_WMF
n++; if (id == CXIMAGE_FORMAT_WMF) return n;
#endif
#if CXIMAGE_SUPPORT_JP2
n++; if (id == CXIMAGE_FORMAT_JP2) return n;
#endif
#if CXIMAGE_SUPPORT_JPC
n++; if (id == CXIMAGE_FORMAT_JPC) return n;
#endif
#if CXIMAGE_SUPPORT_PGX
n++; if (id == CXIMAGE_FORMAT_PGX) return n;
#endif
#if CXIMAGE_SUPPORT_PNM
n++; if (id == CXIMAGE_FORMAT_PNM) return n;
#endif
#if CXIMAGE_SUPPORT_RAS
n++; if (id == CXIMAGE_FORMAT_RAS) return n;
#endif
#if CXIMAGE_SUPPORT_JBG
n++; if (id == CXIMAGE_FORMAT_JBG) return n;
#endif
#if CXIMAGE_SUPPORT_MNG
n++; if (id == CXIMAGE_FORMAT_MNG) return n;
#endif
#if CXIMAGE_SUPPORT_SKA
n++; if (id == CXIMAGE_FORMAT_SKA) return n;
#endif
#if CXIMAGE_SUPPORT_RAW
n++; if (id == CXIMAGE_FORMAT_RAW) return n;
#endif
return 0;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return current frame delay in milliseconds. Only for GIF and MNG formats.
*/
DWORD CxImage::GetFrameDelay() const
{
return info.dwFrameDelay;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets current frame delay. Only for GIF format.
* \param d = delay in milliseconds
*/
void CxImage::SetFrameDelay(DWORD d)
{
info.dwFrameDelay=d;
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::GetOffset(long *x,long *y)
{
*x=info.xOffset;
*y=info.yOffset;
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetOffset(long x,long y)
{
info.xOffset=x;
info.yOffset=y;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \sa SetJpegQuality, GetJpegQualityF
* \author [DP]; changes [Stefan Schürmans]
*/
BYTE CxImage::GetJpegQuality() const
{
return (BYTE)(info.fQuality + 0.5f);
}
////////////////////////////////////////////////////////////////////////////////
/**
* \sa SetJpegQuality, GetJpegQuality
* \author [Stefan Schürmans]
*/
float CxImage::GetJpegQualityF() const
{
return info.fQuality;
}
////////////////////////////////////////////////////////////////////////////////
/**
* quality level for JPEG and JPEG2000
* \param q: can be from 0 to 100
* \author [DP]; changes [Stefan Schürmans]
*/
void CxImage::SetJpegQuality(BYTE q){
info.fQuality = (float)q;
}
////////////////////////////////////////////////////////////////////////////////
/**
* quality level for JPEG and JPEG2000
* necessary for JPEG2000 when quality is between 0.0 and 1.0
* \param q: can be from 0.0 to 100.0
* \author [Stefan Schürmans]
*/
void CxImage::SetJpegQualityF(float q){
if (q>0) info.fQuality = q;
else info.fQuality = 0.0f;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \sa SetJpegScale
*/
BYTE CxImage::GetJpegScale() const
{
return info.nJpegScale;
}
////////////////////////////////////////////////////////////////////////////////
/**
* scaling down during JPEG decoding valid numbers are 1, 2, 4, 8
* \author [ignacio]
*/
void CxImage::SetJpegScale(BYTE q){
info.nJpegScale = q;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Used to monitor the slow loops.
* \return value is from 0 to 100.
* \sa SetProgress
*/
long CxImage::GetProgress() const
{
return info.nProgress;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return the escape code.
* \sa SetEscape
*/
long CxImage::GetEscape() const
{
return info.nEscape;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Forces the value of the internal progress variable.
* \param p should be from 0 to 100.
* \sa GetProgress
*/
void CxImage::SetProgress(long p)
{
info.nProgress = p;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Used to quit the slow loops or the codecs.
* - SetEscape(-1) before Decode forces the function to exit, right after
* the image width and height are available ( for bmp, jpg, gif, tif )
*/
void CxImage::SetEscape(long i)
{
info.nEscape = i;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Checks if the image is correctly initializated.
*/
bool CxImage::IsValid() const
{
return pDib!=0;
}
////////////////////////////////////////////////////////////////////////////////
/**
* True if the image is enabled for painting.
*/
bool CxImage::IsEnabled() const
{
return info.bEnabled;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Enables/disables the image.
*/
void CxImage::Enable(bool enable)
{
info.bEnabled=enable;
}
////////////////////////////////////////////////////////////////////////////////
/**
* This function must be used after a Decode() / Load() call.
* Use the sequence SetFrame(-1); Load(...); GetNumFrames();
* to get the number of images without loading the first image.
* \return the number of images in the file.
*/
long CxImage::GetNumFrames() const
{
return info.nNumFrames;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return the current selected image (zero-based index).
*/
long CxImage::GetFrame() const
{
return info.nFrame;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the image number that the next Decode() / Load() call will load
*/
void CxImage::SetFrame(long nFrame){
info.nFrame=nFrame;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the method for drawing the frame related to others
* \sa GetDisposalMethod
*/
void CxImage::SetDisposalMethod(BYTE dm)
{ info.dispmeth=dm; }
////////////////////////////////////////////////////////////////////////////////
/**
* Gets the method for drawing the frame related to others
* Values : 0 - No disposal specified. The decoder is
* not required to take any action.
* 1 - Do not dispose. The graphic is to be left
* in place.
* 2 - Restore to background color. The area used by the
* graphic must be restored to the background color.
* 3 - Restore to previous. The decoder is required to
* restore the area overwritten by the graphic with
* what was there prior to rendering the graphic.
* 4-7 - To be defined.
*/
BYTE CxImage::GetDisposalMethod() const
{ return info.dispmeth; }
////////////////////////////////////////////////////////////////////////////////
bool CxImage::GetRetreiveAllFrames() const
{ return info.bGetAllFrames; }
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetRetreiveAllFrames(bool flag)
{ info.bGetAllFrames = flag; }
////////////////////////////////////////////////////////////////////////////////
CxImage * CxImage::GetFrame(long nFrame) const
{
if ( ppFrames == NULL) return NULL;
if ( info.nNumFrames == 0) return NULL;
if ( nFrame >= info.nNumFrames ) return NULL;
if ( nFrame < 0) nFrame = info.nNumFrames - 1;
return ppFrames[nFrame];
}
////////////////////////////////////////////////////////////////////////////////
short CxImage::ntohs(const short word)
{
if (info.bLittleEndianHost) return word;
return ( (word & 0xff) << 8 ) | ( (word >> 8) & 0xff );
}
////////////////////////////////////////////////////////////////////////////////
long CxImage::ntohl(const long dword)
{
if (info.bLittleEndianHost) return dword;
return ((dword & 0xff) << 24 ) | ((dword & 0xff00) << 8 ) |
((dword >> 8) & 0xff00) | ((dword >> 24) & 0xff);
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::bihtoh(BITMAPINFOHEADER* bih)
{
bih->biSize = ntohl(bih->biSize);
bih->biWidth = ntohl(bih->biWidth);
bih->biHeight = ntohl(bih->biHeight);
bih->biPlanes = ntohs(bih->biPlanes);
bih->biBitCount = ntohs(bih->biBitCount);
bih->biCompression = ntohl(bih->biCompression);
bih->biSizeImage = ntohl(bih->biSizeImage);
bih->biXPelsPerMeter = ntohl(bih->biXPelsPerMeter);
bih->biYPelsPerMeter = ntohl(bih->biYPelsPerMeter);
bih->biClrUsed = ntohl(bih->biClrUsed);
bih->biClrImportant = ntohl(bih->biClrImportant);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns the last reported error.
*/
const char* CxImage::GetLastError()
{
return info.szLastError;
}
////////////////////////////////////////////////////////////////////////////////
DWORD CxImage::DumpSize()
{
DWORD n;
n = sizeof(BITMAPINFOHEADER) + sizeof(CXIMAGEINFO) + GetSize();
if (pAlpha){
n += 1 + head.biWidth * head.biHeight;
} else n++;
if (pSelection){
n += 1 + head.biWidth * head.biHeight;
} else n++;
if (ppLayers){
for (long m=0; m<GetNumLayers(); m++){
if (GetLayer(m)){
n += 1 + GetLayer(m)->DumpSize();
}
}
} else n++;
if (ppFrames){
for (long m=0; m<GetNumFrames(); m++){
if (GetFrame(m)){
n += 1 + GetFrame(m)->DumpSize();
}
}
} else n++;
return n;
}
////////////////////////////////////////////////////////////////////////////////
DWORD CxImage::Dump(BYTE * dst)
{
if (!dst) return 0;
memcpy(dst,&head,sizeof(BITMAPINFOHEADER));
dst += sizeof(BITMAPINFOHEADER);
memcpy(dst,&info,sizeof(CXIMAGEINFO));
dst += sizeof(CXIMAGEINFO);
memcpy(dst,pDib,GetSize());
dst += GetSize();
if (pAlpha){
memset(dst++, 1, 1);
memcpy(dst,pAlpha,head.biWidth * head.biHeight);
dst += head.biWidth * head.biHeight;
} else {
memset(dst++, 0, 1);
}
if (pSelection){
memset(dst++, 1, 1);
memcpy(dst,pSelection,head.biWidth * head.biHeight);
dst += head.biWidth * head.biHeight;
} else {
memset(dst++, 0, 1);
}
if (ppLayers){
memset(dst++, 1, 1);
for (long m=0; m<GetNumLayers(); m++){
if (GetLayer(m)){
dst += GetLayer(m)->Dump(dst);
}
}
} else {
memset(dst++, 0, 1);
}
if (ppFrames){
memset(dst++, 1, 1);
for (long m=0; m<GetNumFrames(); m++){
if (GetFrame(m)){
dst += GetFrame(m)->Dump(dst);
}
}
} else {
memset(dst++, 0, 1);
}
return DumpSize();
}
////////////////////////////////////////////////////////////////////////////////
DWORD CxImage::UnDump(const BYTE * src)
{
if (!src)
return 0;
if (!Destroy())
return 0;
if (!DestroyFrames())
return 0;
DWORD n = 0;
memcpy(&head,src,sizeof(BITMAPINFOHEADER));
n += sizeof(BITMAPINFOHEADER);
memcpy(&info,&src[n],sizeof(CXIMAGEINFO));
n += sizeof(CXIMAGEINFO);
if (!Create(head.biWidth, head.biHeight, head.biBitCount, info.dwType))
return 0;
memcpy(pDib,&src[n],GetSize());
n += GetSize();
if (src[n++]){
if (AlphaCreate()){
memcpy(pAlpha, &src[n], head.biWidth * head.biHeight);
}
n += head.biWidth * head.biHeight;
}
if (src[n++]){
RECT box = info.rSelectionBox;
if (SelectionCreate()){
info.rSelectionBox = box;
memcpy(pSelection, &src[n], head.biWidth * head.biHeight);
}
n += head.biWidth * head.biHeight;
}
if (src[n++]){
ppLayers = new CxImage*[info.nNumLayers];
for (long m=0; m<GetNumLayers(); m++){
ppLayers[m] = new CxImage();
n += ppLayers[m]->UnDump(&src[n]);
}
}
if (src[n++]){
ppFrames = new CxImage*[info.nNumFrames];
for (long m=0; m<GetNumFrames(); m++){
ppFrames[m] = new CxImage();
n += ppFrames[m]->UnDump(&src[n]);
}
}
return n;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return A.BBCCCDDDD
* - A = main version
* - BB = main revision
* - CCC = minor revision (letter)
* - DDDD = experimental revision
*/
const float CxImage::GetVersionNumber()
{
return 6.000000015f;
}
////////////////////////////////////////////////////////////////////////////////
const TCHAR* CxImage::GetVersion()
{
static const TCHAR CxImageVersion[] = _T("CxImage 6.0.0");
return (CxImageVersion);
}
////////////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@@ -1,253 +0,0 @@
/*
* File: ImaIter.h
* Purpose: Declaration of the Platform Independent Image Base Class
* Author: Alejandro Aguilar Sierra
* Created: 1995
* Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
*
* 07/08/2001 Davide Pizzolato - www.xdp.it
* - removed slow loops
* - added safe checks
*
* Permission is given by the author to freely redistribute and include
* this code in any program as long as this credit is given where due.
*
* COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
* OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
* THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
* OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
* CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
* THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
* SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
* PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
* THIS DISCLAIMER.
*
* Use at your own risk!
* ==========================================================
*/
#if !defined(__ImaIter_h)
#define __ImaIter_h
#include "ximage.h"
#include "ximadef.h"
class CImageIterator
{
friend class CxImage;
protected:
int Itx, Ity; // Counters
int Stepx, Stepy;
BYTE* IterImage; // Image pointer
CxImage *ima;
public:
// Constructors
CImageIterator ( void );
CImageIterator ( CxImage *image );
operator CxImage* ();
// Iterators
BOOL ItOK ();
void Reset ();
void Upset ();
void SetRow(BYTE *buf, int n);
void GetRow(BYTE *buf, int n);
BYTE GetByte( ) { return IterImage[Itx]; }
void SetByte(BYTE b) { IterImage[Itx] = b; }
BYTE* GetRow(void);
BYTE* GetRow(int n);
BOOL NextRow();
BOOL PrevRow();
BOOL NextByte();
BOOL PrevByte();
void SetSteps(int x, int y=0) { Stepx = x; Stepy = y; }
void GetSteps(int *x, int *y) { *x = Stepx; *y = Stepy; }
BOOL NextStep();
BOOL PrevStep();
void SetY(int y); /* AD - for interlace */
int GetY() {return Ity;}
BOOL GetCol(BYTE* pCol, DWORD x);
BOOL SetCol(BYTE* pCol, DWORD x);
};
/////////////////////////////////////////////////////////////////////
inline
CImageIterator::CImageIterator(void)
{
ima = 0;
IterImage = 0;
Itx = Ity = 0;
Stepx = Stepy = 0;
}
/////////////////////////////////////////////////////////////////////
inline
CImageIterator::CImageIterator(CxImage *imageImpl): ima(imageImpl)
{
if (ima) IterImage = ima->GetBits();
Itx = Ity = 0;
Stepx = Stepy = 0;
}
/////////////////////////////////////////////////////////////////////
inline
CImageIterator::operator CxImage* ()
{
return ima;
}
/////////////////////////////////////////////////////////////////////
inline BOOL CImageIterator::ItOK ()
{
if (ima) return ima->IsInside(Itx, Ity);
else return FALSE;
}
/////////////////////////////////////////////////////////////////////
inline void CImageIterator::Reset()
{
if (ima) IterImage = ima->GetBits();
else IterImage=0;
Itx = Ity = 0;
}
/////////////////////////////////////////////////////////////////////
inline void CImageIterator::Upset()
{
Itx = 0;
Ity = ima->GetHeight()-1;
IterImage = ima->GetBits() + ima->GetEffWidth()*(ima->GetHeight()-1);
}
/////////////////////////////////////////////////////////////////////
inline BOOL CImageIterator::NextRow()
{
if (++Ity >= (int)ima->GetHeight()) return 0;
IterImage += ima->GetEffWidth();
return 1;
}
/////////////////////////////////////////////////////////////////////
inline BOOL CImageIterator::PrevRow()
{
if (--Ity < 0) return 0;
IterImage -= ima->GetEffWidth();
return 1;
}
/* AD - for interlace */
inline void CImageIterator::SetY(int y)
{
if ((y < 0) || (y > (int)ima->GetHeight())) return;
Ity = y;
IterImage = ima->GetBits() + ima->GetEffWidth()*y;
}
/////////////////////////////////////////////////////////////////////
inline void CImageIterator::SetRow(BYTE *buf, int n)
{
if (n<0) n = (int)ima->GetEffWidth();
else n = min(n,(int)ima->GetEffWidth());
if ((IterImage!=NULL)&&(buf!=NULL)&&(n>0)) memcpy(IterImage,buf,n);
}
/////////////////////////////////////////////////////////////////////
inline void CImageIterator::GetRow(BYTE *buf, int n)
{
if ((IterImage!=NULL)&&(buf!=NULL)&&(n>0))
memcpy(buf,IterImage,min(n,(int)ima->GetEffWidth()));
}
/////////////////////////////////////////////////////////////////////
inline BYTE* CImageIterator::GetRow()
{
return IterImage;
}
/////////////////////////////////////////////////////////////////////
inline BYTE* CImageIterator::GetRow(int n)
{
SetY(n);
return IterImage;
}
/////////////////////////////////////////////////////////////////////
inline BOOL CImageIterator::NextByte()
{
if (++Itx < (int)ima->GetEffWidth()) return 1;
else
if (++Ity < (int)ima->GetHeight()){
IterImage += ima->GetEffWidth();
Itx = 0;
return 1;
} else
return 0;
}
/////////////////////////////////////////////////////////////////////
inline BOOL CImageIterator::PrevByte()
{
if (--Itx >= 0) return 1;
else
if (--Ity >= 0){
IterImage -= ima->GetEffWidth();
Itx = 0;
return 1;
} else
return 0;
}
/////////////////////////////////////////////////////////////////////
inline BOOL CImageIterator::NextStep()
{
Itx += Stepx;
if (Itx < (int)ima->GetEffWidth()) return 1;
else {
Ity += Stepy;
if (Ity < (int)ima->GetHeight()){
IterImage += ima->GetEffWidth();
Itx = 0;
return 1;
} else
return 0;
}
}
/////////////////////////////////////////////////////////////////////
inline BOOL CImageIterator::PrevStep()
{
Itx -= Stepx;
if (Itx >= 0) return 1;
else {
Ity -= Stepy;
if (Ity >= 0 && Ity < (int)ima->GetHeight()) {
IterImage -= ima->GetEffWidth();
Itx = 0;
return 1;
} else
return 0;
}
}
/////////////////////////////////////////////////////////////////////
inline BOOL CImageIterator::GetCol(BYTE* pCol, DWORD x)
{
if ((pCol==0)||(ima->GetBpp()<8)||(x>=ima->GetWidth()))
return 0;
DWORD h = ima->GetHeight();
//DWORD line = ima->GetEffWidth();
BYTE bytes = (BYTE)(ima->GetBpp()>>3);
BYTE* pSrc;
for (DWORD y=0;y<h;y++){
pSrc = ima->GetBits(y) + x*bytes;
for (BYTE w=0;w<bytes;w++){
*pCol++=*pSrc++;
}
}
return 1;
}
/////////////////////////////////////////////////////////////////////
inline BOOL CImageIterator::SetCol(BYTE* pCol, DWORD x)
{
if ((pCol==0)||(ima->GetBpp()<8)||(x>=ima->GetWidth()))
return 0;
DWORD h = ima->GetHeight();
//DWORD line = ima->GetEffWidth();
BYTE bytes = (BYTE)(ima->GetBpp()>>3);
BYTE* pSrc;
for (DWORD y=0;y<h;y++){
pSrc = ima->GetBits(y) + x*bytes;
for (BYTE w=0;w<bytes;w++){
*pSrc++=*pCol++;
}
}
return 1;
}
/////////////////////////////////////////////////////////////////////
#endif

View File

@@ -1,325 +0,0 @@
/*
* File: ximajas.cpp
* Purpose: Platform Independent JasPer Image Class Loader and Writer
* 12/Apr/2003 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximajas.h"
#if CXIMAGE_SUPPORT_JASPER
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageJAS::Decode(CxFile *hFile, DWORD imagetype)
{
if (hFile == NULL) return false;
jas_image_t *image=0;
jas_stream_t *in=0;
jas_matrix_t **bufs=0;
long i,error=0;
int fmt;
//jas_setdbglevel(0);
cx_try
{
if (jas_init())
cx_throw("cannot initialize jasper");
in = jas_stream_fdopen(0, "rb");
if (!in)
cx_throw("error: cannot open standard input");
CxFileJas src(hFile,in);
fmt = jas_image_getfmt(in);
if (fmt<0)
cx_throw("error: unknowm format");
image = jas_image_decode(in, fmt, 0);
if (!image){
fmt = -1;
cx_throw("error: cannot load image data");
}
char szfmt[4];
*szfmt = '\0';
strncpy(szfmt,jas_image_fmttostr(fmt),3);
szfmt[3] = '\0';
fmt = -1;
#if CXIMAGE_SUPPORT_JP2
if (strcmp(szfmt,"jp2")==0) fmt = CXIMAGE_FORMAT_JP2;
#endif
#if CXIMAGE_SUPPORT_JPC
if (strcmp(szfmt,"jpc")==0) fmt = CXIMAGE_FORMAT_JPC;
#endif
#if CXIMAGE_SUPPORT_RAS
if (strcmp(szfmt,"ras")==0) fmt = CXIMAGE_FORMAT_RAS;
#endif
#if CXIMAGE_SUPPORT_PNM
if (strcmp(szfmt,"pnm")==0) fmt = CXIMAGE_FORMAT_PNM;
#endif
#if CXIMAGE_SUPPORT_PGX
if (strcmp(szfmt,"pgx")==0) fmt = CXIMAGE_FORMAT_PGX;
#endif
//if (fmt<0)
// cx_throw("error: unknowm format");
long x,y,w,h,depth,cmptno;
w = jas_image_cmptwidth(image,0);
h = jas_image_cmptheight(image,0);
depth = jas_image_cmptprec(image,0);
if (info.nEscape == -1){
head.biWidth = w;
head.biHeight= h;
info.dwType = fmt<0 ? 0 : fmt;
cx_throw("output dimensions returned");
}
if (image->numcmpts_ > 64 || image->numcmpts_ < 0)
cx_throw("error: too many components");
// <LD> 01/Jan/2005: Always force conversion to sRGB. Seems to be required for many types of JPEG2000 file.
// if (depth!=1 && depth!=4 && depth!=8)
if (image->numcmpts_>=3 && depth <=8)
{
jas_image_t *newimage;
jas_cmprof_t *outprof;
//jas_eprintf("forcing conversion to sRGB\n");
outprof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB);
if (!outprof) {
cx_throw("cannot create sRGB profile");
}
newimage = jas_image_chclrspc(image, outprof, JAS_CMXFORM_INTENT_PER);
if (!newimage) {
jas_cmprof_destroy(outprof); // <LD> 01/Jan/2005: Destroy color profile on error.
cx_throw("cannot convert to sRGB");
}
jas_image_destroy(image);
jas_cmprof_destroy(outprof);
image = newimage;
}
bufs = (jas_matrix_t **)calloc(image->numcmpts_, sizeof(jas_matrix_t**));
for (i = 0; i < image->numcmpts_; ++i) {
bufs[i] = jas_matrix_create(1, w);
if (!bufs[i]) {
cx_throw("error: cannot allocate memory");
}
}
int nshift = (depth>8) ? (depth-8) : 0;
if (image->numcmpts_==3 &&
image->cmpts_[0]->width_ == image->cmpts_[1]->width_ &&
image->cmpts_[1]->width_ == image->cmpts_[2]->width_ &&
image->cmpts_[0]->height_ == image->cmpts_[1]->height_ &&
image->cmpts_[1]->height_ == image->cmpts_[2]->height_ &&
image->cmpts_[0]->prec_ == image->cmpts_[1]->prec_ &&
image->cmpts_[1]->prec_ == image->cmpts_[2]->prec_ )
{
if(!Create(w,h,24,fmt))
cx_throw("");
RGBQUAD c;
for (y=0; y<h; y++) {
for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {
jas_image_readcmpt(image, cmptno, 0, y, w, 1, bufs[cmptno]);
}
for (x=0; x<w; x++){
c.rgbRed = (BYTE)((jas_matrix_getv(bufs[0], x)>>nshift));
c.rgbGreen = (BYTE)((jas_matrix_getv(bufs[1], x)>>nshift));
c.rgbBlue = (BYTE)((jas_matrix_getv(bufs[2], x)>>nshift));
SetPixelColor(x,h-1-y,c);
}
}
} else {
info.nNumFrames = image->numcmpts_;
if ((info.nFrame<0)||(info.nFrame>=info.nNumFrames)){
cx_throw("wrong frame!");
}
for (cmptno=0; cmptno<=info.nFrame; cmptno++) {
w = jas_image_cmptwidth(image,cmptno);
h = jas_image_cmptheight(image,cmptno);
depth = jas_image_cmptprec(image,cmptno);
if (depth>8) depth=8;
if(!Create(w,h,depth,imagetype))
cx_throw("");
SetGrayPalette();
for (y=0; y<h; y++) {
jas_image_readcmpt(image, cmptno, 0, y, w, 1, bufs[0]);
for (x=0; x<w; x++){
SetPixelIndex(x,h-1-y,(BYTE)((jas_matrix_getv(bufs[0], x)>>nshift)));
}
}
}
}
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
if (info.nEscape == -1 && fmt>0){
error = 0;
} else {
error = 1;
}
}
if (bufs) {
for (i = 0; i < image->numcmpts_; ++i){ if (bufs[i]) jas_matrix_destroy(bufs[i]);}
free(bufs);
}
jas_cleanup();
if (image) jas_image_destroy(image);
if (in) jas_stream_close(in);
return (error==0);
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageJAS::Encode(CxFile * hFile, DWORD imagetype)
{
if (EncodeSafeCheck(hFile)) return false;
if (head.biClrUsed!=0 && !IsGrayScale()){
strcpy(info.szLastError,"JasPer can save only RGB or GrayScale images");
return false;
}
jas_image_t *image=0;
jas_stream_t *out=0;
jas_matrix_t *cmpts[3];
long x,y,yflip,error=0;
uint_fast16_t cmptno, numcmpts=0;
jas_image_cmptparm_t cmptparms[3], *cmptparm;
cx_try {
if (jas_init())
cx_throw("cannot initialize jasper");
out = jas_stream_fdopen(0, "wb");
if (!out)
cx_throw("error: cannot open standard output");
CxFileJas src(hFile,out);
numcmpts = head.biClrUsed==0 ? 3 : 1;
for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno, ++cmptparm) {
cmptparm->tlx = 0;
cmptparm->tly = 0;
cmptparm->hstep = 1;
cmptparm->vstep = 1;
cmptparm->width = head.biWidth;
cmptparm->height = head.biHeight;
cmptparm->prec = 8;
cmptparm->sgnd = false;
}
/* Create image object. */
image = jas_image_create(numcmpts, cmptparms, JAS_CLRSPC_UNKNOWN);
if (!image)
cx_throw("error : jas_image_create");
if (numcmpts == 3) {
jas_image_setclrspc(image, JAS_CLRSPC_SRGB);
jas_image_setcmpttype(image, 0,
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
jas_image_setcmpttype(image, 1,
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
jas_image_setcmpttype(image, 2,
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
} else {
jas_image_setclrspc(image, JAS_CLRSPC_SGRAY);
jas_image_setcmpttype(image, 0,
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
}
for (x = 0; x < numcmpts; ++x) { cmpts[x] = 0; }
/* Create temporary matrices to hold component data. */
for (x = 0; x < numcmpts; ++x) {
cmpts[x] = jas_matrix_create(1, head.biWidth);
if (!cmpts[x]) {
cx_throw("error : can't allocate memory");
}
}
RGBQUAD c;
for (y = 0; y < head.biHeight; ++y) {
for (x = 0; x < head.biWidth; ++x) {
if (head.biClrUsed==0){
c = GetPixelColor(x,y);
jas_matrix_setv(cmpts[0], x, c.rgbRed);
jas_matrix_setv(cmpts[1], x, c.rgbGreen);
jas_matrix_setv(cmpts[2], x, c.rgbBlue);
} else {
jas_matrix_setv(cmpts[0], x, GetPixelIndex(x,y));
}
}
yflip = head.biHeight - 1 - y;
for (cmptno = 0; cmptno < numcmpts; ++cmptno) {
if (jas_image_writecmpt(image, cmptno, 0, yflip, head.biWidth, 1, cmpts[cmptno])) {
cx_throw("error : jas_image_writecmpt");
}
}
}
char szfmt[4];
*szfmt = '\0';
#if CXIMAGE_SUPPORT_JP2
if (imagetype == CXIMAGE_FORMAT_JP2) strcpy(szfmt,"jp2");
#endif
#if CXIMAGE_SUPPORT_JPC
if (imagetype == CXIMAGE_FORMAT_JPC) strcpy(szfmt,"jpc");
#endif
#if CXIMAGE_SUPPORT_RAS
if (imagetype == CXIMAGE_FORMAT_RAS) strcpy(szfmt,"ras");
#endif
#if CXIMAGE_SUPPORT_PNM
if (imagetype == CXIMAGE_FORMAT_PNM) strcpy(szfmt,"pnm");
#endif
#if CXIMAGE_SUPPORT_PGX
if (imagetype == CXIMAGE_FORMAT_PGX){
strcpy(szfmt,"pgx");
if (head.biClrUsed==0) cx_throw("PGX can save only GrayScale images");
}
#endif
int outfmt = jas_image_strtofmt(szfmt);
char szoutopts[32];
sprintf(szoutopts,"rate=%.3f", info.fQuality/100.0f);
if (jas_image_encode(image, out, outfmt, szoutopts)) {
cx_throw("error: cannot encode image");
}
jas_stream_flush(out);
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
error = 1;
}
for (x = 0; x < numcmpts; ++x) { if (cmpts[x]) { jas_matrix_destroy(cmpts[x]); } }
jas_cleanup();
if (image) jas_image_destroy(image);
if (out) jas_stream_close(out);
return (error==0);
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_JASPER

View File

@@ -1,84 +0,0 @@
/*
* File: ximajas.h
* Purpose: Jasper Image Class Loader and Writer
*/
/* ==========================================================
* CxImageJAS (c) 12/Apr/2003 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
*
* based on JasPer Copyright (c) 2001-2003 Michael David Adams - All rights reserved.
* ==========================================================
*/
#if !defined(__ximaJAS_h)
#define __ximaJAS_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_JASPER
#include "../jasper/include/jasper/jasper.h"
class CxImageJAS: public CxImage
{
public:
CxImageJAS(): CxImage((DWORD)0) {} // <vho> cast to DWORD
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,0);}
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,0);}
bool Decode(CxFile * hFile, DWORD imagetype = 0);
bool Decode(FILE *hFile, DWORD imagetype = 0) { CxIOFile file(hFile); return Decode(&file,imagetype); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile, DWORD imagetype = 0);
bool Encode(FILE *hFile, DWORD imagetype = 0) { CxIOFile file(hFile); return Encode(&file,imagetype); }
#endif // CXIMAGE_SUPPORT_ENCODE
protected:
class CxFileJas
{
public:
CxFileJas(CxFile* pFile,jas_stream_t *stream)
{
if (stream->obj_) jas_free(stream->obj_);
stream->obj_ = pFile;
// <vho> - cannot set the stream->ops_->functions here,
// because this overwrites a static structure in the Jasper library.
// This structure is used by Jasper for internal operations too, e.g. tempfile.
// However the ops_ pointer in the stream can be overwritten.
//stream->ops_->close_ = JasClose;
//stream->ops_->read_ = JasRead;
//stream->ops_->seek_ = JasSeek;
//stream->ops_->write_ = JasWrite;
jas_stream_CxFile.close_ = JasClose;
jas_stream_CxFile.read_ = JasRead;
jas_stream_CxFile.seek_ = JasSeek;
jas_stream_CxFile.write_ = JasWrite;
stream->ops_ = &jas_stream_CxFile;
// <vho> - end
}
static int JasRead(jas_stream_obj_t *obj, char *buf, int cnt)
{ return ((CxFile*)obj)->Read(buf,1,cnt); }
static int JasWrite(jas_stream_obj_t *obj, char *buf, int cnt)
{ return ((CxFile*)obj)->Write(buf,1,cnt); }
static long JasSeek(jas_stream_obj_t *obj, long offset, int origin)
{ return ((CxFile*)obj)->Seek(offset,origin); }
static int JasClose(jas_stream_obj_t * /*obj*/)
{ return 1; }
// <vho>
private:
jas_stream_ops_t jas_stream_CxFile;
// <vho> - end
};
};
#endif
#endif

View File

@@ -1,174 +0,0 @@
/*
* File: ximajbg.cpp
* Purpose: Platform Independent JBG Image Class Loader and Writer
* 18/Aug/2002 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximajbg.h"
#if CXIMAGE_SUPPORT_JBG
#include "ximaiter.h"
#define JBIG_BUFSIZE 8192
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageJBG::Decode(CxFile *hFile)
{
if (hFile == NULL) return false;
struct jbg_dec_state jbig_state;
unsigned long xmax = 4294967295UL, ymax = 4294967295UL;
unsigned int len, cnt;
BYTE *buffer,*p;
int result;
cx_try
{
jbg_dec_init(&jbig_state);
jbg_dec_maxsize(&jbig_state, xmax, ymax);
buffer = (BYTE*)malloc(JBIG_BUFSIZE);
if (!buffer) cx_throw("Sorry, not enough memory available!");
result = JBG_EAGAIN;
do {
len = hFile->Read(buffer, 1, JBIG_BUFSIZE);
if (!len) break;
cnt = 0;
p = buffer;
while (len > 0 && (result == JBG_EAGAIN || result == JBG_EOK)) {
result = jbg_dec_in(&jbig_state, p, len, &cnt);
p += cnt;
len -= cnt;
}
} while (result == JBG_EAGAIN || result == JBG_EOK);
if (hFile->Error())
cx_throw("Problem while reading input file");
if (result != JBG_EOK && result != JBG_EOK_INTR)
cx_throw("Problem with input file");
int w, h, bpp, planes, ew;
w = jbg_dec_getwidth(&jbig_state);
h = jbg_dec_getheight(&jbig_state);
planes = jbg_dec_getplanes(&jbig_state);
bpp = (planes+7)>>3;
ew = (w + 7)>>3;
if (info.nEscape == -1){
head.biWidth = w;
head.biHeight= h;
info.dwType = CXIMAGE_FORMAT_JBG;
cx_throw("output dimensions returned");
}
switch (planes){
case 1:
{
BYTE* binary_image = jbg_dec_getimage(&jbig_state, 0);
if (!Create(w,h,1,CXIMAGE_FORMAT_JBG))
cx_throw("");
SetPaletteColor(0,255,255,255);
SetPaletteColor(1,0,0,0);
CImageIterator iter(this);
iter.Upset();
for (int i=0;i<h;i++){
iter.SetRow(binary_image+i*ew,ew);
iter.PrevRow();
}
break;
}
default:
cx_throw("cannot decode images with more than 1 plane");
}
jbg_dec_free(&jbig_state);
free(buffer);
} cx_catch {
jbg_dec_free(&jbig_state);
if (buffer) free(buffer);
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_JBG) return true;
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageJBG::Encode(CxFile * hFile)
{
if (EncodeSafeCheck(hFile)) return false;
if (head.biBitCount != 1){
strcpy(info.szLastError,"JBG can save only 1-bpp images");
return false;
}
int w, h, bpp, planes, ew, i, j, x, y;
w = head.biWidth;
h = head.biHeight;
planes = 1;
bpp = (planes+7)>>3;
ew = (w + 7)>>3;
BYTE mask;
RGBQUAD *rgb = GetPalette();
if (CompareColors(&rgb[0],&rgb[1])<0) mask=255; else mask=0;
BYTE *buffer = (BYTE*)malloc(ew*h*2);
if (!buffer) {
strcpy(info.szLastError,"Sorry, not enough memory available!");
return false;
}
for (y=0; y<h; y++){
i= y*ew;
j= (h-y-1)*info.dwEffWidth;
for (x=0; x<ew; x++){
buffer[i + x]=info.pImage[j + x]^mask;
}
}
struct jbg_enc_state jbig_state;
jbg_enc_init(&jbig_state, w, h, planes, &buffer, jbig_data_out, hFile);
//jbg_enc_layers(&jbig_state, 2);
//jbg_enc_lrlmax(&jbig_state, 800, 600);
// Specify a few other options (each is ignored if negative)
int dl = -1, dh = -1, d = -1, l0 = -1, mx = -1;
int options = JBG_TPDON | JBG_TPBON | JBG_DPON;
int order = JBG_ILEAVE | JBG_SMID;
jbg_enc_lrange(&jbig_state, dl, dh);
jbg_enc_options(&jbig_state, order, options, l0, mx, -1);
// now encode everything and send it to data_out()
jbg_enc_out(&jbig_state);
// give encoder a chance to free its temporary data structures
jbg_enc_free(&jbig_state);
free(buffer);
if (hFile->Error()){
strcpy(info.szLastError,"Problem while writing JBG file");
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_JBG

View File

@@ -1,44 +0,0 @@
/*
* File: ximajbg.h
* Purpose: JBG Image Class Loader and Writer
*/
/* ==========================================================
* CxImageJBG (c) 18/Aug/2002 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
*
* based on LIBJBG Copyright (c) 2002, Markus Kuhn - All rights reserved.
* ==========================================================
*/
#if !defined(__ximaJBG_h)
#define __ximaJBG_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_JBG
extern "C" {
#include "../jbig/jbig.h"
};
class CxImageJBG: public CxImage
{
public:
CxImageJBG(): CxImage(CXIMAGE_FORMAT_JBG) {}
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JBG);}
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_JBG);}
bool Decode(CxFile * hFile);
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile);
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
#endif // CXIMAGE_SUPPORT_ENCODE
protected:
static void jbig_data_out(BYTE *buffer, unsigned int len, void *file)
{((CxFile*)file)->Write(buffer,len,1);}
};
#endif
#endif

View File

@@ -1,496 +0,0 @@
/*
* File: ximajpg.cpp
* Purpose: Platform Independent JPEG Image Class Loader and Writer
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximajpg.h"
#if CXIMAGE_SUPPORT_JPG
#include "../jpeg/jmorecfg.h"
#include "ximaiter.h"
#include <setjmp.h>
struct jpg_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
char* buffer; /* error message <CSC>*/
};
typedef jpg_error_mgr *jpg_error_ptr;
////////////////////////////////////////////////////////////////////////////////
// Here's the routine that will replace the standard error_exit method:
////////////////////////////////////////////////////////////////////////////////
static void
ima_jpeg_error_exit (j_common_ptr cinfo)
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
jpg_error_ptr myerr = (jpg_error_ptr) cinfo->err;
/* Create the message */
myerr->pub.format_message (cinfo, myerr->buffer);
/* Send it to stderr, adding a newline */
/* Return control to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}
////////////////////////////////////////////////////////////////////////////////
CxImageJPG::CxImageJPG(): CxImage(CXIMAGE_FORMAT_JPG)
{
#if CXIMAGEJPG_SUPPORT_EXIF
m_exif = NULL;
memset(&m_exifinfo, 0, sizeof(EXIFINFO));
#endif
}
////////////////////////////////////////////////////////////////////////////////
CxImageJPG::~CxImageJPG()
{
#if CXIMAGEJPG_SUPPORT_EXIF
if (m_exif) delete m_exif;
#endif
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGEJPG_SUPPORT_EXIF
bool CxImageJPG::DecodeExif(CxFile * hFile)
{
m_exif = new CxExifInfo(&m_exifinfo);
if (m_exif){
long pos=hFile->Tell();
m_exif->DecodeExif(hFile);
hFile->Seek(pos,SEEK_SET);
return m_exif->m_exifinfo->IsExif;
} else {
return false;
}
}
#endif //CXIMAGEJPG_SUPPORT_EXIF
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageJPG::Decode(CxFile * hFile)
{
bool is_exif = false;
#if CXIMAGEJPG_SUPPORT_EXIF
is_exif = DecodeExif(hFile);
#endif
CImageIterator iter(this);
/* 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. <CSC> */
struct jpg_error_mgr jerr;
jerr.buffer=info.szLastError;
/* More stuff */
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.
*/
/* 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 = ima_jpeg_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);
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);
CxFileJpg src(hFile);
cinfo.src = &src;
/* Step 3: read file parameters with jpeg_read_header() */
(void) jpeg_read_header(&cinfo, TRUE);
/* Step 4 <chupeev> handle decoder options*/
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_GRAYSCALE) != 0)
cinfo.out_color_space = JCS_GRAYSCALE;
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_QUANTIZE) != 0) {
cinfo.quantize_colors = TRUE;
cinfo.desired_number_of_colors = GetJpegQuality();
}
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_DITHER) != 0)
cinfo.dither_mode = m_nDither;
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_ONEPASS) != 0)
cinfo.two_pass_quantize = FALSE;
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_NOSMOOTH) != 0)
cinfo.do_fancy_upsampling = FALSE;
//<DP>: Load true color images as RGB (no quantize)
/* Step 4: set parameters for decompression */
/* if (cinfo.jpeg_color_space!=JCS_GRAYSCALE) {
* cinfo.quantize_colors = TRUE;
* cinfo.desired_number_of_colors = 128;
*}
*/ //</DP>
// Set the scale <ignacio>
cinfo.scale_denom = GetJpegScale();
// Borrowed the idea from GIF implementation <ignacio>
if (info.nEscape == -1) {
// Return output dimensions only
jpeg_calc_output_dimensions(&cinfo);
head.biWidth = cinfo.output_width;
head.biHeight = cinfo.output_height;
info.dwType = CXIMAGE_FORMAT_JPG;
jpeg_destroy_decompress(&cinfo);
return true;
}
/* Step 5: Start decompressor */
jpeg_start_decompress(&cinfo);
/* 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.
*/
//Create the image using output dimensions <ignacio>
//Create(cinfo.image_width, cinfo.image_height, 8*cinfo.output_components, CXIMAGE_FORMAT_JPG);
Create(cinfo.output_width, cinfo.output_height, 8*cinfo.output_components, CXIMAGE_FORMAT_JPG);
if (!pDib) longjmp(jerr.setjmp_buffer, 1); //<DP> check if the image has been created
if (is_exif){
#if CXIMAGEJPG_SUPPORT_EXIF
if ((m_exifinfo.Xresolution != 0.0) && (m_exifinfo.ResolutionUnit != 0))
SetXDPI((long)(m_exifinfo.Xresolution/m_exifinfo.ResolutionUnit));
if ((m_exifinfo.Yresolution != 0.0) && (m_exifinfo.ResolutionUnit != 0))
SetYDPI((long)(m_exifinfo.Yresolution/m_exifinfo.ResolutionUnit));
#endif
} else {
switch (cinfo.density_unit) {
case 0: // [andy] fix for aspect ratio...
if((cinfo.Y_density > 0) && (cinfo.X_density > 0)){
SetYDPI((long)(GetXDPI()*(float(cinfo.Y_density)/float(cinfo.X_density))));
}
break;
case 2: // [andy] fix: cinfo.X/Y_density is pixels per centimeter
SetXDPI((long)floor(cinfo.X_density * 2.54 + 0.5));
SetYDPI((long)floor(cinfo.Y_density * 2.54 + 0.5));
break;
default:
SetXDPI(cinfo.X_density);
SetYDPI(cinfo.Y_density);
}
}
if (cinfo.out_color_space==JCS_GRAYSCALE){
SetGrayPalette();
head.biClrUsed =256;
} else {
if (cinfo.quantize_colors){
SetPalette(cinfo.actual_number_of_colors, cinfo.colormap[0], cinfo.colormap[1], cinfo.colormap[2]);
head.biClrUsed=cinfo.actual_number_of_colors;
} else {
head.biClrUsed=0;
}
}
/* 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.
*/
iter.Upset();
while (cinfo.output_scanline < cinfo.output_height) {
if (info.nEscape) longjmp(jerr.setjmp_buffer, 1); // <vho> - cancel decoding
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
// info.nProgress = (long)(100*cinfo.output_scanline/cinfo.output_height);
//<DP> Step 6a: CMYK->RGB */
if ((cinfo.num_components==4)&&(cinfo.quantize_colors==FALSE)){
BYTE k,*dst,*src;
dst=iter.GetRow();
src=buffer[0];
for(long x3=0,x4=0; x3<(long)info.dwEffWidth && x4<row_stride; x3+=3, x4+=4){
k=src[x4+3];
dst[x3] =(BYTE)((k * src[x4+2])/255);
dst[x3+1]=(BYTE)((k * src[x4+1])/255);
dst[x3+2]=(BYTE)((k * src[x4+0])/255);
}
} else {
/* Assume put_scanline_someplace wants a pointer and sample count. */
iter.SetRow(buffer[0], row_stride);
}
iter.PrevRow();
}
/* 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.
*/
//<DP> Step 7A: Swap red and blue components
// not necessary if swapped red and blue definition in jmorecfg.h;ln322 <W. Morrison>
if ((cinfo.num_components==3)&&(cinfo.quantize_colors==FALSE)){
BYTE* r0=GetBits();
for(long y=0;y<head.biHeight;y++){
if (info.nEscape) longjmp(jerr.setjmp_buffer, 1); // <vho> - cancel decoding
RGBtoBGR(r0,3*head.biWidth);
r0+=info.dwEffWidth;
}
}
/* Step 8: Release JPEG decompression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_decompress(&cinfo);
/* 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 true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageJPG::Encode(CxFile * hFile)
{
if (EncodeSafeCheck(hFile)) return false;
if (head.biClrUsed!=0 && !IsGrayScale()){
strcpy(info.szLastError,"JPEG can save only RGB or GreyScale images");
return false;
}
// necessary for EXIF, and for roll backs
long pos=hFile->Tell();
/* 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;
/* We use our private extension JPEG error handler. <CSC> */
struct jpg_error_mgr jerr;
jerr.buffer=info.szLastError;
/* More stuff */
int row_stride; /* physical row width in image buffer */
JSAMPARRAY buffer; /* Output row 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); <CSC>
/* We set up the normal JPEG error routines, then override error_exit. */
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = ima_jpeg_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.
*/
strcpy(info.szLastError, jerr.buffer); //<CSC>
jpeg_destroy_compress(&cinfo);
return 0;
}
/* 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.
*/
//jpeg_stdio_dest(&cinfo, outfile);
CxFileJpg dest(hFile);
cinfo.dest = &dest;
/* 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 = GetWidth(); // image width and height, in pixels
cinfo.image_height = GetHeight();
if (IsGrayScale()){
cinfo.input_components = 1; // # of color components per pixel
cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */
} else {
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:
*/
//#ifdef C_ARITH_CODING_SUPPORTED
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_ARITHMETIC) != 0)
cinfo.arith_code = TRUE;
//#endif
//#ifdef ENTROPY_OPT_SUPPORTED
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_OPTIMIZE) != 0)
cinfo.optimize_coding = TRUE;
//#endif
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_GRAYSCALE) != 0)
jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE);
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_SMOOTHING) != 0)
cinfo.smoothing_factor = m_nSmoothing;
jpeg_set_quality(&cinfo, GetJpegQuality(), (GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_BASELINE) != 0);
//#ifdef C_PROGRESSIVE_SUPPORTED
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_PROGRESSIVE) != 0)
jpeg_simple_progression(&cinfo);
//#endif
#ifdef C_LOSSLESS_SUPPORTED
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_LOSSLESS) != 0)
jpeg_simple_lossless(&cinfo, m_nPredictor, m_nPointTransform);
#endif
//SetCodecOption(ENCODE_SUBSAMPLE_444 | GetCodecOption(CXIMAGE_FORMAT_JPG),CXIMAGE_FORMAT_JPG);
// 2x2, 1x1, 1x1 (4:1:1) : High (default sub sampling)
cinfo.comp_info[0].h_samp_factor = 2;
cinfo.comp_info[0].v_samp_factor = 2;
cinfo.comp_info[1].h_samp_factor = 1;
cinfo.comp_info[1].v_samp_factor = 1;
cinfo.comp_info[2].h_samp_factor = 1;
cinfo.comp_info[2].v_samp_factor = 1;
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_SUBSAMPLE_422) != 0){
// 2x1, 1x1, 1x1 (4:2:2) : Medium
cinfo.comp_info[0].h_samp_factor = 2;
cinfo.comp_info[0].v_samp_factor = 1;
cinfo.comp_info[1].h_samp_factor = 1;
cinfo.comp_info[1].v_samp_factor = 1;
cinfo.comp_info[2].h_samp_factor = 1;
cinfo.comp_info[2].v_samp_factor = 1;
}
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_SUBSAMPLE_444) != 0){
// 1x1 1x1 1x1 (4:4:4) : None
cinfo.comp_info[0].h_samp_factor = 1;
cinfo.comp_info[0].v_samp_factor = 1;
cinfo.comp_info[1].h_samp_factor = 1;
cinfo.comp_info[1].v_samp_factor = 1;
cinfo.comp_info[2].h_samp_factor = 1;
cinfo.comp_info[2].v_samp_factor = 1;
}
cinfo.density_unit=1;
cinfo.X_density=(unsigned short)GetXDPI();
cinfo.Y_density=(unsigned short)GetYDPI();
/* 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 = info.dwEffWidth; /* JSAMPLEs per row in image_buffer */
//<DP> "8+row_stride" fix heap deallocation problem during debug???
buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo, JPOOL_IMAGE, 8+row_stride, 1);
CImageIterator iter(this);
iter.Upset();
while (cinfo.next_scanline < cinfo.image_height) {
// info.nProgress = (long)(100*cinfo.next_scanline/cinfo.image_height);
iter.GetRow(buffer[0], row_stride);
// not necessary if swapped red and blue definition in jmorecfg.h;ln322 <W. Morrison>
if (head.biClrUsed==0){ // swap R & B for RGB images
RGBtoBGR(buffer[0], row_stride); // Lance : 1998/09/01 : Bug ID: EXP-2.1.1-9
}
iter.PrevRow();
(void) jpeg_write_scanlines(&cinfo, buffer, 1);
}
/* Step 6: Finish compression */
jpeg_finish_compress(&cinfo);
/* Step 7: release JPEG compression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_compress(&cinfo);
#if CXIMAGEJPG_SUPPORT_EXIF
if (m_exif && m_exif->m_exifinfo->IsExif){
// discard useless sections (if any) read from original image
m_exif->DiscardAllButExif();
// read new created image, to split the sections
hFile->Seek(pos,SEEK_SET);
m_exif->DecodeExif(hFile,EXIF_READ_IMAGE);
// save back the image, adding EXIF section
hFile->Seek(pos,SEEK_SET);
m_exif->EncodeExif(hFile);
}
#endif
/* And we're done! */
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_JPG

View File

@@ -1,317 +0,0 @@
/*
* File: ximajpg.h
* Purpose: JPG Image Class Loader and Writer
*/
/* ==========================================================
* CxImageJPG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
*
* Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
*
* Special thanks to Chris Shearer Cooper for CxFileJpg tips & code
*
* EXIF support based on jhead-1.8 by Matthias Wandel <mwandel(at)rim(dot)net>
*
* original CImageJPG and CImageIterator implementation are:
* Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
*
* This software is based in part on the work of the Independent JPEG Group.
* Copyright (C) 1991-1998, Thomas G. Lane.
* ==========================================================
*/
#if !defined(__ximaJPEG_h)
#define __ximaJPEG_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_JPG
#define CXIMAGEJPG_SUPPORT_EXIF 1
extern "C" {
#include "../jpeg/jpeglib.h"
#include "../jpeg/jerror.h"
}
class DLL_EXP CxImageJPG: public CxImage
{
public:
CxImageJPG();
~CxImageJPG();
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JPG);}
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_JPG);}
bool Decode(CxFile * hFile);
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile);
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
#endif // CXIMAGE_SUPPORT_ENCODE
/*
* EXIF support based on jhead-1.8 by Matthias Wandel <mwandel(at)rim(dot)net>
*/
#if CXIMAGEJPG_SUPPORT_EXIF
#define MAX_COMMENT 1000
#define MAX_SECTIONS 20
typedef struct tag_ExifInfo {
char Version [5];
char CameraMake [32];
char CameraModel [40];
char DateTime [20];
int Height, Width;
int Orientation;
int IsColor;
int Process;
int FlashUsed;
float FocalLength;
float ExposureTime;
float ApertureFNumber;
float Distance;
float CCDWidth;
float ExposureBias;
int Whitebalance;
int MeteringMode;
int ExposureProgram;
int ISOequivalent;
int CompressionLevel;
float FocalplaneXRes;
float FocalplaneYRes;
float FocalplaneUnits;
float Xresolution;
float Yresolution;
float ResolutionUnit;
float Brightness;
char Comments[MAX_COMMENT];
unsigned char * ThumbnailPointer; /* Pointer at the thumbnail */
unsigned ThumbnailSize; /* Size of thumbnail. */
bool IsExif;
} EXIFINFO;
//--------------------------------------------------------------------------
// 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_JFIF 0xE0 // Jfif marker
#define M_EXIF 0xE1 // Exif marker
#define M_COM 0xFE // COMment
#define PSEUDO_IMAGE_MARKER 0x123; // Extra value.
#define EXIF_READ_EXIF 0x01
#define EXIF_READ_IMAGE 0x02
#define EXIF_READ_ALL 0x03
class DLL_EXP CxExifInfo
{
typedef struct tag_Section_t{
BYTE* Data;
int Type;
unsigned Size;
} Section_t;
public:
EXIFINFO* m_exifinfo;
char m_szLastError[256];
CxExifInfo(EXIFINFO* info = NULL);
~CxExifInfo();
bool DecodeExif(CxFile * hFile, int nReadMode = EXIF_READ_EXIF);
bool EncodeExif(CxFile * hFile);
void DiscardAllButExif();
protected:
bool process_EXIF(unsigned char * CharBuf, unsigned int length);
void process_COM (const BYTE * Data, int length);
void process_SOFn (const BYTE * Data, int marker);
int Get16u(void * Short);
int Get16m(void * Short);
long Get32s(void * Long);
unsigned long Get32u(void * Long);
double ConvertAnyFormat(void * ValuePtr, int Format);
void* FindSection(int SectionType);
bool ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength,
EXIFINFO * const pInfo, unsigned char ** const LastExifRefdP, int NestingLevel=0);
int ExifImageWidth;
int MotorolaOrder;
Section_t Sections[MAX_SECTIONS];
int SectionsRead;
bool freeinfo;
};
CxExifInfo* m_exif;
EXIFINFO m_exifinfo;
bool DecodeExif(CxFile * hFile);
bool DecodeExif(FILE * hFile) { CxIOFile file(hFile); return DecodeExif(&file); }
#endif //CXIMAGEJPG_SUPPORT_EXIF
////////////////////////////////////////////////////////////////////////////////////////
////////////////////// C x F i l e J p g ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
// thanks to Chris Shearer Cooper <cscooper(at)frii(dot)com>
class CxFileJpg : public jpeg_destination_mgr, public jpeg_source_mgr
{
public:
enum { eBufSize = 4096 };
CxFileJpg(CxFile* pFile)
{
m_pFile = pFile;
init_destination = InitDestination;
empty_output_buffer = EmptyOutputBuffer;
term_destination = TermDestination;
init_source = InitSource;
fill_input_buffer = FillInputBuffer;
skip_input_data = SkipInputData;
resync_to_restart = jpeg_resync_to_restart; // use default method
term_source = TermSource;
next_input_byte = NULL; //* => next byte to read from buffer
bytes_in_buffer = 0; //* # of bytes remaining in buffer
m_pBuffer = new unsigned char[eBufSize];
}
~CxFileJpg()
{
delete [] m_pBuffer;
}
static void InitDestination(j_compress_ptr cinfo)
{
CxFileJpg* pDest = (CxFileJpg*)cinfo->dest;
pDest->next_output_byte = pDest->m_pBuffer;
pDest->free_in_buffer = eBufSize;
}
static boolean EmptyOutputBuffer(j_compress_ptr cinfo)
{
CxFileJpg* pDest = (CxFileJpg*)cinfo->dest;
if (pDest->m_pFile->Write(pDest->m_pBuffer,1,eBufSize)!=(size_t)eBufSize)
ERREXIT(cinfo, JERR_FILE_WRITE);
pDest->next_output_byte = pDest->m_pBuffer;
pDest->free_in_buffer = eBufSize;
return TRUE;
}
static void TermDestination(j_compress_ptr cinfo)
{
CxFileJpg* pDest = (CxFileJpg*)cinfo->dest;
size_t datacount = eBufSize - pDest->free_in_buffer;
/* Write any data remaining in the buffer */
if (datacount > 0) {
if (!pDest->m_pFile->Write(pDest->m_pBuffer,1,datacount))
ERREXIT(cinfo, JERR_FILE_WRITE);
}
pDest->m_pFile->Flush();
/* Make sure we wrote the output file OK */
if (pDest->m_pFile->Error()) ERREXIT(cinfo, JERR_FILE_WRITE);
return;
}
static void InitSource(j_decompress_ptr cinfo)
{
CxFileJpg* pSource = (CxFileJpg*)cinfo->src;
pSource->m_bStartOfFile = TRUE;
}
static boolean FillInputBuffer(j_decompress_ptr cinfo)
{
size_t nbytes;
CxFileJpg* pSource = (CxFileJpg*)cinfo->src;
nbytes = pSource->m_pFile->Read(pSource->m_pBuffer,1,eBufSize);
if (nbytes <= 0){
if (pSource->m_bStartOfFile) //* Treat empty input file as fatal error
ERREXIT(cinfo, JERR_INPUT_EMPTY);
WARNMS(cinfo, JWRN_JPEG_EOF);
// Insert a fake EOI marker
pSource->m_pBuffer[0] = (JOCTET) 0xFF;
pSource->m_pBuffer[1] = (JOCTET) JPEG_EOI;
nbytes = 2;
}
pSource->next_input_byte = pSource->m_pBuffer;
pSource->bytes_in_buffer = nbytes;
pSource->m_bStartOfFile = FALSE;
return TRUE;
}
static void SkipInputData(j_decompress_ptr cinfo, long num_bytes)
{
CxFileJpg* pSource = (CxFileJpg*)cinfo->src;
if (num_bytes > 0){
while (num_bytes > (long)pSource->bytes_in_buffer){
num_bytes -= (long)pSource->bytes_in_buffer;
FillInputBuffer(cinfo);
// note we assume that fill_input_buffer will never return FALSE,
// so suspension need not be handled.
}
pSource->next_input_byte += (size_t) num_bytes;
pSource->bytes_in_buffer -= (size_t) num_bytes;
}
}
static void TermSource(j_decompress_ptr /*cinfo*/)
{
return;
}
protected:
CxFile *m_pFile;
unsigned char *m_pBuffer;
bool m_bStartOfFile;
};
public:
enum CODEC_OPTION
{
ENCODE_BASELINE = 0x1,
ENCODE_ARITHMETIC = 0x2,
ENCODE_GRAYSCALE = 0x4,
ENCODE_OPTIMIZE = 0x8,
ENCODE_PROGRESSIVE = 0x10,
ENCODE_LOSSLESS = 0x20,
ENCODE_SMOOTHING = 0x40,
DECODE_GRAYSCALE = 0x80,
DECODE_QUANTIZE = 0x100,
DECODE_DITHER = 0x200,
DECODE_ONEPASS = 0x400,
DECODE_NOSMOOTH = 0x800,
ENCODE_SUBSAMPLE_422 = 0x1000,
ENCODE_SUBSAMPLE_444 = 0x2000
};
int m_nPredictor;
int m_nPointTransform;
int m_nSmoothing;
int m_nQuantize;
J_DITHER_MODE m_nDither;
};
#endif
#endif

View File

@@ -1,365 +0,0 @@
// xImalpha.cpp : Alpha channel functions
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximage.h"
#if CXIMAGE_SUPPORT_ALPHA
////////////////////////////////////////////////////////////////////////////////
/**
* \sa AlphaSetMax
*/
BYTE CxImage::AlphaGetMax() const
{
return info.nAlphaMax;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets global Alpha (opacity) value applied to the whole image,
* valid only for painting functions.
* \param nAlphaMax: can be from 0 to 255
*/
void CxImage::AlphaSetMax(BYTE nAlphaMax)
{
info.nAlphaMax=nAlphaMax;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Checks if the image has a valid alpha channel.
*/
bool CxImage::AlphaIsValid()
{
return pAlpha!=0;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Enables the alpha palette, so the Draw() function changes its behavior.
*/
void CxImage::AlphaPaletteEnable(bool enable)
{
info.bAlphaPaletteEnabled=enable;
}
////////////////////////////////////////////////////////////////////////////////
/**
* True if the alpha palette is enabled for painting.
*/
bool CxImage::AlphaPaletteIsEnabled()
{
return info.bAlphaPaletteEnabled;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the alpha channel to full transparent. AlphaSet(0) has the same effect
*/
void CxImage::AlphaClear()
{
if (pAlpha) memset(pAlpha,0,head.biWidth * head.biHeight);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the alpha level for the whole image.
* \param level : from 0 (transparent) to 255 (opaque)
*/
void CxImage::AlphaSet(BYTE level)
{
if (pAlpha) memset(pAlpha,level,head.biWidth * head.biHeight);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Allocates an empty (opaque) alpha channel.
*/
bool CxImage::AlphaCreate()
{
if (pAlpha==NULL) {
pAlpha = (BYTE*)malloc(head.biWidth * head.biHeight);
if (pAlpha) memset(pAlpha,255,head.biWidth * head.biHeight);
}
return (pAlpha!=0);
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::AlphaDelete()
{
if (pAlpha) { free(pAlpha); pAlpha=0; }
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::AlphaInvert()
{
if (pAlpha) {
BYTE *iSrc=pAlpha;
long n=head.biHeight*head.biWidth;
for(long i=0; i < n; i++){
*iSrc=(BYTE)~(*(iSrc));
iSrc++;
}
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* Imports an existing alpa channel from another image with the same width and height.
*/
bool CxImage::AlphaCopy(CxImage &from)
{
if (from.pAlpha == NULL || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false;
if (pAlpha==NULL) pAlpha = (BYTE*)malloc(head.biWidth * head.biHeight);
if (pAlpha==NULL) return false;
memcpy(pAlpha,from.pAlpha,head.biWidth * head.biHeight);
info.nAlphaMax=from.info.nAlphaMax;
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Creates the alpha channel from a gray scale image.
*/
bool CxImage::AlphaSet(CxImage &from)
{
if (!from.IsGrayScale() || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false;
if (pAlpha==NULL) pAlpha = (BYTE*)malloc(head.biWidth * head.biHeight);
BYTE* src = from.info.pImage;
BYTE* dst = pAlpha;
if (src==NULL || dst==NULL) return false;
for (long y=0; y<head.biHeight; y++){
memcpy(dst,src,head.biWidth);
dst += head.biWidth;
src += from.info.dwEffWidth;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the alpha level for a single pixel
*/
void CxImage::AlphaSet(const long x,const long y,const BYTE level)
{
if (pAlpha && IsInside(x,y)) pAlpha[x+y*head.biWidth]=level;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Gets the alpha level for a single pixel
*/
BYTE CxImage::AlphaGet(const long x,const long y)
{
if (pAlpha && IsInside(x,y)) return pAlpha[x+y*head.biWidth];
return 0;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns pointer to alpha data for pixel (x,y).
*
* \author ***bd*** 2.2004
*/
BYTE* CxImage::AlphaGetPointer(const long x,const long y)
{
if (pAlpha && IsInside(x,y)) return pAlpha+x+y*head.biWidth;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Get alpha value without boundscheck (a bit faster). Pixel must be inside the image.
*
* \author ***bd*** 2.2004
*/
BYTE CxImage::BlindAlphaGet(const long x,const long y)
{
#ifdef _DEBUG
if (!IsInside(x,y) || (pAlpha==0))
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
throw 0;
#else
return 0;
#endif
#endif
return pAlpha[x+y*head.biWidth];
}
////////////////////////////////////////////////////////////////////////////////
/**
* Resets the alpha palette
*/
void CxImage::AlphaPaletteClear()
{
RGBQUAD c;
for(WORD ip=0; ip<head.biClrUsed;ip++){
c=GetPaletteColor((BYTE)ip);
c.rgbReserved=0;
SetPaletteColor((BYTE)ip,c);
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* Checks if the image has a valid alpha palette.
*/
bool CxImage::AlphaPaletteIsValid()
{
RGBQUAD c;
for(WORD ip=0; ip<head.biClrUsed;ip++){
c=GetPaletteColor((BYTE)ip);
if (c.rgbReserved != 0) return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Blends the alpha channel and the alpha palette with the pixels. The result is a 24 bit image.
* The background color can be selected using SetTransColor().
*/
void CxImage::AlphaStrip()
{
bool bAlphaPaletteIsValid = AlphaPaletteIsValid();
bool bAlphaIsValid = AlphaIsValid();
if (!(bAlphaIsValid || bAlphaPaletteIsValid)) return;
RGBQUAD c;
long a, a1;
if (head.biBitCount==24){
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
c = BlindGetPixelColor(x,y);
if (bAlphaIsValid) a=(BlindAlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
a1 = 256-a;
c.rgbBlue = (BYTE)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)>>8);
c.rgbGreen = (BYTE)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)>>8);
c.rgbRed = (BYTE)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)>>8);
BlindSetPixelColor(x,y,c);
}
}
AlphaDelete();
} else {
CxImage tmp(head.biWidth,head.biHeight,24);
if (!tmp.IsValid()){
strcpy(info.szLastError,tmp.GetLastError());
return;
}
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
c = BlindGetPixelColor(x,y);
if (bAlphaIsValid) a=(BlindAlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
if (bAlphaPaletteIsValid) a=(c.rgbReserved*a)/255;
a1 = 256-a;
c.rgbBlue = (BYTE)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)>>8);
c.rgbGreen = (BYTE)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)>>8);
c.rgbRed = (BYTE)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)>>8);
tmp.BlindSetPixelColor(x,y,c);
}
}
Transfer(tmp);
}
return;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::AlphaFlip()
{
if (!pAlpha) return false;
BYTE *buff = (BYTE*)malloc(head.biWidth);
if (!buff) return false;
BYTE *iSrc,*iDst;
iSrc = pAlpha + (head.biHeight-1)*head.biWidth;
iDst = pAlpha;
for (long i=0; i<(head.biHeight/2); ++i)
{
memcpy(buff, iSrc, head.biWidth);
memcpy(iSrc, iDst, head.biWidth);
memcpy(iDst, buff, head.biWidth);
iSrc-=head.biWidth;
iDst+=head.biWidth;
}
free(buff);
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::AlphaMirror()
{
if (!pAlpha) return false;
BYTE* pAlpha2 = (BYTE*)malloc(head.biWidth * head.biHeight);
if (!pAlpha2) return false;
BYTE *iSrc,*iDst;
long wdt=head.biWidth-1;
iSrc=pAlpha + wdt;
iDst=pAlpha2;
for(long y=0; y < head.biHeight; y++){
for(long x=0; x <= wdt; x++)
*(iDst+x)=*(iSrc-x);
iSrc+=head.biWidth;
iDst+=head.biWidth;
}
free(pAlpha);
pAlpha=pAlpha2;
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Exports the alpha channel in a 8bpp grayscale image.
*/
bool CxImage::AlphaSplit(CxImage *dest)
{
if (!pAlpha || !dest) return false;
CxImage tmp(head.biWidth,head.biHeight,8);
if (!tmp.IsValid()){
strcpy(info.szLastError,tmp.GetLastError());
return false;
}
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
tmp.BlindSetPixelIndex(x,y,pAlpha[x+y*head.biWidth]);
}
}
tmp.SetGrayPalette();
dest->Transfer(tmp);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Exports the alpha palette channel in a 8bpp grayscale image.
*/
bool CxImage::AlphaPaletteSplit(CxImage *dest)
{
if (!AlphaPaletteIsValid() || !dest) return false;
CxImage tmp(head.biWidth,head.biHeight,8);
if (!tmp.IsValid()){
strcpy(info.szLastError,tmp.GetLastError());
return false;
}
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
tmp.BlindSetPixelIndex(x,y,BlindGetPixelColor(x,y).rgbReserved);
}
}
tmp.SetGrayPalette();
dest->Transfer(tmp);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Merge in the alpha layer the transparent color mask
* (previously set with SetTransColor or SetTransIndex)
*/
bool CxImage::AlphaFromTransparency()
{
if (!IsValid() || !IsTransparent())
return false;
AlphaCreate();
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
if (IsTransparent(x,y)){
AlphaSet(x,y,0);
}
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_ALPHA

View File

@@ -1,116 +0,0 @@
// xImaLyr.cpp : Layers functions
/* 21/04/2003 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximage.h"
#if CXIMAGE_SUPPORT_LAYERS
////////////////////////////////////////////////////////////////////////////////
/**
* If the object is an internal layer, GetParent return its parent in the hierarchy.
*/
CxImage* CxImage::GetParent() const
{
return info.pParent;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Number of layers allocated directly by the object.
*/
long CxImage::GetNumLayers() const
{
return info.nNumLayers;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Creates an empty layer. If position is less than 0, the new layer will be placed in the last position
*/
bool CxImage::LayerCreate(long position)
{
if ( position < 0 || position > info.nNumLayers ) position = info.nNumLayers;
CxImage** ptmp = new CxImage*[info.nNumLayers + 1];
if (ptmp==0) return false;
int i=0;
for (int n=0; n<info.nNumLayers; n++){
if (position == n){
ptmp[n] = new CxImage();
i=1;
}
ptmp[n+i]=ppLayers[n];
}
if (i==0) ptmp[info.nNumLayers] = new CxImage();
if (ptmp[position]){
ptmp[position]->info.pParent = this;
} else {
free(ptmp);
return false;
}
info.nNumLayers++;
delete [] ppLayers;
ppLayers = ptmp;
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Deletes a layer. If position is less than 0, the last layer will be deleted
*/
bool CxImage::LayerDelete(long position)
{
if ( position >= info.nNumLayers ) return false;
if ( position < 0) position = info.nNumLayers - 1;
if ( position < 0) return false;
if (info.nNumLayers>1){
CxImage** ptmp = new CxImage*[info.nNumLayers - 1];
if (ptmp==0) return false;
int i=0;
for (int n=0; n<info.nNumLayers; n++){
if (position == n){
delete ppLayers[n];
i=1;
}
ptmp[n]=ppLayers[n+i];
}
info.nNumLayers--;
delete [] ppLayers;
ppLayers = ptmp;
} else {
delete ppLayers[0];
delete [] ppLayers;
ppLayers = 0;
info.nNumLayers = 0;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::LayerDeleteAll()
{
if (ppLayers) {
for(long n=0; n<info.nNumLayers;n++){ delete ppLayers[n]; }
delete [] ppLayers; ppLayers=0; info.nNumLayers = 0;
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns a pointer to a layer. If position is less than 0, the last layer will be returned
*/
CxImage* CxImage::GetLayer(long position)
{
if ( ppLayers == NULL) return NULL;
if ( info.nNumLayers == 0) return NULL;
if ( position >= info.nNumLayers ) return NULL;
if ( position < 0) position = info.nNumLayers - 1;
return ppLayers[position];
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_LAYERS

View File

@@ -1,430 +0,0 @@
/*
* File: ximamng.cpp
* Purpose: Platform Independent MNG Image Class Loader and Writer
* Author: 07/Aug/2001 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximamng.h"
#if CXIMAGE_SUPPORT_MNG
////////////////////////////////////////////////////////////////////////////////
// callbacks for the mng decoder:
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// memory allocation; data must be zeroed
static mng_ptr
mymngalloc( mng_uint32 size )
{
return (mng_ptr)calloc(1, size);
}
////////////////////////////////////////////////////////////////////////////////
// memory deallocation
static void mymngfree(mng_ptr p, mng_uint32 size)
{
free(p);
}
////////////////////////////////////////////////////////////////////////////////
// Stream open/close:
// since the user is responsible for opening and closing the file,
// we leave the default implementation open
static mng_bool mymngopenstream(mng_handle mng) { return MNG_TRUE; }
static mng_bool mymngopenstreamwrite(mng_handle mng) { return MNG_TRUE; }
static mng_bool mymngclosestream(mng_handle mng) { return MNG_TRUE; }
////////////////////////////////////////////////////////////////////////////////
// feed data to the decoder
static mng_bool mymngreadstream(mng_handle mng, mng_ptr buffer, mng_uint32 size, mng_uint32 *bytesread)
{
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
// read the requested amount of data from the file
*bytesread = mymng->file->Read( buffer, sizeof(BYTE), size);
return MNG_TRUE;
}
////////////////////////////////////////////////////////////////////////////////
static mng_bool mymngwritestream (mng_handle mng, mng_ptr pBuf, mng_uint32 iSize, mng_uint32 *iWritten)
{
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
// write it
*iWritten = mymng->file->Write (pBuf, 1, iSize);
return MNG_TRUE;
}
////////////////////////////////////////////////////////////////////////////////
// the header's been read. set up the display stuff
static mng_bool mymngprocessheader( mng_handle mng, mng_uint32 width, mng_uint32 height )
{
// normally the image buffer is allocated here,
// but in this module we don't know nothing about
// the final environment.
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
mymng->width = width;
mymng->height = height;
mymng->bpp = 24;
mymng->effwdt = ((((width * mymng->bpp) + 31) >> 5) << 2);
if (mng->bUseBKGD){
mymng->nBkgndIndex = 0;
mymng->nBkgndColor.rgbRed = mng->iBGred >> 8;
mymng->nBkgndColor.rgbGreen =mng->iBGgreen >> 8;
mymng->nBkgndColor.rgbBlue = mng->iBGblue >> 8;
}
mymng->image = (BYTE*)malloc(height * mymng->effwdt);
// tell the mng decoder about our bit-depth choice
#if CXIMAGE_SUPPORT_ALPHA
mng_set_canvasstyle( mng, MNG_CANVAS_RGB8_A8 );
mymng->alpha = (BYTE*)malloc(height * width);
#else
mng_set_canvasstyle( mng, MNG_CANVAS_BGR8);
mymng->alpha = NULL;
#endif
return MNG_TRUE;
}
////////////////////////////////////////////////////////////////////////////////
// return a row pointer for the decoder to fill
static mng_ptr mymnggetcanvasline( mng_handle mng, mng_uint32 line )
{
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
return (mng_ptr)(mymng->image + (mymng->effwdt * (mymng->height - 1 - line)));
}
////////////////////////////////////////////////////////////////////////////////
// return a row pointer for the decoder to fill for alpha channel
static mng_ptr mymnggetalphaline( mng_handle mng, mng_uint32 line )
{
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
return (mng_ptr)(mymng->alpha + (mymng->width * (mymng->height - 1 - line)));
}
////////////////////////////////////////////////////////////////////////////////
// timer
static mng_uint32 mymnggetticks(mng_handle mng)
{
#ifdef WIN32
return (mng_uint32)GetTickCount();
#else
return 0;
#endif
}
////////////////////////////////////////////////////////////////////////////////
// Refresh: actual frame need to be updated (Invalidate)
static mng_bool mymngrefresh(mng_handle mng, mng_uint32 x, mng_uint32 y, mng_uint32 w, mng_uint32 h)
{
// mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
return MNG_TRUE;
}
////////////////////////////////////////////////////////////////////////////////
// interframe delay callback
static mng_bool mymngsettimer(mng_handle mng, mng_uint32 msecs)
{
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
mymng->delay = msecs; // set the timer for when the decoder wants to be woken
return MNG_TRUE;
}
////////////////////////////////////////////////////////////////////////////////
static mng_bool mymngerror(mng_handle mng, mng_int32 code, mng_int8 severity, mng_chunkid chunktype, mng_uint32 chunkseq, mng_int32 extra1, mng_int32 extra2, mng_pchar text)
{
return mng_cleanup(&mng); //<Arkadiy Olovyannikov>
}
////////////////////////////////////////////////////////////////////////////////
// CxImage members
////////////////////////////////////////////////////////////////////////////////
CxImageMNG::CxImageMNG(): CxImage(CXIMAGE_FORMAT_MNG)
{
hmng = NULL;
memset(&mnginfo,0,sizeof(mngstuff));
mnginfo.nBkgndIndex = -1;
mnginfo.speed = 1.0f;
}
////////////////////////////////////////////////////////////////////////////////
CxImageMNG::~CxImageMNG()
{
// cleanup and return
if (mnginfo.thread){ //close the animation thread
mnginfo.animation_enabled=0;
ResumeThread(mnginfo.thread);
WaitForSingleObject(mnginfo.thread,500);
CloseHandle(mnginfo.thread);
}
// free objects
if (mnginfo.image) free(mnginfo.image);
if (mnginfo.alpha) free(mnginfo.alpha);
if (hmng) mng_cleanup(&hmng); //be sure it's not needed any more. (active timers ?)
}
////////////////////////////////////////////////////////////////////////////////
void CxImageMNG::SetCallbacks(mng_handle mng)
{
// set the callbacks
mng_setcb_errorproc(mng, mymngerror);
mng_setcb_openstream(mng, mymngopenstream);
mng_setcb_closestream(mng, mymngclosestream);
mng_setcb_readdata(mng, mymngreadstream);
mng_setcb_processheader(mng, mymngprocessheader);
mng_setcb_getcanvasline(mng, mymnggetcanvasline);
mng_setcb_refresh(mng, mymngrefresh);
mng_setcb_gettickcount(mng, mymnggetticks);
mng_setcb_settimer(mng, mymngsettimer);
mng_setcb_refresh(mng, mymngrefresh);
mng_setcb_getalphaline(mng, mymnggetalphaline);
}
////////////////////////////////////////////////////////////////////////////////
// can't use the CxImage implementation because it looses mnginfo
bool CxImageMNG::Load(const TCHAR * imageFileName){
FILE* hFile; //file handle to read the image
#ifdef WIN32
if ((hFile=_tfopen(imageFileName,_T("rb")))==NULL) return false; // For UNICODE support
#else
if ((hFile=fopen(imageFileName,"rb"))==NULL) return false;
#endif
bool bOK = Decode(hFile);
fclose(hFile);
return bOK;
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageMNG::Decode(CxFile *hFile)
{
if (hFile == NULL) return false;
cx_try
{
// set up the mng decoder for our stream
hmng = mng_initialize(&mnginfo, mymngalloc, mymngfree, MNG_NULL);
if (hmng == NULL) cx_throw("could not initialize libmng");
// set the file we want to play
mnginfo.file = hFile;
// Set the colorprofile, lcms uses this:
mng_set_srgb(hmng, MNG_TRUE );
// Set white as background color:
WORD Red,Green,Blue;
Red = Green = Blue = (255 << 8) + 255;
mng_set_bgcolor(hmng, Red, Green, Blue );
// If PNG Background is available, use it:
mng_set_usebkgd(hmng, MNG_TRUE );
// No need to store chunks:
mng_set_storechunks(hmng, MNG_FALSE);
// No need to wait: straight reading
mng_set_suspensionmode(hmng, MNG_FALSE);
SetCallbacks(hmng);
mng_datap pData = (mng_datap)hmng;
// read in the image
info.nNumFrames=0;
int retval=MNG_NOERROR;
retval = mng_readdisplay(hmng);
if (retval != MNG_NOERROR && retval != MNG_NEEDTIMERWAIT){
mng_store_error(hmng,retval,0,0);
if (hmng->zErrortext){
cx_throw(hmng->zErrortext);
} else {
cx_throw("Error in MNG file");
}
}
if (info.nEscape == -1) {
// Return output dimensions only
head.biWidth = hmng->iWidth;
head.biHeight = hmng->iHeight;
info.dwType = CXIMAGE_FORMAT_MNG;
return true;
}
// read all
while(pData->bReading){
retval = mng_display_resume(hmng);
info.nNumFrames++;
}
// single frame check:
if (retval != MNG_NEEDTIMERWAIT){
info.nNumFrames--;
} else {
mnginfo.animation=1;
}
if (info.nNumFrames<=0) info.nNumFrames=1;
if (mnginfo.animation_enabled==0){
// select the frame
if (info.nFrame>=0 && info.nFrame<info.nNumFrames){
for (int n=0;n<info.nFrame;n++) mng_display_resume(hmng);
} else cx_throw("Error: frame not present in MNG file");
}
if (mnginfo.nBkgndIndex >= 0){
info.nBkgndIndex = mnginfo.nBkgndIndex;
info.nBkgndColor.rgbRed = mnginfo.nBkgndColor.rgbRed;
info.nBkgndColor.rgbGreen = mnginfo.nBkgndColor.rgbGreen;
info.nBkgndColor.rgbBlue = mnginfo.nBkgndColor.rgbBlue;
}
//store the newly created image
if (Create(mnginfo.width,mnginfo.height,mnginfo.bpp, CXIMAGE_FORMAT_MNG)){
memcpy(GetBits(), mnginfo.image, info.dwEffWidth * head.biHeight);
#if CXIMAGE_SUPPORT_ALPHA
SwapRGB2BGR();
AlphaCreate();
if(AlphaIsValid() && mnginfo.alpha){
memcpy(AlphaGetPointer(),mnginfo.alpha,mnginfo.width * mnginfo.height);
}
#endif
} else cx_throw("CxImageMNG::Decode cannot create image");
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageMNG::Encode(CxFile *hFile)
{
if (EncodeSafeCheck(hFile)) return false;
cx_try
{
if (head.biClrUsed != 0) cx_throw("MNG encoder can save only RGB images");
// set the file we want to play
mnginfo.file = hFile;
mnginfo.bpp = head.biBitCount;
mnginfo.effwdt = info.dwEffWidth;
mnginfo.height = head.biHeight;
mnginfo.width = head.biWidth;
mnginfo.image = (BYTE*)malloc(head.biSizeImage);
if (mnginfo.image == NULL) cx_throw("could not allocate memory for MNG");
memcpy(mnginfo.image,info.pImage, head.biSizeImage);
// set up the mng decoder for our stream
hmng = mng_initialize(&mnginfo, mymngalloc, mymngfree, MNG_NULL);
if (hmng == NULL) cx_throw("could not initialize libmng");
mng_setcb_openstream(hmng, mymngopenstreamwrite );
mng_setcb_closestream(hmng, mymngclosestream);
mng_setcb_writedata(hmng, mymngwritestream);
// Write File:
mng_create(hmng);
// Just a single Frame (save a normal PNG):
WritePNG(hmng, 0, 1 );
// Now write file:
mng_write(hmng);
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// Writes a single PNG datastream
void CxImageMNG::WritePNG( mng_handle hMNG, int Frame, int FrameCount )
{
mngstuff *mymng = (mngstuff *)mng_get_userdata(hMNG);
int OffsetX=0,OffsetY=0,OffsetW=mymng->width,OffsetH=mymng->height;
BYTE *tmpbuffer = new BYTE[ (mymng->effwdt+1) * mymng->height];
if( tmpbuffer == 0 ) return;
// Write DEFI chunk.
mng_putchunk_defi( hMNG, 0, 0, 0, MNG_TRUE, OffsetX, OffsetY, MNG_FALSE, 0, 0, 0, 0 );
// Write Header:
mng_putchunk_ihdr(
hMNG,
OffsetW, OffsetH,
MNG_BITDEPTH_8,
MNG_COLORTYPE_RGB,
MNG_COMPRESSION_DEFLATE,
MNG_FILTER_ADAPTIVE,
MNG_INTERLACE_NONE
);
// transfer data, add Filterbyte:
for( int Row=0; Row<OffsetH; Row++ ){
// First Byte in each Scanline is Filterbyte: Currently 0 -> No Filter.
tmpbuffer[Row*(mymng->effwdt+1)]=0;
// Copy the scanline: (reverse order)
memcpy(tmpbuffer+Row*(mymng->effwdt+1)+1,
mymng->image+((OffsetH-1-(OffsetY+Row))*(mymng->effwdt))+OffsetX,mymng->effwdt);
// swap red and blue components
RGBtoBGR(tmpbuffer+Row*(mymng->effwdt+1)+1,mymng->effwdt);
}
// Compress data with ZLib (Deflate):
BYTE *dstbuffer = new BYTE[(mymng->effwdt+1)*OffsetH];
if( dstbuffer == 0 ) return;
DWORD dstbufferSize=(mymng->effwdt+1)*OffsetH;
// Compress data:
if(Z_OK != compress2((Bytef *)dstbuffer,(ULONG *)&dstbufferSize,(const Bytef*)tmpbuffer,
(ULONG) (mymng->effwdt+1)*OffsetH,9 )) return;
// Write Data into MNG File:
mng_putchunk_idat( hMNG, dstbufferSize, (mng_ptr*)dstbuffer);
mng_putchunk_iend(hMNG);
// Free the stuff:
delete [] tmpbuffer;
delete [] dstbuffer;
}
////////////////////////////////////////////////////////////////////////////////
long CxImageMNG::Resume()
{
if (MNG_NEEDTIMERWAIT == mng_display_resume(hmng)){
if (info.pImage==NULL){
Create(mnginfo.width,mnginfo.height,mnginfo.bpp, CXIMAGE_FORMAT_MNG);
}
if (IsValid()){
memcpy(GetBits(), mnginfo.image, info.dwEffWidth * head.biHeight);
#if CXIMAGE_SUPPORT_ALPHA
SwapRGB2BGR();
AlphaCreate();
if(AlphaIsValid() && mnginfo.alpha){
memcpy(AlphaGetPointer(),mnginfo.alpha,mnginfo.width * mnginfo.height);
}
#endif
}
} else {
mnginfo.animation_enabled = 0;
}
return mnginfo.animation_enabled;
}
////////////////////////////////////////////////////////////////////////////////
void CxImageMNG::SetSpeed(float speed)
{
if (speed>10.0) mnginfo.speed = 10.0f;
else if (speed<0.1) mnginfo.speed = 0.1f;
else mnginfo.speed=speed;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_MNG

View File

@@ -1,88 +0,0 @@
/*
* File: ximamng.h
* Purpose: Declaration of the MNG Image Class
* Author: Davide Pizzolato - www.xdp.it
* Created: 2001
*/
/* ==========================================================
* CxImageMNG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
*
* Special thanks to Frank Haug <f.haug(at)jdm(dot)de> for suggestions and code.
*
* original mng.cpp code created by Nikolaus Brennig, November 14th, 2000. <virtualnik(at)nol(dot)at>
*
* LIBMNG Copyright (c) 2000,2001 Gerard Juyn (gerard@libmng.com)
* ==========================================================
*/
#if !defined(__ximaMNG_h)
#define __ximaMNG_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_MNG
//#define MNG_NO_CMS
#define MNG_SUPPORT_DISPLAY
#define MNG_SUPPORT_READ
#define MNG_SUPPORT_WRITE
#define MNG_ACCESS_CHUNKS
#define MNG_STORE_CHUNKS
extern "C" {
#include "../mng/libmng.h"
#include "../mng/libmng_data.h"
#include "../mng/libmng_error.h"
}
//unsigned long _stdcall RunMNGThread(void *lpParam);
typedef struct tagmngstuff
{
CxFile *file;
BYTE *image;
BYTE *alpha;
HANDLE thread;
mng_uint32 delay;
mng_uint32 width;
mng_uint32 height;
mng_uint32 effwdt;
mng_int16 bpp;
mng_bool animation;
mng_bool animation_enabled;
float speed;
long nBkgndIndex;
RGBQUAD nBkgndColor;
} mngstuff;
class CxImageMNG: public CxImage
{
public:
CxImageMNG();
~CxImageMNG();
bool Load(const TCHAR * imageFileName);
bool Decode(CxFile * hFile);
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile);
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_MNG);}
#endif // CXIMAGE_SUPPORT_ENCODE
long Resume();
void SetSpeed(float speed);
mng_handle hmng;
mngstuff mnginfo;
protected:
void WritePNG(mng_handle hMNG, int Frame, int FrameCount );
void SetCallbacks(mng_handle mng);
};
#endif
#endif

View File

@@ -1,834 +0,0 @@
// xImaPal.cpp : Palette and Pixel functions
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximage.h"
////////////////////////////////////////////////////////////////////////////////
/**
* returns the palette dimension in byte
*/
DWORD CxImage::GetPaletteSize()
{
return (head.biClrUsed * sizeof(RGBQUAD));
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPaletteColor(BYTE idx, BYTE r, BYTE g, BYTE b, BYTE alpha)
{
if ((pDib)&&(head.biClrUsed)){
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx<head.biClrUsed){
long ldx=idx*sizeof(RGBQUAD);
iDst[ldx++] = (BYTE) b;
iDst[ldx++] = (BYTE) g;
iDst[ldx++] = (BYTE) r;
iDst[ldx] = (BYTE) alpha;
info.last_c_isvalid = false;
}
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPaletteColor(BYTE idx, RGBQUAD c)
{
if ((pDib)&&(head.biClrUsed)){
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx<head.biClrUsed){
long ldx=idx*sizeof(RGBQUAD);
iDst[ldx++] = (BYTE) c.rgbBlue;
iDst[ldx++] = (BYTE) c.rgbGreen;
iDst[ldx++] = (BYTE) c.rgbRed;
iDst[ldx] = (BYTE) c.rgbReserved;
info.last_c_isvalid = false;
}
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPaletteColor(BYTE idx, COLORREF cr)
{
if ((pDib)&&(head.biClrUsed)){
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx<head.biClrUsed){
long ldx=idx*sizeof(RGBQUAD);
iDst[ldx++] = (BYTE) GetBValue(cr);
iDst[ldx++] = (BYTE) GetGValue(cr);
iDst[ldx++] = (BYTE) GetRValue(cr);
iDst[ldx] = (BYTE) 0;
info.last_c_isvalid = false;
}
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* returns the pointer to the first palette index
*/
RGBQUAD* CxImage::GetPalette() const
{
if ((pDib)&&(head.biClrUsed))
return (RGBQUAD*)((BYTE*)pDib + sizeof(BITMAPINFOHEADER));
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns the color of the specified index.
*/
RGBQUAD CxImage::GetPaletteColor(BYTE idx)
{
RGBQUAD rgb = {0,0,0,0};
if ((pDib)&&(head.biClrUsed)){
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx<head.biClrUsed){
long ldx=idx*sizeof(RGBQUAD);
rgb.rgbBlue = iDst[ldx++];
rgb.rgbGreen=iDst[ldx++];
rgb.rgbRed =iDst[ldx++];
rgb.rgbReserved = iDst[ldx];
}
}
return rgb;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns the palette index of the specified pixel.
*/
BYTE CxImage::GetPixelIndex(long x,long y)
{
if ((pDib==NULL)||(head.biClrUsed==0)) return 0;
if ((x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight)) {
if (info.nBkgndIndex >= 0) return (BYTE)info.nBkgndIndex;
else return *info.pImage;
}
if (head.biBitCount==8){
return info.pImage[y*info.dwEffWidth + x];
} else {
BYTE pos;
BYTE iDst= info.pImage[y*info.dwEffWidth + (x*head.biBitCount >> 3)];
if (head.biBitCount==4){
pos = (BYTE)(4*(1-x%2));
iDst &= (0x0F<<pos);
return (BYTE)(iDst >> pos);
} else if (head.biBitCount==1){
pos = (BYTE)(7-x%8);
iDst &= (0x01<<pos);
return (BYTE)(iDst >> pos);
}
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
BYTE CxImage::BlindGetPixelIndex(const long x,const long y)
{
#ifdef _DEBUG
if ((pDib==NULL) || (head.biClrUsed==0) || !IsInside(x,y))
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
throw 0;
#else
return 0;
#endif
#endif
if (head.biBitCount==8){
return info.pImage[y*info.dwEffWidth + x];
} else {
BYTE pos;
BYTE iDst= info.pImage[y*info.dwEffWidth + (x*head.biBitCount >> 3)];
if (head.biBitCount==4){
pos = (BYTE)(4*(1-x%2));
iDst &= (0x0F<<pos);
return (BYTE)(iDst >> pos);
} else if (head.biBitCount==1){
pos = (BYTE)(7-x%8);
iDst &= (0x01<<pos);
return (BYTE)(iDst >> pos);
}
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
RGBQUAD CxImage::GetPixelColor(long x,long y, bool bGetAlpha)
{
// RGBQUAD rgb={0,0,0,0};
RGBQUAD rgb=info.nBkgndColor; //<mpwolski>
if ((pDib==NULL)||(x<0)||(y<0)||
(x>=head.biWidth)||(y>=head.biHeight)){
if (info.nBkgndIndex >= 0){
if (head.biBitCount<24) return GetPaletteColor((BYTE)info.nBkgndIndex);
else return info.nBkgndColor;
} else if (pDib) return GetPixelColor(0,0);
return rgb;
}
if (head.biClrUsed){
rgb = GetPaletteColor(BlindGetPixelIndex(x,y));
} else {
BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3;
rgb.rgbBlue = *iDst++;
rgb.rgbGreen= *iDst++;
rgb.rgbRed = *iDst;
}
#if CXIMAGE_SUPPORT_ALPHA
if (pAlpha && bGetAlpha) rgb.rgbReserved = BlindAlphaGet(x,y);
#else
rgb.rgbReserved = 0;
#endif //CXIMAGE_SUPPORT_ALPHA
return rgb;
}
////////////////////////////////////////////////////////////////////////////////
/**
* This is (a bit) faster version of GetPixelColor.
* It tests bounds only in debug mode (_DEBUG defined).
*
* It is an error to request out-of-borders pixel with this method.
* In DEBUG mode an exception will be thrown, and data will be violated in non-DEBUG mode.
* \author ***bd*** 2.2004
*/
RGBQUAD CxImage::BlindGetPixelColor(const long x,const long y, bool bGetAlpha)
{
RGBQUAD rgb;
#ifdef _DEBUG
if ((pDib==NULL) || !IsInside(x,y))
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
throw 0;
#else
{rgb.rgbReserved = 0; return rgb;}
#endif
#endif
if (head.biClrUsed){
rgb = GetPaletteColor(BlindGetPixelIndex(x,y));
} else {
BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3;
rgb.rgbBlue = *iDst++;
rgb.rgbGreen= *iDst++;
rgb.rgbRed = *iDst;
rgb.rgbReserved = 0; //needed for images without alpha layer
}
#if CXIMAGE_SUPPORT_ALPHA
if (pAlpha && bGetAlpha) rgb.rgbReserved = BlindAlphaGet(x,y);
#else
rgb.rgbReserved = 0;
#endif //CXIMAGE_SUPPORT_ALPHA
return rgb;
}
////////////////////////////////////////////////////////////////////////////////
BYTE CxImage::GetPixelGray(long x, long y)
{
RGBQUAD color = GetPixelColor(x,y);
return (BYTE)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue);
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::BlindSetPixelIndex(long x,long y,BYTE i)
{
#ifdef _DEBUG
if ((pDib==NULL)||(head.biClrUsed==0)||
(x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight))
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
throw 0;
#else
return;
#endif
#endif
if (head.biBitCount==8){
info.pImage[y*info.dwEffWidth + x]=i;
return;
} else {
BYTE pos;
BYTE* iDst= info.pImage + y*info.dwEffWidth + (x*head.biBitCount >> 3);
if (head.biBitCount==4){
pos = (BYTE)(4*(1-x%2));
*iDst &= ~(0x0F<<pos);
*iDst |= ((i & 0x0F)<<pos);
return;
} else if (head.biBitCount==1){
pos = (BYTE)(7-x%8);
*iDst &= ~(0x01<<pos);
*iDst |= ((i & 0x01)<<pos);
return;
}
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPixelIndex(long x,long y,BYTE i)
{
if ((pDib==NULL)||(head.biClrUsed==0)||
(x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight)) return ;
if (head.biBitCount==8){
info.pImage[y*info.dwEffWidth + x]=i;
return;
} else {
BYTE pos;
BYTE* iDst= info.pImage + y*info.dwEffWidth + (x*head.biBitCount >> 3);
if (head.biBitCount==4){
pos = (BYTE)(4*(1-x%2));
*iDst &= ~(0x0F<<pos);
*iDst |= ((i & 0x0F)<<pos);
return;
} else if (head.biBitCount==1){
pos = (BYTE)(7-x%8);
*iDst &= ~(0x01<<pos);
*iDst |= ((i & 0x01)<<pos);
return;
}
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPixelColor(long x,long y,COLORREF cr)
{
SetPixelColor(x,y,RGBtoRGBQUAD(cr));
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::BlindSetPixelColor(long x,long y,RGBQUAD c, bool bSetAlpha)
{
#ifdef _DEBUG
if ((pDib==NULL)||(x<0)||(y<0)||
(x>=head.biWidth)||(y>=head.biHeight))
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
throw 0;
#else
return;
#endif
#endif
if (head.biClrUsed)
BlindSetPixelIndex(x,y,GetNearestIndex(c));
else {
BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3;
*iDst++ = c.rgbBlue;
*iDst++ = c.rgbGreen;
*iDst = c.rgbRed;
}
#if CXIMAGE_SUPPORT_ALPHA
if (bSetAlpha) AlphaSet(x,y,c.rgbReserved);
#endif //CXIMAGE_SUPPORT_ALPHA
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPixelColor(long x,long y,RGBQUAD c, bool bSetAlpha)
{
if ((pDib==NULL)||(x<0)||(y<0)||
(x>=head.biWidth)||(y>=head.biHeight)) return;
if (head.biClrUsed)
BlindSetPixelIndex(x,y,GetNearestIndex(c));
else {
BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3;
*iDst++ = c.rgbBlue;
*iDst++ = c.rgbGreen;
*iDst = c.rgbRed;
}
#if CXIMAGE_SUPPORT_ALPHA
if (bSetAlpha) AlphaSet(x,y,c.rgbReserved);
#endif //CXIMAGE_SUPPORT_ALPHA
}
////////////////////////////////////////////////////////////////////////////////
/**
* Blends the current pixel color with a new color.
* \param x,y = pixel
* \param c = new color
* \param blend = can be from 0 (no effect) to 1 (full effect).
* \param bSetAlpha = if true, blends also the alpha component stored in c.rgbReserved
*/
void CxImage::BlendPixelColor(long x,long y,RGBQUAD c, float blend, bool bSetAlpha)
{
if ((pDib==NULL)||(x<0)||(y<0)||
(x>=head.biWidth)||(y>=head.biHeight)) return;
int a0 = (int)(256*blend);
int a1 = 256 - a0;
RGBQUAD c0 = BlindGetPixelColor(x,y);
c.rgbRed = (BYTE)((c.rgbRed * a0 + c0.rgbRed * a1)>>8);
c.rgbBlue = (BYTE)((c.rgbBlue * a0 + c0.rgbBlue * a1)>>8);
c.rgbGreen = (BYTE)((c.rgbGreen * a0 + c0.rgbGreen * a1)>>8);
if (head.biClrUsed)
BlindSetPixelIndex(x,y,GetNearestIndex(c));
else {
BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3;
*iDst++ = c.rgbBlue;
*iDst++ = c.rgbGreen;
*iDst = c.rgbRed;
#if CXIMAGE_SUPPORT_ALPHA
if (bSetAlpha) AlphaSet(x,y,c.rgbReserved);
#endif //CXIMAGE_SUPPORT_ALPHA
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns the best palette index that matches a specified color.
*/
BYTE CxImage::GetNearestIndex(RGBQUAD c)
{
if ((pDib==NULL)||(head.biClrUsed==0)) return 0;
// <RJ> check matching with the previous result
if (info.last_c_isvalid && (*(long*)&info.last_c == *(long*)&c)) return info.last_c_index;
info.last_c = c;
info.last_c_isvalid = true;
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
long distance=200000;
int i,j = 0;
long k,l;
int m = (int)(head.biClrImportant==0 ? head.biClrUsed : head.biClrImportant);
for(i=0,l=0;i<m;i++,l+=sizeof(RGBQUAD)){
k = (iDst[l]-c.rgbBlue)*(iDst[l]-c.rgbBlue)+
(iDst[l+1]-c.rgbGreen)*(iDst[l+1]-c.rgbGreen)+
(iDst[l+2]-c.rgbRed)*(iDst[l+2]-c.rgbRed);
// k = abs(iDst[l]-c.rgbBlue)+abs(iDst[l+1]-c.rgbGreen)+abs(iDst[l+2]-c.rgbRed);
if (k==0){
j=i;
break;
}
if (k<distance){
distance=k;
j=i;
}
}
info.last_c_index = (BYTE)j;
return (BYTE)j;
}
////////////////////////////////////////////////////////////////////////////////
/**
* swaps the blue and red components (for RGB images)
* \param buffer : pointer to the pixels
* \param length : number of bytes to swap. lenght may not exceed the scan line.
*/
void CxImage::RGBtoBGR(BYTE *buffer, int length)
{
if (buffer && (head.biClrUsed==0)){
BYTE temp;
length = min(length,(int)info.dwEffWidth);
length = min(length,(int)(3*head.biWidth));
for (int i=0;i<length;i+=3){
temp = buffer[i]; buffer[i] = buffer[i+2]; buffer[i+2] = temp;
}
}
}
////////////////////////////////////////////////////////////////////////////////
RGBQUAD CxImage::RGBtoRGBQUAD(COLORREF cr)
{
RGBQUAD c;
c.rgbRed = GetRValue(cr); /* get R, G, and B out of DWORD */
c.rgbGreen = GetGValue(cr);
c.rgbBlue = GetBValue(cr);
c.rgbReserved=0;
return c;
}
////////////////////////////////////////////////////////////////////////////////
COLORREF CxImage::RGBQUADtoRGB (RGBQUAD c)
{
return RGB(c.rgbRed,c.rgbGreen,c.rgbBlue);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns the color of the specified index.
* \param i = palette index
* \param r, g, b = output color channels
*/
bool CxImage::GetPaletteColor(BYTE i, BYTE* r, BYTE* g, BYTE* b)
{
RGBQUAD* ppal=GetPalette();
if (ppal) {
*r = ppal[i].rgbRed;
*g = ppal[i].rgbGreen;
*b = ppal[i].rgbBlue;
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPalette(DWORD n, BYTE *r, BYTE *g, BYTE *b)
{
if ((!r)||(pDib==NULL)||(head.biClrUsed==0)) return;
if (!g) g = r;
if (!b) b = g;
RGBQUAD* ppal=GetPalette();
DWORD m=min(n,head.biClrUsed);
for (DWORD i=0; i<m;i++){
ppal[i].rgbRed=r[i];
ppal[i].rgbGreen=g[i];
ppal[i].rgbBlue=b[i];
}
info.last_c_isvalid = false;
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPalette(rgb_color *rgb,DWORD nColors)
{
if ((!rgb)||(pDib==NULL)||(head.biClrUsed==0)) return;
RGBQUAD* ppal=GetPalette();
DWORD m=min(nColors,head.biClrUsed);
for (DWORD i=0; i<m;i++){
ppal[i].rgbRed=rgb[i].r;
ppal[i].rgbGreen=rgb[i].g;
ppal[i].rgbBlue=rgb[i].b;
}
info.last_c_isvalid = false;
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPalette(RGBQUAD* pPal,DWORD nColors)
{
if ((pPal==NULL)||(pDib==NULL)||(head.biClrUsed==0)) return;
memcpy(GetPalette(),pPal,min(GetPaletteSize(),nColors*sizeof(RGBQUAD)));
info.last_c_isvalid = false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets (or replaces) the palette to gray scale palette.
* The function doesn't change the pixels; for standard
* gray scale conversion use GrayScale().
*/
void CxImage::SetGrayPalette()
{
if ((pDib==NULL)||(head.biClrUsed==0)) return;
RGBQUAD* pal=GetPalette();
for (DWORD ni=0;ni<head.biClrUsed;ni++)
pal[ni].rgbBlue=pal[ni].rgbGreen = pal[ni].rgbRed = (BYTE)(ni*(255/(head.biClrUsed-1)));
}
////////////////////////////////////////////////////////////////////////////////
/**
* Colorize the palette.
* \sa Colorize
*/
void CxImage::BlendPalette(COLORREF cr,long perc)
{
if ((pDib==NULL)||(head.biClrUsed==0)) return;
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
DWORD i,r,g,b;
RGBQUAD* pPal=(RGBQUAD*)iDst;
r = GetRValue(cr);
g = GetGValue(cr);
b = GetBValue(cr);
if (perc>100) perc=100;
for(i=0;i<head.biClrUsed;i++){
pPal[i].rgbBlue=(BYTE)((pPal[i].rgbBlue*(100-perc)+b*perc)/100);
pPal[i].rgbGreen =(BYTE)((pPal[i].rgbGreen*(100-perc)+g*perc)/100);
pPal[i].rgbRed =(BYTE)((pPal[i].rgbRed*(100-perc)+r*perc)/100);
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns true if the image has 256 colors and a linear grey scale palette.
*/
bool CxImage::IsGrayScale()
{
RGBQUAD* ppal=GetPalette();
if(!(pDib && ppal && head.biClrUsed)) return false;
for(DWORD i=0;i<head.biClrUsed;i++){
if (ppal[i].rgbBlue!=i || ppal[i].rgbGreen!=i || ppal[i].rgbRed!=i) return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* swap two indexes in the image and their colors in the palette
*/
void CxImage::SwapIndex(BYTE idx1, BYTE idx2)
{
RGBQUAD* ppal=GetPalette();
if(!(pDib && ppal)) return;
//swap the colors
RGBQUAD tempRGB=GetPaletteColor(idx1);
SetPaletteColor(idx1,GetPaletteColor(idx2));
SetPaletteColor(idx2,tempRGB);
//swap the pixels
BYTE idx;
for(long y=0; y < head.biHeight; y++){
for(long x=0; x < head.biWidth; x++){
idx=BlindGetPixelIndex(x,y);
if (idx==idx1) BlindSetPixelIndex(x,y,idx2);
if (idx==idx2) BlindSetPixelIndex(x,y,idx1);
}
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* swap Red and Blue colors
*/
void CxImage::SwapRGB2BGR()
{
if (!pDib) return;
if (head.biClrUsed){
RGBQUAD* ppal=GetPalette();
BYTE b;
if(!ppal) return;
for(WORD a=0;a<head.biClrUsed;a++){
b=ppal[a].rgbBlue; ppal[a].rgbBlue=ppal[a].rgbRed; ppal[a].rgbRed=b;
}
} else {
for(long y=0;y<head.biHeight;y++){
RGBtoBGR(GetBits(y),3*head.biWidth);
}
}
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::IsTransparent(long x, long y)
{
if (!pDib) return false;
if (info.nBkgndIndex>=0){
if (head.biClrUsed){
if (GetPixelIndex(x,y) == info.nBkgndIndex) return true;
} else {
RGBQUAD ct = info.nBkgndColor;
RGBQUAD c = GetPixelColor(x,y,false);
if (*(long*)&c==*(long*)&ct) return true;
}
}
#if CXIMAGE_SUPPORT_ALPHA
if (pAlpha) return AlphaGet(x,y)==0;
#endif
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::GetTransparentMask(CxImage* iDst)
{
if (!pDib) return false;
CxImage tmp;
tmp.Create(head.biWidth, head.biHeight, 1, GetType());
tmp.SetStdPalette();
tmp.Clear(0);
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
if (IsTransparent(x,y)){
tmp.BlindSetPixelIndex(x,y,1);
}
}
}
if (iDst) iDst->Transfer(tmp);
else Transfer(tmp);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Checks if image has the same palette, if any.
* \param img = image to compare.
* \param bCheckAlpha = check also the rgbReserved field.
*/
bool CxImage::IsSamePalette(CxImage &img, bool bCheckAlpha)
{
if (head.biClrUsed != img.head.biClrUsed)
return false;
if (head.biClrUsed == 0)
return false;
RGBQUAD c1,c2;
for (DWORD n=0; n<head.biClrUsed; n++){
c1 = GetPaletteColor((BYTE)n);
c2 = img.GetPaletteColor((BYTE)n);
if (c1.rgbRed != c2.rgbRed) return false;
if (c1.rgbBlue != c2.rgbBlue) return false;
if (c1.rgbGreen != c2.rgbGreen) return false;
if (bCheckAlpha && (c1.rgbReserved != c2.rgbReserved)) return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \sa SetClrImportant
*/
DWORD CxImage::GetClrImportant() const
{
return head.biClrImportant;
}
////////////////////////////////////////////////////////////////////////////////
/**
* sets the maximum number of colors that some functions like
* DecreaseBpp() or GetNearestIndex() will use on indexed images
* \param ncolors should be less than 2^bpp,
* or 0 if all the colors are important.
*/
void CxImage::SetClrImportant(DWORD ncolors)
{
if (ncolors==0 || ncolors>256) {
head.biClrImportant = 0;
return;
}
switch(head.biBitCount){
case 1:
head.biClrImportant = min(ncolors,2);
break;
case 4:
head.biClrImportant = min(ncolors,16);
break;
case 8:
head.biClrImportant = ncolors;
break;
}
return;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns pointer to pixel. Currently implemented only for truecolor images.
*
* \param x,y - coordinates
*
* \return pointer to first byte of pixel data
*
* \author ***bd*** 2.2004
*/
void* CxImage::BlindGetPixelPointer(const long x, const long y)
{
#ifdef _DEBUG
if ((pDib==NULL) || !IsInside(x,y))
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
throw 0;
#else
return 0;
#endif
#endif
if (!IsIndexed())
return info.pImage + y*info.dwEffWidth + x*3;
else
return 0;
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::DrawLine(int StartX, int EndX, int StartY, int EndY, COLORREF cr)
{
DrawLine(StartX, EndX, StartY, EndY, RGBtoRGBQUAD(cr));
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::DrawLine(int StartX, int EndX, int StartY, int EndY, RGBQUAD color, bool bSetAlpha)
{
if (!pDib) return;
//////////////////////////////////////////////////////
// Draws a line using the Bresenham line algorithm
// Thanks to Jordan DeLozier <JDL>
//////////////////////////////////////////////////////
int x1 = StartX;
int y1 = StartY;
int x = x1; // Start x off at the first pixel
int y = y1; // Start y off at the first pixel
int x2 = EndX;
int y2 = EndY;
int xinc1,xinc2,yinc1,yinc2; // Increasing values
int den, num, numadd,numpixels;
int deltax = abs(x2 - x1); // The difference between the x's
int deltay = abs(y2 - y1); // The difference between the y's
// Get Increasing Values
if (x2 >= x1) { // The x-values are increasing
xinc1 = 1;
xinc2 = 1;
} else { // The x-values are decreasing
xinc1 = -1;
xinc2 = -1;
}
if (y2 >= y1) { // The y-values are increasing
yinc1 = 1;
yinc2 = 1;
} else { // The y-values are decreasing
yinc1 = -1;
yinc2 = -1;
}
// Actually draw the line
if (deltax >= deltay) // There is at least one x-value for every y-value
{
xinc1 = 0; // Don't change the x when numerator >= denominator
yinc2 = 0; // Don't change the y for every iteration
den = deltax;
num = deltax / 2;
numadd = deltay;
numpixels = deltax; // There are more x-values than y-values
}
else // There is at least one y-value for every x-value
{
xinc2 = 0; // Don't change the x for every iteration
yinc1 = 0; // Don't change the y when numerator >= denominator
den = deltay;
num = deltay / 2;
numadd = deltax;
numpixels = deltay; // There are more y-values than x-values
}
for (int curpixel = 0; curpixel <= numpixels; curpixel++)
{
// Draw the current pixel
SetPixelColor(x,y,color,bSetAlpha);
num += numadd; // Increase the numerator by the top of the fraction
if (num >= den) // Check if numerator >= denominator
{
num -= den; // Calculate the new numerator value
x += xinc1; // Change the x as appropriate
y += yinc1; // Change the y as appropriate
}
x += xinc2; // Change the x as appropriate
y += yinc2; // Change the y as appropriate
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets a palette with standard colors for 1, 4 and 8 bpp images.
*/
void CxImage::SetStdPalette()
{
if (!pDib) return;
switch (head.biBitCount){
case 8:
{
const BYTE pal256[1024] = {0,0,0,0,0,0,128,0,0,128,0,0,0,128,128,0,128,0,0,0,128,0,128,0,128,128,0,0,192,192,192,0,
192,220,192,0,240,202,166,0,212,240,255,0,177,226,255,0,142,212,255,0,107,198,255,0,
72,184,255,0,37,170,255,0,0,170,255,0,0,146,220,0,0,122,185,0,0,98,150,0,0,74,115,0,0,
50,80,0,212,227,255,0,177,199,255,0,142,171,255,0,107,143,255,0,72,115,255,0,37,87,255,0,0,
85,255,0,0,73,220,0,0,61,185,0,0,49,150,0,0,37,115,0,0,25,80,0,212,212,255,0,177,177,255,0,
142,142,255,0,107,107,255,0,72,72,255,0,37,37,255,0,0,0,254,0,0,0,220,0,0,0,185,0,0,0,150,0,
0,0,115,0,0,0,80,0,227,212,255,0,199,177,255,0,171,142,255,0,143,107,255,0,115,72,255,0,
87,37,255,0,85,0,255,0,73,0,220,0,61,0,185,0,49,0,150,0,37,0,115,0,25,0,80,0,240,212,255,0,
226,177,255,0,212,142,255,0,198,107,255,0,184,72,255,0,170,37,255,0,170,0,255,0,146,0,220,0,
122,0,185,0,98,0,150,0,74,0,115,0,50,0,80,0,255,212,255,0,255,177,255,0,255,142,255,0,255,107,255,0,
255,72,255,0,255,37,255,0,254,0,254,0,220,0,220,0,185,0,185,0,150,0,150,0,115,0,115,0,80,0,80,0,
255,212,240,0,255,177,226,0,255,142,212,0,255,107,198,0,255,72,184,0,255,37,170,0,255,0,170,0,
220,0,146,0,185,0,122,0,150,0,98,0,115,0,74,0,80,0,50,0,255,212,227,0,255,177,199,0,255,142,171,0,
255,107,143,0,255,72,115,0,255,37,87,0,255,0,85,0,220,0,73,0,185,0,61,0,150,0,49,0,115,0,37,0,
80,0,25,0,255,212,212,0,255,177,177,0,255,142,142,0,255,107,107,0,255,72,72,0,255,37,37,0,254,0,
0,0,220,0,0,0,185,0,0,0,150,0,0,0,115,0,0,0,80,0,0,0,255,227,212,0,255,199,177,0,255,171,142,0,
255,143,107,0,255,115,72,0,255,87,37,0,255,85,0,0,220,73,0,0,185,61,0,0,150,49,0,0,115,37,0,
0,80,25,0,0,255,240,212,0,255,226,177,0,255,212,142,0,255,198,107,0,255,184,72,0,255,170,37,0,
255,170,0,0,220,146,0,0,185,122,0,0,150,98,0,0,115,74,0,0,80,50,0,0,255,255,212,0,255,255,177,0,
255,255,142,0,255,255,107,0,255,255,72,0,255,255,37,0,254,254,0,0,220,220,0,0,185,185,0,0,150,150,0,
0,115,115,0,0,80,80,0,0,240,255,212,0,226,255,177,0,212,255,142,0,198,255,107,0,184,255,72,0,
170,255,37,0,170,255,0,0,146,220,0,0,122,185,0,0,98,150,0,0,74,115,0,0,50,80,0,0,227,255,212,0,
199,255,177,0,171,255,142,0,143,255,107,0,115,255,72,0,87,255,37,0,85,255,0,0,73,220,0,0,61,185,0,
0,49,150,0,0,37,115,0,0,25,80,0,0,212,255,212,0,177,255,177,0,142,255,142,0,107,255,107,0,72,255,72,0,
37,255,37,0,0,254,0,0,0,220,0,0,0,185,0,0,0,150,0,0,0,115,0,0,0,80,0,0,212,255,227,0,177,255,199,0,
142,255,171,0,107,255,143,0,72,255,115,0,37,255,87,0,0,255,85,0,0,220,73,0,0,185,61,0,0,150,49,0,0,
115,37,0,0,80,25,0,212,255,240,0,177,255,226,0,142,255,212,0,107,255,198,0,72,255,184,0,37,255,170,0,
0,255,170,0,0,220,146,0,0,185,122,0,0,150,98,0,0,115,74,0,0,80,50,0,212,255,255,0,177,255,255,0,
142,255,255,0,107,255,255,0,72,255,255,0,37,255,255,0,0,254,254,0,0,220,220,0,0,185,185,0,0,
150,150,0,0,115,115,0,0,80,80,0,242,242,242,0,230,230,230,0,218,218,218,0,206,206,206,0,194,194,194,0,
182,182,182,0,170,170,170,0,158,158,158,0,146,146,146,0,134,134,134,0,122,122,122,0,110,110,110,0,
98,98,98,0,86,86,86,0,74,74,74,0,62,62,62,0,50,50,50,0,38,38,38,0,26,26,26,0,14,14,14,0,240,251,255,0,
164,160,160,0,128,128,128,0,0,0,255,0,0,255,0,0,0,255,255,0,255,0,0,0,255,0,255,0,255,255,0,0,255,255,255,0};
memcpy(GetPalette(),pal256,1024);
break;
}
case 4:
{
const BYTE pal16[64]={0,0,0,0,0,0,128,0,0,128,0,0,0,128,128,0,128,0,0,0,128,0,128,0,128,128,0,0,192,192,192,0,
128,128,128,0,0,0,255,0,0,255,0,0,0,255,255,0,255,0,0,0,255,0,255,0,255,255,0,0,255,255,255,0};
memcpy(GetPalette(),pal16,64);
break;
}
case 1:
{
const BYTE pal2[8]={0,0,0,0,255,255,255,0};
memcpy(GetPalette(),pal2,8);
break;
}
}
info.last_c_isvalid = false;
return;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,479 +0,0 @@
/*
* File: ximapcx.cpp
* Purpose: Platform Independent PCX Image Class Loader and Writer
* 05/Jan/2002 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*
* based on ppmtopcx.c - convert a portable pixmap to PCX
* Copyright (C) 1994 by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
* based on ppmtopcx.c by Michael Davidson
*/
#include "ximapcx.h"
#if CXIMAGE_SUPPORT_PCX
#include "xmemfile.h"
#define PCX_MAGIC 0X0A // PCX magic number
#define PCX_256_COLORS 0X0C // magic number for 256 colors
#define PCX_HDR_SIZE 128 // size of PCX header
#define PCX_MAXCOLORS 256
#define PCX_MAXPLANES 4
#define PCX_MAXVAL 255
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImagePCX::Decode(CxFile *hFile)
{
if (hFile == NULL) return false;
PCXHEADER pcxHeader;
int i, x, y, y2, nbytes, count, Height, Width;
BYTE c, ColorMap[PCX_MAXCOLORS][3];
BYTE *pcximage = NULL, *lpHead1 = NULL, *lpHead2 = NULL;
BYTE *pcxplanes, *pcxpixels;
cx_try
{
if (hFile->Read(&pcxHeader,sizeof(PCXHEADER),1)==0) cx_throw("Can't read PCX image");
PCX_toh(&pcxHeader);
if (pcxHeader.Manufacturer != PCX_MAGIC) cx_throw("Error: Not a PCX file");
// Check for PCX run length encoding
if (pcxHeader.Encoding != 1) cx_throw("PCX file has unknown encoding scheme");
Width = (pcxHeader.Xmax - pcxHeader.Xmin) + 1;
Height = (pcxHeader.Ymax - pcxHeader.Ymin) + 1;
info.xDPI = pcxHeader.Hres;
info.yDPI = pcxHeader.Vres;
if (info.nEscape == -1){
head.biWidth = Width;
head.biHeight= Height;
info.dwType = CXIMAGE_FORMAT_PCX;
return true;
}
// Check that we can handle this image format
if (pcxHeader.ColorPlanes > 4)
cx_throw("Can't handle image with more than 4 planes");
// Create the image
if (pcxHeader.ColorPlanes >= 3 && pcxHeader.BitsPerPixel == 8){
Create (Width, Height, 24, CXIMAGE_FORMAT_PCX);
#if CXIMAGE_SUPPORT_ALPHA
if (pcxHeader.ColorPlanes==4) AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA
} else if (pcxHeader.ColorPlanes == 4 && pcxHeader.BitsPerPixel == 1)
Create (Width, Height, 4, CXIMAGE_FORMAT_PCX);
else
Create (Width, Height, pcxHeader.BitsPerPixel, CXIMAGE_FORMAT_PCX);
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
//Read the image and check if it's ok
nbytes = pcxHeader.BytesPerLine * pcxHeader.ColorPlanes * Height;
lpHead1 = pcximage = (BYTE*)malloc(nbytes);
while (nbytes > 0){
if (hFile == NULL || hFile->Eof()) cx_throw("corrupted PCX");
hFile->Read(&c,1,1);
if ((c & 0XC0) != 0XC0){ // Repeated group
*pcximage++ = c;
--nbytes;
continue;
}
count = c & 0X3F; // extract count
hFile->Read(&c,1,1);
if (count > nbytes) cx_throw("repeat count spans end of image");
nbytes -= count;
while (--count >=0) *pcximage++ = c;
}
pcximage = lpHead1;
//store the palette
for (i = 0; i < 16; i++){
ColorMap[i][0] = pcxHeader.ColorMap[i][0];
ColorMap[i][1] = pcxHeader.ColorMap[i][1];
ColorMap[i][2] = pcxHeader.ColorMap[i][2];
}
if (pcxHeader.BitsPerPixel == 8 && pcxHeader.ColorPlanes == 1){
hFile->Read(&c,1,1);
if (c != PCX_256_COLORS) cx_throw("bad color map signature");
for (i = 0; i < PCX_MAXCOLORS; i++){
hFile->Read(&ColorMap[i][0],1,1);
hFile->Read(&ColorMap[i][1],1,1);
hFile->Read(&ColorMap[i][2],1,1);
}
}
if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 1){
ColorMap[0][0] = ColorMap[0][1] = ColorMap[0][2] = 0;
ColorMap[1][0] = ColorMap[1][1] = ColorMap[1][2] = 255;
}
for (DWORD idx=0; idx<head.biClrUsed; idx++) SetPaletteColor((BYTE)idx,ColorMap[idx][0],ColorMap[idx][1],ColorMap[idx][2]);
lpHead2 = pcxpixels = (BYTE *)malloc(Width + pcxHeader.BytesPerLine * 8);
// Convert the image
for (y = 0; y < Height; y++){
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
y2=Height-1-y;
pcxpixels = lpHead2;
pcxplanes = pcximage + (y * pcxHeader.BytesPerLine * pcxHeader.ColorPlanes);
if (pcxHeader.ColorPlanes == 3 && pcxHeader.BitsPerPixel == 8){
// Deal with 24 bit color image
for (x = 0; x < Width; x++){
SetPixelColor(x,y2,RGB(pcxplanes[x],pcxplanes[pcxHeader.BytesPerLine + x],pcxplanes[2*pcxHeader.BytesPerLine + x]));
}
continue;
#if CXIMAGE_SUPPORT_ALPHA
} else if (pcxHeader.ColorPlanes == 4 && pcxHeader.BitsPerPixel == 8){
for (x = 0; x < Width; x++){
SetPixelColor(x,y2,RGB(pcxplanes[x],pcxplanes[pcxHeader.BytesPerLine + x],pcxplanes[2*pcxHeader.BytesPerLine + x]));
AlphaSet(x,y2,pcxplanes[3*pcxHeader.BytesPerLine + x]);
}
continue;
#endif //CXIMAGE_SUPPORT_ALPHA
} else if (pcxHeader.ColorPlanes == 1) {
if (!PCX_UnpackPixels(pcxpixels, pcxplanes, pcxHeader.BytesPerLine, pcxHeader.ColorPlanes, pcxHeader.BitsPerPixel)){
cx_throw("PCX_UnpackPixels: Can't handle packed pixels with more than 1 plane");
}
} else {
if (!PCX_PlanesToPixels(pcxpixels, pcxplanes, pcxHeader.BytesPerLine, pcxHeader.ColorPlanes, pcxHeader.BitsPerPixel)){
cx_throw("PCX_PlanesToPixels: more than 4 planes or more than 1 bit per pixel");
}
}
for (x = 0; x < Width; x++) SetPixelIndex(x,y2,pcxpixels[x]);
}
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
if (lpHead1){ free(lpHead1); lpHead1 = NULL; }
if (lpHead2){ free(lpHead2); lpHead2 = NULL; }
return false;
}
if (lpHead1){ free(lpHead1); lpHead1 = NULL; }
if (lpHead2){ free(lpHead2); lpHead2 = NULL; }
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImagePCX::Encode(CxFile * hFile)
{
if (EncodeSafeCheck(hFile)) return false;
cx_try
{
PCXHEADER pcxHeader;
memset(&pcxHeader,0,sizeof(pcxHeader));
pcxHeader.Manufacturer = PCX_MAGIC;
pcxHeader.Version = 5;
pcxHeader.Encoding = 1;
pcxHeader.Xmin = 0;
pcxHeader.Ymin = 0;
pcxHeader.Xmax = (WORD)head.biWidth-1;
pcxHeader.Ymax = (WORD)head.biHeight-1;
pcxHeader.Hres = (WORD)info.xDPI;
pcxHeader.Vres = (WORD)info.yDPI;
pcxHeader.Reserved = 0;
pcxHeader.PaletteType = head.biClrUsed==0;
switch(head.biBitCount){
case 24:
case 8:
{
pcxHeader.BitsPerPixel = 8;
pcxHeader.ColorPlanes = head.biClrUsed==0 ? 3 : 1;
#if CXIMAGE_SUPPORT_ALPHA
if (AlphaIsValid() && head.biClrUsed==0) pcxHeader.ColorPlanes =4;
#endif //CXIMAGE_SUPPORT_ALPHA
pcxHeader.BytesPerLine = (WORD)head.biWidth;
break;
}
default: //(4 1)
pcxHeader.BitsPerPixel = 1;
pcxHeader.ColorPlanes = head.biClrUsed==16 ? 4 : 1;
pcxHeader.BytesPerLine = (WORD)((head.biWidth * pcxHeader.BitsPerPixel + 7)>>3);
}
if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 1){
pcxHeader.ColorMap[0][0] = pcxHeader.ColorMap[0][1] = pcxHeader.ColorMap[0][2] = 0;
pcxHeader.ColorMap[1][0] = pcxHeader.ColorMap[1][1] = pcxHeader.ColorMap[1][2] = 255;
}
if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 4){
RGBQUAD c;
for (int i = 0; i < 16; i++){
c=GetPaletteColor(i);
pcxHeader.ColorMap[i][0] = c.rgbRed;
pcxHeader.ColorMap[i][1] = c.rgbGreen;
pcxHeader.ColorMap[i][2] = c.rgbBlue;
}
}
pcxHeader.BytesPerLine = (pcxHeader.BytesPerLine + 1)&(~1);
PCX_toh(&pcxHeader);
if (hFile->Write(&pcxHeader, sizeof(pcxHeader), 1) == 0 )
cx_throw("cannot write PCX header");
PCX_toh(&pcxHeader);
CxMemFile buffer;
buffer.Open();
BYTE c,n;
long x,y;
if (head.biClrUsed==0){
for (y = head.biHeight-1; y >=0 ; y--){
for (int p=0; p<pcxHeader.ColorPlanes; p++){
c=n=0;
for (x = 0; x<head.biWidth; x++){
if (p==0)
PCX_PackPixels(BlindGetPixelColor(x,y).rgbRed,c,n,buffer);
else if (p==1)
PCX_PackPixels(BlindGetPixelColor(x,y).rgbGreen,c,n,buffer);
else if (p==2)
PCX_PackPixels(BlindGetPixelColor(x,y).rgbBlue,c,n,buffer);
#if CXIMAGE_SUPPORT_ALPHA
else if (p==3)
PCX_PackPixels(BlindAlphaGet(x,y),c,n,buffer);
#endif //CXIMAGE_SUPPORT_ALPHA
}
PCX_PackPixels(-1-(head.biWidth&0x1),c,n,buffer);
}
}
hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);
} else if (head.biBitCount==8) {
for (y = head.biHeight-1; y >=0 ; y--){
c=n=0;
for (x = 0; x<head.biWidth; x++){
PCX_PackPixels(GetPixelIndex(x,y),c,n,buffer);
}
PCX_PackPixels(-1-(head.biWidth&0x1),c,n,buffer);
}
hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);
if (head.biBitCount == 8){
hFile->PutC(0x0C);
BYTE* pal = (BYTE*)malloc(768);
RGBQUAD c;
for (int i=0;i<256;i++){
c=GetPaletteColor(i);
pal[3*i+0] = c.rgbRed;
pal[3*i+1] = c.rgbGreen;
pal[3*i+2] = c.rgbBlue;
}
hFile->Write(pal,768,1);
free(pal);
}
} else { //(head.biBitCount==4) || (head.biBitCount==1)
RGBQUAD *rgb = GetPalette();
bool binvert = false;
if (CompareColors(&rgb[0],&rgb[1])>0) binvert=(head.biBitCount==1);
BYTE* plane = (BYTE*)malloc(pcxHeader.BytesPerLine);
BYTE* raw = (BYTE*)malloc(head.biWidth);
for(y = head.biHeight-1; y >=0 ; y--) {
for( x = 0; x < head.biWidth; x++) raw[x] = (BYTE)GetPixelIndex(x,y);
if (binvert) for( x = 0; x < head.biWidth; x++) raw[x] = 1-raw[x];
for( x = 0; x < pcxHeader.ColorPlanes; x++ ) {
PCX_PixelsToPlanes(raw, head.biWidth, plane, x);
PCX_PackPlanes(plane, pcxHeader.BytesPerLine, buffer);
}
}
free(plane);
free(raw);
hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);
}
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
// Convert multi-plane format into 1 pixel per byte
// from unpacked file data bitplanes[] into pixel row pixels[]
// image Height rows, with each row having planes image planes each
// bytesperline bytes
bool CxImagePCX::PCX_PlanesToPixels(BYTE * pixels, BYTE * bitplanes, short bytesperline, short planes, short bitsperpixel)
{
int i, j, npixels;
BYTE * p;
if (planes > 4) return false;
if (bitsperpixel != 1) return false;
// Clear the pixel buffer
npixels = (bytesperline * 8) / bitsperpixel;
p = pixels;
while (--npixels >= 0) *p++ = 0;
// Do the format conversion
for (i = 0; i < planes; i++){
int pixbit, bits, mask;
p = pixels;
pixbit = (1 << i); // pixel bit for this plane
for (j = 0; j < bytesperline; j++){
bits = *bitplanes++;
for (mask = 0X80; mask != 0; mask >>= 1, p++)
if (bits & mask) *p |= pixbit;
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// convert packed pixel format into 1 pixel per byte
// from unpacked file data bitplanes[] into pixel row pixels[]
// image Height rows, with each row having planes image planes each
// bytesperline bytes
bool CxImagePCX::PCX_UnpackPixels(BYTE * pixels, BYTE * bitplanes, short bytesperline, short planes, short bitsperpixel)
{
register int bits;
if (planes != 1) return false;
if (bitsperpixel == 8){ // 8 bits/pixels, no unpacking needed
while (bytesperline-- > 0) *pixels++ = *bitplanes++;
} else if (bitsperpixel == 4){ // 4 bits/pixel, two pixels per byte
while (bytesperline-- > 0){
bits = *bitplanes++;
*pixels++ = (BYTE)((bits >> 4) & 0X0F);
*pixels++ = (BYTE)((bits) & 0X0F);
}
} else if (bitsperpixel == 2){ // 2 bits/pixel, four pixels per byte
while (bytesperline-- > 0){
bits = *bitplanes++;
*pixels++ = (BYTE)((bits >> 6) & 0X03);
*pixels++ = (BYTE)((bits >> 4) & 0X03);
*pixels++ = (BYTE)((bits >> 2) & 0X03);
*pixels++ = (BYTE)((bits) & 0X03);
}
} else if (bitsperpixel == 1){ // 1 bits/pixel, 8 pixels per byte
while (bytesperline-- > 0){
bits = *bitplanes++;
*pixels++ = ((bits & 0X80) != 0);
*pixels++ = ((bits & 0X40) != 0);
*pixels++ = ((bits & 0X20) != 0);
*pixels++ = ((bits & 0X10) != 0);
*pixels++ = ((bits & 0X08) != 0);
*pixels++ = ((bits & 0X04) != 0);
*pixels++ = ((bits & 0X02) != 0);
*pixels++ = ((bits & 0X01) != 0);
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/* PCX_PackPixels(const long p,BYTE &c, BYTE &n, long &l, CxFile &f)
* p = current pixel (-1 ends the line -2 ends odd line)
* c = previous pixel
* n = number of consecutive pixels
*/
void CxImagePCX::PCX_PackPixels(const long p,BYTE &c, BYTE &n, CxFile &f)
{
if (p!=c && n){
if (n==1 && c<0xC0){
f.PutC(c);
} else {
f.PutC(0xC0|n);
f.PutC(c);
}
n=0;
}
if (n==0x3F) {
f.PutC(0xFF);
f.PutC(c);
n=0;
}
if (p==-2) f.PutC(0);
c=(BYTE)p;
n++;
}
////////////////////////////////////////////////////////////////////////////////
void CxImagePCX::PCX_PackPlanes(BYTE* buff, const long size, CxFile &f)
{
BYTE *start,*end;
BYTE c, previous, count;
start = buff;
end = buff + size;
previous = *start++;
count = 1;
while (start < end) {
c = *start++;
if (c == previous && count < 63) {
++count;
continue;
}
if (count > 1 || (previous & 0xc0) == 0xc0) {
f.PutC( count | 0xc0 );
}
f.PutC(previous);
previous = c;
count = 1;
}
if (count > 1 || (previous & 0xc0) == 0xc0) {
count |= 0xc0;
f.PutC(count);
}
f.PutC(previous);
}
////////////////////////////////////////////////////////////////////////////////
void CxImagePCX::PCX_PixelsToPlanes(BYTE* raw, long width, BYTE* buf, long plane)
{
int cbit, x, mask;
unsigned char *cp = buf-1;
mask = 1 << plane;
cbit = -1;
for( x = 0; x < width; x++ ) {
if( cbit < 0 ) {
cbit = 7;
*++cp = 0;
}
if( raw[x] & mask )
*cp |= (1<<cbit);
--cbit;
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImagePCX::PCX_toh(PCXHEADER* p)
{
p->Xmin = ntohs(p->Xmin);
p->Ymin = ntohs(p->Ymin);
p->Xmax = ntohs(p->Xmax);
p->Ymax = ntohs(p->Ymax);
p->Hres = ntohs(p->Hres);
p->Vres = ntohs(p->Vres);
p->BytesPerLine = ntohs(p->BytesPerLine);
p->PaletteType = ntohs(p->PaletteType);
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_PCX

View File

@@ -1,64 +0,0 @@
/*
* File: ximapcx.h
* Purpose: PCX Image Class Loader and Writer
*/
/* ==========================================================
* CxImagePCX (c) 05/Jan/2002 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
*
* Parts of the code come from Paintlib: Copyright (c) 1996-1998 Ulrich von Zadow
* ==========================================================
*/
#if !defined(__ximaPCX_h)
#define __ximaPCX_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_PCX
class CxImagePCX: public CxImage
{
// PCX Image File
#pragma pack(1)
typedef struct tagPCXHEADER
{
char Manufacturer; // always 0X0A
char Version; // version number
char Encoding; // always 1
char BitsPerPixel; // color bits
WORD Xmin, Ymin; // image origin
WORD Xmax, Ymax; // image dimensions
WORD Hres, Vres; // resolution values
BYTE ColorMap[16][3]; // color palette
char Reserved;
char ColorPlanes; // color planes
WORD BytesPerLine; // line buffer size
WORD PaletteType; // grey or color palette
char Filter[58];
} PCXHEADER;
#pragma pack()
public:
CxImagePCX(): CxImage(CXIMAGE_FORMAT_PCX) {}
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_PCX);}
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_PCX);}
bool Decode(CxFile * hFile);
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile);
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
#endif // CXIMAGE_SUPPORT_ENCODE
protected:
bool PCX_PlanesToPixels(BYTE * pixels, BYTE * bitplanes, short bytesperline, short planes, short bitsperpixel);
bool PCX_UnpackPixels(BYTE * pixels, BYTE * bitplanes, short bytesperline, short planes, short bitsperpixel);
void PCX_PackPixels(const long p,BYTE &c, BYTE &n, CxFile &f);
void PCX_PackPlanes(BYTE* buff, const long size, CxFile &f);
void PCX_PixelsToPlanes(BYTE* raw, long width, BYTE* buf, long plane);
void PCX_toh(PCXHEADER* p);
};
#endif
#endif

View File

@@ -1,536 +0,0 @@
/*
* File: ximapng.cpp
* Purpose: Platform Independent PNG Image Class Loader and Writer
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximapng.h"
#if CXIMAGE_SUPPORT_PNG
#include "ximaiter.h"
////////////////////////////////////////////////////////////////////////////////
void CxImagePNG::ima_png_error(png_struct *png_ptr, char *message)
{
strcpy(info.szLastError,message);
longjmp(png_ptr->jmpbuf, 1);
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
void CxImagePNG::expand2to4bpp(BYTE* prow)
{
BYTE *psrc,*pdst;
BYTE pos,idx;
for(long x=head.biWidth-1;x>=0;x--){
psrc = prow + ((2*x)>>3);
pdst = prow + ((4*x)>>3);
pos = (BYTE)(2*(3-x%4));
idx = (BYTE)((*psrc & (0x03<<pos))>>pos);
pos = (BYTE)(4*(1-x%2));
*pdst &= ~(0x0F<<pos);
*pdst |= (idx & 0x0F)<<pos;
}
}
////////////////////////////////////////////////////////////////////////////////
bool CxImagePNG::Decode(CxFile *hFile)
{
png_struct *png_ptr;
png_info *info_ptr;
BYTE *row_pointers=NULL;
CImageIterator iter(this);
cx_try
{
/* 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,(void *)NULL,NULL,NULL);
if (png_ptr == NULL) cx_throw("Failed to create PNG structure");
/* Allocate/initialize the memory for image information. REQUIRED. */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
cx_throw("Failed to initialize PNG info structure");
}
/* 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_ptr->jmpbuf)) {
/* Free all of the memory associated with the png_ptr and info_ptr */
delete [] row_pointers;
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
cx_throw("");
}
// use custom I/O functions
png_set_read_fn(png_ptr, hFile, /*(png_rw_ptr)*/user_read_data);
png_set_error_fn(png_ptr,info.szLastError,/*(png_error_ptr)*/user_error_fn,NULL);
/* read the file information */
png_read_info(png_ptr, info_ptr);
if (info.nEscape == -1){
head.biWidth = info_ptr->width;
head.biHeight= info_ptr->height;
info.dwType = CXIMAGE_FORMAT_PNG;
longjmp(png_ptr->jmpbuf, 1);
}
/* calculate new number of channels */
int channels=0;
switch(info_ptr->color_type){
case PNG_COLOR_TYPE_GRAY:
case PNG_COLOR_TYPE_PALETTE:
channels = 1;
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
channels = 2;
break;
case PNG_COLOR_TYPE_RGB:
channels = 3;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
channels = 4;
break;
default:
strcpy(info.szLastError,"unknown PNG color type");
longjmp(png_ptr->jmpbuf, 1);
}
//find the right pixel depth used for cximage
int pixel_depth = info_ptr->pixel_depth;
if (channels == 1 && pixel_depth>8) pixel_depth=8;
if (channels == 2) pixel_depth=8;
if (channels >= 3) pixel_depth=24;
if (!Create(info_ptr->width, info_ptr->height, pixel_depth, CXIMAGE_FORMAT_PNG)){
longjmp(png_ptr->jmpbuf, 1);
}
/* get metrics */
switch (info_ptr->phys_unit_type)
{
case PNG_RESOLUTION_UNKNOWN:
SetXDPI(info_ptr->x_pixels_per_unit);
SetYDPI(info_ptr->y_pixels_per_unit);
break;
case PNG_RESOLUTION_METER:
SetXDPI((long)floor(info_ptr->x_pixels_per_unit * 254.0 / 10000.0 + 0.5));
SetYDPI((long)floor(info_ptr->y_pixels_per_unit * 254.0 / 10000.0 + 0.5));
break;
}
if (info_ptr->num_palette>0){
SetPalette((rgb_color*)info_ptr->palette,info_ptr->num_palette);
SetClrImportant(info_ptr->num_palette);
} else if (info_ptr->bit_depth ==2) { //<DP> needed for 2 bpp grayscale PNGs
SetPaletteColor(0,0,0,0);
SetPaletteColor(1,85,85,85);
SetPaletteColor(2,170,170,170);
SetPaletteColor(3,255,255,255);
} else SetGrayPalette(); //<DP> needed for grayscale PNGs
int nshift = max(0,(info_ptr->bit_depth>>3)-1)<<3;
if (info_ptr->num_trans!=0){ //palette transparency
if (info_ptr->num_trans==1){
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE){
info.nBkgndIndex = info_ptr->trans_values.index;
} else{
info.nBkgndIndex = info_ptr->trans_values.gray>>nshift;
}
}
if (info_ptr->num_trans>1){
RGBQUAD* pal=GetPalette();
if (pal){
DWORD ip;
for (ip=0;ip<min(head.biClrUsed,(unsigned long)info_ptr->num_trans);ip++)
pal[ip].rgbReserved=info_ptr->trans[ip];
for (ip=info_ptr->num_trans;ip<head.biClrUsed;ip++){
pal[ip].rgbReserved=255;
}
info.bAlphaPaletteEnabled=true;
}
}
}
if (channels == 3){ //check RGB binary transparency
png_bytep trans;
int num_trans;
png_color_16 *image_background;
if (png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &image_background)){
info.nBkgndColor.rgbRed = (BYTE)(info_ptr->trans_values.red>>nshift);
info.nBkgndColor.rgbGreen = (BYTE)(info_ptr->trans_values.green>>nshift);
info.nBkgndColor.rgbBlue = (BYTE)(info_ptr->trans_values.blue>>nshift);
info.nBkgndColor.rgbReserved = 0;
info.nBkgndIndex = 0;
}
}
int alpha_present = (channels - 1) % 2;
if (alpha_present){
#if CXIMAGE_SUPPORT_ALPHA // <vho>
AlphaCreate();
#else
png_set_strip_alpha(png_ptr);
#endif //CXIMAGE_SUPPORT_ALPHA
}
// <vho> - flip the RGB pixels to BGR (or RGBA to BGRA)
if (info_ptr->color_type & PNG_COLOR_MASK_COLOR){
png_set_bgr(png_ptr);
}
// <vho> - handle cancel
if (info.nEscape) longjmp(png_ptr->jmpbuf, 1);
// row_bytes is the width x number of channels x (bit-depth / 8)
row_pointers = new BYTE[info_ptr->rowbytes + 8];
// turn on interlace handling
int number_passes = png_set_interlace_handling(png_ptr);
if (number_passes>1){
SetCodecOption(1);
} else {
SetCodecOption(0);
}
int chan_offset = info_ptr->bit_depth >> 3;
int pixel_offset = info_ptr->pixel_depth >> 3;
for (int pass=0; pass < number_passes; pass++) {
iter.Upset();
int y=0;
do {
// <vho> - handle cancel
if (info.nEscape) longjmp(png_ptr->jmpbuf, 1);
#if CXIMAGE_SUPPORT_ALPHA // <vho>
if (AlphaIsValid()) {
//compute the correct position of the line
long ax,ay;
ay = head.biHeight-1-y;
BYTE* prow= iter.GetRow(ay);
//recover data from previous scan
if (info_ptr->interlace_type && pass>0 && pass!=7){
for(ax=0;ax<head.biWidth;ax++){
long px = ax * pixel_offset;
if (channels == 2){
row_pointers[px] = prow[ax];
row_pointers[px+chan_offset]=AlphaGet(ax,ay);
} else {
long qx = ax * 3;
row_pointers[px] =prow[qx];
row_pointers[px+chan_offset] =prow[qx+1];
row_pointers[px+chan_offset*2]=prow[qx+2];
row_pointers[px+chan_offset*3]=AlphaGet(ax,ay);
}
}
}
//read next row
png_read_row(png_ptr, row_pointers, NULL);
//RGBA -> RGB + A
for(ax=0;ax<head.biWidth;ax++){
long px = ax * pixel_offset;
if (channels == 2){
prow[ax] = row_pointers[px];
AlphaSet(ax,ay,row_pointers[px+chan_offset]);
} else {
long qx = ax * 3;
prow[qx] =row_pointers[px];
prow[qx+1]=row_pointers[px+chan_offset];
prow[qx+2]=row_pointers[px+chan_offset*2];
AlphaSet(ax,ay,row_pointers[px+chan_offset*3]);
}
}
} else
#endif // CXIMAGE_SUPPORT_ALPHA // vho
{
//recover data from previous scan
if (info_ptr->interlace_type && pass>0){
iter.GetRow(row_pointers, info_ptr->rowbytes);
//re-expand buffer for images with bit depth > 8
if (info_ptr->bit_depth > 8){
for(long ax=(head.biWidth*channels-1);ax>=0;ax--)
row_pointers[ax*chan_offset] = row_pointers[ax];
}
}
//read next row
png_read_row(png_ptr, row_pointers, NULL);
//shrink 16 bit depth images down to 8 bits
if (info_ptr->bit_depth > 8){
for(long ax=0;ax<(head.biWidth*channels);ax++)
row_pointers[ax] = row_pointers[ax*chan_offset];
}
//copy the pixels
iter.SetRow(row_pointers, info_ptr->rowbytes);
//<DP> expand 2 bpp images only in the last pass
if (info_ptr->bit_depth==2 && pass==(number_passes-1))
expand2to4bpp(iter.GetRow());
//go on
iter.PrevRow();
}
y++;
} while(y<head.biHeight);
}
delete [] row_pointers;
/* read the rest of the file, getting any additional chunks in info_ptr */
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);
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_PNG) return true;
return false;
}
/* that's it */
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImagePNG::Encode(CxFile *hFile)
{
if (EncodeSafeCheck(hFile)) return false;
CImageIterator iter(this);
BYTE trans[256]; //for transparency (don't move)
png_struct *png_ptr;
png_info *info_ptr;
cx_try
{
/* 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,(void *)NULL,NULL,NULL);
if (png_ptr == NULL) cx_throw("Failed to create PNG structure");
/* Allocate/initialize the image information data. REQUIRED */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL){
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
cx_throw("Failed to initialize PNG info structure");
}
/* Set error handling. REQUIRED if you aren't supplying your own
* error hadnling functions in the png_create_write_struct() call.
*/
if (setjmp(png_ptr->jmpbuf)){
/* If we get here, we had a problem reading the file */
if (info_ptr->palette) free(info_ptr->palette);
png_destroy_write_struct(&png_ptr, (png_infopp)&info_ptr);
cx_throw("Error saving PNG file");
}
/* set up the output control */
//png_init_io(png_ptr, hFile);
// use custom I/O functions
png_set_write_fn(png_ptr,hFile,/*(png_rw_ptr)*/user_write_data,/*(png_flush_ptr)*/user_flush_data);
/* set the file information here */
info_ptr->width = GetWidth();
info_ptr->height = GetHeight();
info_ptr->pixel_depth = (BYTE)GetBpp();
info_ptr->channels = (GetBpp()>8) ? (BYTE)3: (BYTE)1;
info_ptr->bit_depth = (BYTE)(GetBpp()/info_ptr->channels);
info_ptr->compression_type = info_ptr->filter_type = 0;
info_ptr->valid = 0;
switch(GetCodecOption(CXIMAGE_FORMAT_PNG)){
case 1:
info_ptr->interlace_type = PNG_INTERLACE_ADAM7;
break;
default:
info_ptr->interlace_type = PNG_INTERLACE_NONE;
}
/* set compression level */
//png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
bool bGrayScale = IsGrayScale();
if (GetNumColors()){
if (bGrayScale){
info_ptr->color_type = PNG_COLOR_TYPE_GRAY;
} else {
info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
}
} else {
info_ptr->color_type = PNG_COLOR_TYPE_RGB;
}
#if CXIMAGE_SUPPORT_ALPHA
if (AlphaIsValid()){
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
info_ptr->channels++;
info_ptr->bit_depth = 8;
info_ptr->pixel_depth += 8;
}
#endif
/* set background */
png_color_16 image_background={ 0, 255, 255, 255, 0 };
RGBQUAD tc = GetTransColor();
if (info.nBkgndIndex>=0) {
image_background.blue = tc.rgbBlue;
image_background.green = tc.rgbGreen;
image_background.red = tc.rgbRed;
}
png_set_bKGD(png_ptr, info_ptr, &image_background);
/* set metrics */
png_set_pHYs(png_ptr, info_ptr, head.biXPelsPerMeter, head.biYPelsPerMeter, PNG_RESOLUTION_METER);
png_set_IHDR(png_ptr, info_ptr, info_ptr->width, info_ptr->height, info_ptr->bit_depth,
info_ptr->color_type, info_ptr->interlace_type,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
//<DP> simple transparency
if (info.nBkgndIndex >= 0){
info_ptr->num_trans = 1;
info_ptr->valid |= PNG_INFO_tRNS;
info_ptr->trans = trans;
info_ptr->trans_values.index = (BYTE)info.nBkgndIndex;
info_ptr->trans_values.red = tc.rgbRed;
info_ptr->trans_values.green = tc.rgbGreen;
info_ptr->trans_values.blue = tc.rgbBlue;
info_ptr->trans_values.gray = info_ptr->trans_values.index;
// the transparency indexes start from 0 for non grayscale palette
if (!bGrayScale && head.biClrUsed && info.nBkgndIndex)
SwapIndex(0,(BYTE)info.nBkgndIndex);
}
/* set the palette if there is one */
if (GetPalette()){
if (!bGrayScale){
info_ptr->valid |= PNG_INFO_PLTE;
}
int nc = GetClrImportant();
if (nc==0) nc = GetNumColors();
if (info.bAlphaPaletteEnabled){
for(WORD ip=0; ip<nc;ip++)
trans[ip]=GetPaletteColor((BYTE)ip).rgbReserved;
info_ptr->num_trans = (WORD)nc;
info_ptr->valid |= PNG_INFO_tRNS;
info_ptr->trans = trans;
}
// copy the palette colors
info_ptr->palette = new png_color[nc];
info_ptr->num_palette = (png_uint_16) nc;
for (int i=0; i<nc; i++)
GetPaletteColor(i, &info_ptr->palette[i].red, &info_ptr->palette[i].green, &info_ptr->palette[i].blue);
}
#if CXIMAGE_SUPPORT_ALPHA // <vho>
//Merge the transparent color with the alpha channel
if (AlphaIsValid() && head.biBitCount==24 && info.nBkgndIndex>=0){
for(long y=0; y < head.biHeight; y++){
for(long x=0; x < head.biWidth ; x++){
RGBQUAD c=GetPixelColor(x,y,false);
if (*(long*)&c==*(long*)&tc)
AlphaSet(x,y,0);
} } }
#endif // CXIMAGE_SUPPORT_ALPHA // <vho>
int row_size = max(info.dwEffWidth, info_ptr->width*info_ptr->channels*(info_ptr->bit_depth/8));
info_ptr->rowbytes = row_size;
BYTE *row_pointers = new BYTE[row_size];
/* write the file information */
png_write_info(png_ptr, info_ptr);
//interlace handling
int num_pass = png_set_interlace_handling(png_ptr);
for (int pass = 0; pass < num_pass; pass++){
//write image
iter.Upset();
long ay=head.biHeight-1;
RGBQUAD c;
do {
#if CXIMAGE_SUPPORT_ALPHA // <vho>
if (AlphaIsValid()){
for (long ax=head.biWidth-1; ax>=0;ax--){
c = BlindGetPixelColor(ax,ay);
int px = ax * info_ptr->channels;
if (!bGrayScale){
row_pointers[px++]=c.rgbRed;
row_pointers[px++]=c.rgbGreen;
}
row_pointers[px++]=c.rgbBlue;
row_pointers[px] = AlphaGet(ax,ay);
}
png_write_row(png_ptr, row_pointers);
ay--;
}
else
#endif //CXIMAGE_SUPPORT_ALPHA // <vho>
{
iter.GetRow(row_pointers, row_size);
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB) //HACK BY OP
RGBtoBGR(row_pointers, row_size);
png_write_row(png_ptr, row_pointers);
}
} while(iter.PrevRow());
}
delete [] row_pointers;
//if necessary, restore the original palette
if (!bGrayScale && head.biClrUsed && info.nBkgndIndex>0)
SwapIndex((BYTE)info.nBkgndIndex,0);
/* It is REQUIRED to call this to finish writing the rest of the file */
png_write_end(png_ptr, info_ptr);
/* if you malloced the palette, free it here */
if (info_ptr->palette){
delete [] (info_ptr->palette);
info_ptr->palette = NULL;
}
/* clean up after the write, and free any memory allocated */
png_destroy_write_struct(&png_ptr, (png_infopp)&info_ptr);
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
return FALSE;
}
/* that's it */
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_PNG

View File

@@ -1,74 +0,0 @@
/*
* File: ximapng.h
* Purpose: PNG Image Class Loader and Writer
*/
/* ==========================================================
* CxImagePNG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
*
* Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
*
* original CImagePNG and CImageIterator implementation are:
* Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
*
* libpng Copyright (c) 1998-2003 Glenn Randers-Pehrson
* ==========================================================
*/
#if !defined(__ximaPNG_h)
#define __ximaPNG_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_PNG
extern "C" {
#include "../png/png.h"
}
class CxImagePNG: public CxImage
{
public:
CxImagePNG(): CxImage(CXIMAGE_FORMAT_PNG) {}
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_PNG);}
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_PNG);}
bool Decode(CxFile * hFile);
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile);
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
#endif // CXIMAGE_SUPPORT_ENCODE
protected:
void ima_png_error(png_struct *png_ptr, char *message);
void expand2to4bpp(BYTE* prow);
static void PNGAPI user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
CxFile* hFile = (CxFile*)png_get_io_ptr(png_ptr);
if (hFile == NULL || hFile->Read(data,1,length) != length) png_error(png_ptr, "Read Error");
}
static void PNGAPI user_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
CxFile* hFile = (CxFile*)png_get_io_ptr(png_ptr);
if (hFile == NULL || hFile->Write(data,1,length) != length) png_error(png_ptr, "Write Error");
}
static void PNGAPI user_flush_data(png_structp png_ptr)
{
CxFile* hFile = (CxFile*)png_get_io_ptr(png_ptr);
if (hFile == NULL || !hFile->Flush()) png_error(png_ptr, "Flush Error");
}
static void PNGAPI user_error_fn(png_structp png_ptr,png_const_charp error_msg)
{
strncpy((char*)png_ptr->error_ptr,error_msg,255);
longjmp(png_ptr->jmpbuf, 1);
}
};
#endif
#endif

View File

@@ -1,228 +0,0 @@
/*
* File: ximaraw.cpp
* Purpose: Platform Independent RAW Image Class Loader
* 16/Dec/2007 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*
* CxImageRAW (c) May/2006 pdw63
*
* based on dcraw.c -- Dave Coffin's raw photo decoder
* Copyright 1997-2007 by Dave Coffin, dcoffin a cybercom o net
*/
#include "ximaraw.h"
#if CXIMAGE_SUPPORT_RAW
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageRAW::Decode(CxFile *hFile)
{
if (hFile==NULL)
return false;
DCRAW dcr;
cx_try
{
// initialization
dcr_init_dcraw(&dcr);
dcr.opt.user_qual = GetCodecOption(CXIMAGE_FORMAT_RAW) & 0x03;
// setup variables for debugging
char szClass[] = "CxImageRAW";
dcr.ifname = szClass;
dcr.sz_error = info.szLastError;
// setup library options, see dcr_print_manual for the available switches
// call dcr_parse_command_line_options(&dcr,0,0,0) to set default options
// if (dcr_parse_command_line_options(&dcr,argc,argv,&arg))
if (dcr_parse_command_line_options(&dcr,0,0,0)){
cx_throw("CxImageRAW: unknown option");
}
// set return point for error handling
if (setjmp (dcr.failure)) {
cx_throw("");
}
// install file manager
CxFileRaw src(hFile,&dcr);
// check file header
dcr_identify(&dcr);
if(!dcr.is_raw){
cx_throw("CxImageRAW: not a raw image");
}
if (dcr.load_raw == NULL) {
cx_throw("CxImageRAW: missing raw decoder");
}
// verify special case
if (dcr.load_raw == dcr_kodak_ycbcr_load_raw) {
dcr.height += dcr.height & 1;
dcr.width += dcr.width & 1;
}
if (info.nEscape == -1){
head.biWidth = dcr.width;
head.biHeight= dcr.height;
info.dwType = CXIMAGE_FORMAT_RAW;
cx_throw("output dimensions returned");
}
// shrinked decoding available and requested?
dcr.shrink = dcr.filters && (dcr.opt.half_size || dcr.opt.threshold || dcr.opt.aber[0] != 1 || dcr.opt.aber[2] != 1);
dcr.iheight = (dcr.height + dcr.shrink) >> dcr.shrink;
dcr.iwidth = (dcr.width + dcr.shrink) >> dcr.shrink;
// install custom camera matrix
if (dcr.opt.use_camera_matrix && dcr.cmatrix[0][0] > 0.25) {
memcpy (dcr.rgb_cam, dcr.cmatrix, sizeof dcr.cmatrix);
dcr.raw_color = 0;
}
// allocate memory for the image
dcr.image = (ushort (*)[4]) calloc (dcr.iheight*dcr.iwidth, sizeof *dcr.image);
dcr_merror (&dcr, dcr.image, szClass);
if (dcr.meta_length) {
dcr.meta_data = (char *) malloc (dcr.meta_length);
dcr_merror (&dcr, dcr.meta_data, szClass);
}
// start image decoder
hFile->Seek(dcr.data_offset, SEEK_SET);
(*dcr.load_raw)(&dcr);
// post processing
if (dcr.zero_is_bad) dcr_remove_zeroes(&dcr);
dcr_bad_pixels(&dcr);
if (dcr.opt.dark_frame) dcr_subtract (&dcr,dcr.opt.dark_frame);
dcr.quality = 2 + !dcr.fuji_width;
if (dcr.opt.user_qual >= 0) dcr.quality = dcr.opt.user_qual;
if (dcr.opt.user_black >= 0) dcr.black = dcr.opt.user_black;
#ifdef COLORCHECK
dcr_colorcheck(&dcr);
#endif
#if RESTRICTED
if (dcr.is_foveon && !dcr.opt.document_mode) dcr_foveon_interpolate(&dcr);
#endif
if (!dcr.is_foveon && dcr.opt.document_mode < 2) dcr_scale_colors(&dcr);
// pixel interpolation and filters
dcr_pre_interpolate(&dcr);
if (dcr.filters && !dcr.opt.document_mode) {
if (dcr.quality == 0)
dcr_lin_interpolate(&dcr);
else if (dcr.quality == 1 || dcr.colors > 3)
dcr_vng_interpolate(&dcr);
else if (dcr.quality == 2)
dcr_ppg_interpolate(&dcr);
else
dcr_ahd_interpolate(&dcr);
}
if (dcr.mix_green) {
long i;
for (dcr.colors=3, i=0; i < dcr.height*dcr.width; i++) {
dcr.image[i][1] = (dcr.image[i][1] + dcr.image[i][3]) >> 1;
}
}
if (!dcr.is_foveon && dcr.colors == 3) dcr_median_filter(&dcr);
if (!dcr.is_foveon && dcr.opt.highlight == 2) dcr_blend_highlights(&dcr);
if (!dcr.is_foveon && dcr.opt.highlight > 2) dcr_recover_highlights(&dcr);
if (dcr.opt.use_fuji_rotate) dcr_fuji_rotate(&dcr);
#ifndef NO_LCMS
if (dcr.opt.cam_profile) dcr_apply_profile (dcr.opt.cam_profile, dcr.opt.out_profile);
#endif
// final conversion
dcr_convert_to_rgb(&dcr);
if (dcr.opt.use_fuji_rotate) dcr_stretch(&dcr);
dcr.iheight = dcr.height;
dcr.iwidth = dcr.width;
if (dcr.flip & 4) SWAP(dcr.height,dcr.width);
// ready to transfer data from dcr.image
if (!Create(dcr.width,dcr.height,24,CXIMAGE_FORMAT_RAW)){
cx_throw("");
}
uchar *ppm = (uchar *) calloc (dcr.width, dcr.colors*dcr.opt.output_bps/8);
ushort *ppm2 = (ushort *) ppm;
dcr_merror (&dcr, ppm, szClass);
uchar lut[0x10000];
if (dcr.opt.output_bps == 8) dcr_gamma_lut (&dcr, lut);
long c, row, col, soff, rstep, cstep;
soff = dcr_flip_index (&dcr, 0, 0);
cstep = dcr_flip_index (&dcr, 0, 1) - soff;
rstep = dcr_flip_index (&dcr, 1, 0) - dcr_flip_index (&dcr, 0, dcr.width);
for (row=0; row < dcr.height; row++, soff += rstep) {
for (col=0; col < dcr.width; col++, soff += cstep) {
if (dcr.opt.output_bps == 8)
for (c=0; c < dcr.colors; c++) ppm [col*dcr.colors+c] = lut[dcr.image[soff][c]];
else
for (c=0; c < dcr.colors; c++) ppm2[col*dcr.colors+c] = dcr.image[soff][c];
}
if (dcr.opt.output_bps == 16 && !dcr.opt.output_tiff && htons(0x55aa) != 0x55aa)
_swab ((char*)ppm2, (char*)ppm2, dcr.width*dcr.colors*2);
DWORD size = dcr.width * (dcr.colors*dcr.opt.output_bps/8);
RGBtoBGR(ppm,size);
memcpy(GetBits(dcr.height - 1 - row), ppm, min(size,GetEffWidth()));
}
free (ppm);
dcr_cleanup_dcraw(&dcr);
} cx_catch {
dcr_cleanup_dcraw(&dcr);
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_RAW) return true;
return false;
}
/* that's it */
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageRAW::Encode(CxFile * hFile)
{
if (hFile == NULL) return false;
strcpy(info.szLastError, "Save RAW not supported");
return false;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_RAW

View File

@@ -1,108 +0,0 @@
/*
* File: ximaraw.h
* Purpose: RAW Image Class Loader and Writer
*/
/* ==========================================================
* CxImageRAW (c) May/2006 pdw63
* For conditions of distribution and use, see copyright notice in ximage.h
* Special thanks to David Coffin for dcraw without which this class would not exist
*
* libdcr (c) Dec/2007 Davide Pizzolato - www.xdp.it
*
* based on dcraw.c -- Dave Coffin's raw photo decoder
* Copyright 1997-2007 by Dave Coffin, dcoffin a cybercom o net
* ==========================================================
*/
#if !defined(__ximaRAW_h)
#define __ximaRAW_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_RAW
extern "C" {
#include "../raw/libdcr.h"
}
class CxImageRAW: public CxImage
{
public:
CxImageRAW(): CxImage(CXIMAGE_FORMAT_RAW) {}
// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_ICO);}
// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_ICO);}
bool Decode(CxFile * hFile);
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile);
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
#endif // CXIMAGE_SUPPORT_ENCODE
enum CODEC_OPTION
{
DECODE_QUALITY_LIN = 0x00,
DECODE_QUALITY_VNG = 0x01,
DECODE_QUALITY_PPG = 0x02,
DECODE_QUALITY_AHD = 0x03,
};
protected:
class CxFileRaw
{
public:
CxFileRaw(CxFile* pFile,DCRAW *stream)
{
stream->obj_ = pFile;
ras_stream_CxFile.read_ = raw_sfile_read;
ras_stream_CxFile.write_ = raw_sfile_write;
ras_stream_CxFile.seek_ = raw_sfile_seek;
ras_stream_CxFile.close_ = raw_sfile_close;
ras_stream_CxFile.gets_ = raw_sfile_gets;
ras_stream_CxFile.eof_ = raw_sfile_eof;
ras_stream_CxFile.tell_ = raw_sfile_tell;
ras_stream_CxFile.getc_ = raw_sfile_getc;
ras_stream_CxFile.scanf_ = raw_sfile_scanf;
stream->ops_ = &ras_stream_CxFile;
}
static int raw_sfile_read(dcr_stream_obj *obj, void *buf, int size, int cnt)
{ return ((CxFile*)obj)->Read(buf,size,cnt); }
static int raw_sfile_write(dcr_stream_obj *obj, void *buf, int size, int cnt)
{ return ((CxFile*)obj)->Write(buf,size,cnt); }
static long raw_sfile_seek(dcr_stream_obj *obj, long offset, int origin)
{ return ((CxFile*)obj)->Seek(offset,origin); }
static int raw_sfile_close(dcr_stream_obj *obj)
{ return 1; /*((CxFile*)obj)->Close();*/ }
static char* raw_sfile_gets(dcr_stream_obj *obj, char *string, int n)
{ return ((CxFile*)obj)->GetS(string,n); }
static int raw_sfile_eof(dcr_stream_obj *obj)
{ return ((CxFile*)obj)->Eof(); }
static long raw_sfile_tell(dcr_stream_obj *obj)
{ return ((CxFile*)obj)->Tell(); }
static int raw_sfile_getc(dcr_stream_obj *obj)
{ return ((CxFile*)obj)->GetC(); }
static int raw_sfile_scanf(dcr_stream_obj *obj,const char *format, void* output)
{ return ((CxFile*)obj)->Scanf(format, output); }
private:
dcr_stream_ops ras_stream_CxFile;
};
};
#endif
#endif

View File

@@ -1,697 +0,0 @@
// xImaSel.cpp : Selection functions
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximage.h"
#if CXIMAGE_SUPPORT_SELECTION
////////////////////////////////////////////////////////////////////////////////
/**
* Checks if the image has a valid selection.
*/
bool CxImage::SelectionIsValid()
{
return pSelection!=0;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Gets the smallest rectangle that contains the selection
*/
void CxImage::SelectionGetBox(RECT& r)
{
memcpy(&r,&info.rSelectionBox,sizeof(RECT));
}
////////////////////////////////////////////////////////////////////////////////
/**
* Empties the selection.
*/
bool CxImage::SelectionClear(BYTE level)
{
if (pSelection){
if (level==0){
memset(pSelection,0,head.biWidth * head.biHeight);
info.rSelectionBox.left = head.biWidth;
info.rSelectionBox.bottom = head.biHeight;
info.rSelectionBox.right = info.rSelectionBox.top = 0;
} else {
memset(pSelection,level,head.biWidth * head.biHeight);
info.rSelectionBox.right = head.biWidth;
info.rSelectionBox.top = head.biHeight;
info.rSelectionBox.left = info.rSelectionBox.bottom = 0;
}
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Allocates an empty selection.
*/
bool CxImage::SelectionCreate()
{
SelectionDelete();
pSelection = (BYTE*)calloc(head.biWidth * head.biHeight, 1);
return (pSelection!=0);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Deallocates the selction.
*/
bool CxImage::SelectionDelete()
{
if (pSelection){
free(pSelection);
pSelection=NULL;
}
info.rSelectionBox.left = head.biWidth;
info.rSelectionBox.bottom = head.biHeight;
info.rSelectionBox.right = info.rSelectionBox.top = 0;
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Checks if the coordinates are inside the selection.
*/
bool CxImage::SelectionIsInside(long x, long y)
{
if (IsInside(x,y)){
if (pSelection==NULL) return true;
return pSelection[x+y*head.biWidth]!=0;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Checks if the coordinates are inside the selection.
* "blind" version assumes that (x,y) is inside to the image.
*/
bool CxImage::BlindSelectionIsInside(long x, long y)
{
#ifdef _DEBUG
if (!IsInside(x,y))
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
throw 0;
#else
return 0;
#endif
#endif
if (pSelection==NULL) return true;
return pSelection[x+y*head.biWidth]!=0;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Adds a rectangle to the existing selection.
*/
bool CxImage::SelectionAddRect(RECT r, BYTE level)
{
if (pSelection==NULL) SelectionCreate();
if (pSelection==NULL) return false;
RECT r2;
if (r.left<r.right) {r2.left=r.left; r2.right=r.right; } else {r2.left=r.right ; r2.right=r.left; }
if (r.bottom<r.top) {r2.bottom=r.bottom; r2.top=r.top; } else {r2.bottom=r.top ; r2.top=r.bottom; }
if (info.rSelectionBox.top <= r2.top) info.rSelectionBox.top = max(0L,min(head.biHeight,r2.top+1));
if (info.rSelectionBox.left > r2.left) info.rSelectionBox.left = max(0L,min(head.biWidth,r2.left));
if (info.rSelectionBox.right <= r2.right) info.rSelectionBox.right = max(0L,min(head.biWidth,r2.right+1));
if (info.rSelectionBox.bottom > r2.bottom) info.rSelectionBox.bottom = max(0L,min(head.biHeight,r2.bottom));
long ymin = max(0L,min(head.biHeight,r2.bottom));
long ymax = max(0L,min(head.biHeight,r2.top+1));
long xmin = max(0L,min(head.biWidth,r2.left));
long xmax = max(0L,min(head.biWidth,r2.right+1));
for (long y=ymin; y<ymax; y++)
memset(pSelection + xmin + y * head.biWidth, level, xmax-xmin);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Adds an ellipse to the existing selection.
*/
bool CxImage::SelectionAddEllipse(RECT r, BYTE level)
{
if (pSelection==NULL) SelectionCreate();
if (pSelection==NULL) return false;
long xradius = abs(r.right - r.left)/2;
long yradius = abs(r.top - r.bottom)/2;
if (xradius==0 || yradius==0) return false;
long xcenter = (r.right + r.left)/2;
long ycenter = (r.top + r.bottom)/2;
if (info.rSelectionBox.left > (xcenter - xradius)) info.rSelectionBox.left = max(0L,min(head.biWidth,(xcenter - xradius)));
if (info.rSelectionBox.right <= (xcenter + xradius)) info.rSelectionBox.right = max(0L,min(head.biWidth,(xcenter + xradius + 1)));
if (info.rSelectionBox.bottom > (ycenter - yradius)) info.rSelectionBox.bottom = max(0L,min(head.biHeight,(ycenter - yradius)));
if (info.rSelectionBox.top <= (ycenter + yradius)) info.rSelectionBox.top = max(0L,min(head.biHeight,(ycenter + yradius + 1)));
long xmin = max(0L,min(head.biWidth,xcenter - xradius));
long xmax = max(0L,min(head.biWidth,xcenter + xradius + 1));
long ymin = max(0L,min(head.biHeight,ycenter - yradius));
long ymax = max(0L,min(head.biHeight,ycenter + yradius + 1));
long y,yo;
for (y=ymin; y<min(ycenter,ymax); y++){
for (long x=xmin; x<xmax; x++){
yo = (long)(ycenter - yradius * sqrt(1-pow((float)(x - xcenter)/(float)xradius,2)));
if (yo<y) pSelection[x + y * head.biWidth] = level;
}
}
for (y=ycenter; y<ymax; y++){
for (long x=xmin; x<xmax; x++){
yo = (long)(ycenter + yradius * sqrt(1-pow((float)(x - xcenter)/(float)xradius,2)));
if (yo>y) pSelection[x + y * head.biWidth] = level;
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Inverts the selection.
* Note: the SelectionBox is set to "full image", call SelectionGetBox before (if necessary)
*/
bool CxImage::SelectionInvert()
{
if (pSelection) {
BYTE *iSrc=pSelection;
long n=head.biHeight*head.biWidth;
for(long i=0; i < n; i++){
*iSrc=(BYTE)~(*(iSrc));
iSrc++;
}
SelectionRebuildBox();
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Imports an existing region from another image with the same width and height.
*/
bool CxImage::SelectionCopy(CxImage &from)
{
if (from.pSelection == NULL || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false;
if (pSelection==NULL) pSelection = (BYTE*)malloc(head.biWidth * head.biHeight);
if (pSelection==NULL) return false;
memcpy(pSelection,from.pSelection,head.biWidth * head.biHeight);
memcpy(&info.rSelectionBox,&from.info.rSelectionBox,sizeof(RECT));
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Adds a polygonal region to the existing selection. points points to an array of POINT structures.
* Each structure specifies the x-coordinate and y-coordinate of one vertex of the polygon.
* npoints specifies the number of POINT structures in the array pointed to by points.
*/
bool CxImage::SelectionAddPolygon(POINT *points, long npoints, BYTE level)
{
if (points==NULL || npoints<3) return false;
if (pSelection==NULL) SelectionCreate();
if (pSelection==NULL) return false;
BYTE* plocal = (BYTE*)calloc(head.biWidth*head.biHeight, 1);
RECT localbox = {head.biWidth,0,0,head.biHeight};
long x,y,i=0;
POINT *current;
POINT *next = NULL;
POINT *start = NULL;
//trace contour
while (i < npoints){
current = &points[i];
if (current->x!=-1){
if (i==0 || (i>0 && points[i-1].x==-1)) start = &points[i];
if ((i+1)==npoints || points[i+1].x==-1)
next = start;
else
next = &points[i+1];
float beta;
if (current->x != next->x){
beta = (float)(next->y - current->y)/(float)(next->x - current->x);
if (current->x < next->x){
for (x=current->x; x<=next->x; x++){
y = (long)(current->y + (x - current->x) * beta);
if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
}
} else {
for (x=current->x; x>=next->x; x--){
y = (long)(current->y + (x - current->x) * beta);
if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
}
}
}
if (current->y != next->y){
beta = (float)(next->x - current->x)/(float)(next->y - current->y);
if (current->y < next->y){
for (y=current->y; y<=next->y; y++){
x = (long)(current->x + (y - current->y) * beta);
if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
}
} else {
for (y=current->y; y>=next->y; y--){
x = (long)(current->x + (y - current->y) * beta);
if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
}
}
}
}
RECT r2;
if (current->x < next->x) {r2.left=current->x; r2.right=next->x; } else {r2.left=next->x ; r2.right=current->x; }
if (current->y < next->y) {r2.bottom=current->y; r2.top=next->y; } else {r2.bottom=next->y ; r2.top=current->y; }
if (localbox.top < r2.top) localbox.top = max(0L,min(head.biHeight-1,r2.top+1));
if (localbox.left > r2.left) localbox.left = max(0L,min(head.biWidth-1,r2.left-1));
if (localbox.right < r2.right) localbox.right = max(0L,min(head.biWidth-1,r2.right+1));
if (localbox.bottom > r2.bottom) localbox.bottom = max(0L,min(head.biHeight-1,r2.bottom-1));
i++;
}
//fill the outer region
long npix=(localbox.right - localbox.left)*(localbox.top - localbox.bottom);
POINT* pix = (POINT*)calloc(npix,sizeof(POINT));
BYTE back=0, mark=1;
long fx, fy, fxx, fyy, first, last;
long xmin = 0;
long xmax = 0;
long ymin = 0;
long ymax = 0;
for (int side=0; side<4; side++){
switch(side){
case 0:
xmin=localbox.left; xmax=localbox.right+1; ymin=localbox.bottom; ymax=localbox.bottom+1;
break;
case 1:
xmin=localbox.right; xmax=localbox.right+1; ymin=localbox.bottom; ymax=localbox.top+1;
break;
case 2:
xmin=localbox.left; xmax=localbox.right+1; ymin=localbox.top; ymax=localbox.top+1;
break;
case 3:
xmin=localbox.left; xmax=localbox.left+1; ymin=localbox.bottom; ymax=localbox.top+1;
break;
}
//fill from the border points
for(y=ymin;y<ymax;y++){
for(x=xmin;x<xmax;x++){
if (plocal[x+y*head.biWidth]==0){
// Subject: FLOOD FILL ROUTINE Date: 12-23-97 (00:57)
// Author: Petter Holmberg Code: QB, QBasic, PDS
// Origin: petter.holmberg@usa.net Packet: GRAPHICS.ABC
first=0;
last=1;
while(first!=last){
fx = pix[first].x;
fy = pix[first].y;
fxx = fx + x;
fyy = fy + y;
for(;;)
{
if ((plocal[fxx + fyy*head.biWidth] == back) &&
fxx>=localbox.left && fxx<=localbox.right && fyy>=localbox.bottom && fyy<=localbox.top )
{
plocal[fxx + fyy*head.biWidth] = mark;
if (fyy > 0 && plocal[fxx + (fyy - 1)*head.biWidth] == back){
pix[last].x = fx;
pix[last].y = fy - 1;
last++;
if (last == npix) last = 0;
}
if ((fyy + 1)<head.biHeight && plocal[fxx + (fyy + 1)*head.biWidth] == back){
pix[last].x = fx;
pix[last].y = fy + 1;
last++;
if (last == npix) last = 0;
}
} else {
break;
}
fx++;
fxx++;
};
fx = pix[first].x - 1;
fy = pix[first].y;
fxx = fx + x;
fyy = fy + y;
for( ;; )
{
if ((plocal[fxx + fyy*head.biWidth] == back) &&
fxx>=localbox.left && fxx<=localbox.right && fyy>=localbox.bottom && fyy<=localbox.top )
{
plocal[fxx + (y + fy)*head.biWidth] = mark;
if (fyy > 0 && plocal[fxx + (fyy - 1)*head.biWidth] == back){
pix[last].x = fx;
pix[last].y = fy - 1;
last++;
if (last == npix) last = 0;
}
if ((fyy + 1)<head.biHeight && plocal[fxx + (fyy + 1)*head.biWidth] == back){
pix[last].x = fx;
pix[last].y = fy + 1;
last++;
if (last == npix) last = 0;
}
} else {
break;
}
fx--;
fxx--;
}
first++;
if (first == npix) first = 0;
}
}
}
}
}
//transfer the region
long yoffset;
for (y=localbox.bottom; y<=localbox.top; y++){
yoffset = y * head.biWidth;
for (x=localbox.left; x<=localbox.right; x++)
if (plocal[x + yoffset]!=1) pSelection[x + yoffset]=level;
}
if (info.rSelectionBox.top <= localbox.top) info.rSelectionBox.top = min(head.biHeight,localbox.top + 1);
if (info.rSelectionBox.left > localbox.left) info.rSelectionBox.left = min(head.biWidth,localbox.left);
if (info.rSelectionBox.right <= localbox.right) info.rSelectionBox.right = min(head.biWidth,localbox.right + 1);
if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = min(head.biHeight,localbox.bottom);
free(plocal);
free(pix);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Adds to the selection all the pixels matching the specified color.
*/
bool CxImage::SelectionAddColor(RGBQUAD c, BYTE level)
{
if (pSelection==NULL) SelectionCreate();
if (pSelection==NULL) return false;
RECT localbox = {head.biWidth,0,0,head.biHeight};
for (long y = 0; y < head.biHeight; y++){
for (long x = 0; x < head.biWidth; x++){
RGBQUAD color = BlindGetPixelColor(x, y);
if (color.rgbRed == c.rgbRed &&
color.rgbGreen == c.rgbGreen &&
color.rgbBlue == c.rgbBlue)
{
pSelection[x + y * head.biWidth] = level;
if (localbox.top < y) localbox.top = y;
if (localbox.left > x) localbox.left = x;
if (localbox.right < x) localbox.right = x;
if (localbox.bottom > y) localbox.bottom = y;
}
}
}
if (info.rSelectionBox.top <= localbox.top) info.rSelectionBox.top = localbox.top + 1;
if (info.rSelectionBox.left > localbox.left) info.rSelectionBox.left = localbox.left;
if (info.rSelectionBox.right <= localbox.right) info.rSelectionBox.right = localbox.right + 1;
if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = localbox.bottom;
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Adds a single pixel to the existing selection.
*/
bool CxImage::SelectionAddPixel(long x, long y, BYTE level)
{
if (pSelection==NULL) SelectionCreate();
if (pSelection==NULL) return false;
if (IsInside(x,y)) {
pSelection[x + y * head.biWidth] = level; // set the correct mask bit
if (info.rSelectionBox.top <= y) info.rSelectionBox.top = y+1;
if (info.rSelectionBox.left > x) info.rSelectionBox.left = x;
if (info.rSelectionBox.right <= x) info.rSelectionBox.right = x+1;
if (info.rSelectionBox.bottom > y) info.rSelectionBox.bottom = y;
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Exports the selection channel in a 8bpp grayscale image.
*/
bool CxImage::SelectionSplit(CxImage *dest)
{
if (!pSelection || !dest) return false;
CxImage tmp(head.biWidth,head.biHeight,8);
if (!tmp.IsValid()){
strcpy(info.szLastError,tmp.GetLastError());
return false;
}
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
tmp.BlindSetPixelIndex(x,y,pSelection[x+y*head.biWidth]);
}
}
tmp.SetGrayPalette();
dest->Transfer(tmp);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Creates the selection channel from a gray scale image.
* black = unselected
*/
bool CxImage::SelectionSet(CxImage &from)
{
if (!from.IsGrayScale() || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight){
strcpy(info.szLastError,"CxImage::SelectionSet: wrong width or height, or image is not gray scale");
return false;
}
if (pSelection==NULL) pSelection = (BYTE*)malloc(head.biWidth * head.biHeight);
BYTE* src = from.info.pImage;
BYTE* dst = pSelection;
if (src==NULL || dst==NULL){
strcpy(info.szLastError,"CxImage::SelectionSet: null pointer");
return false;
}
for (long y=0; y<head.biHeight; y++){
memcpy(dst,src,head.biWidth);
dst += head.biWidth;
src += from.info.dwEffWidth;
}
SelectionRebuildBox();
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the Selection level for a single pixel
* internal use only: doesn't set SelectionBox. Use SelectionAddPixel
*/
void CxImage::SelectionSet(const long x,const long y,const BYTE level)
{
if (pSelection && IsInside(x,y)) pSelection[x+y*head.biWidth]=level;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Gets the Selection level for a single pixel
*/
BYTE CxImage::SelectionGet(const long x,const long y)
{
if (pSelection && IsInside(x,y)) return pSelection[x+y*head.biWidth];
return 0;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Rebuilds the SelectionBox
*/
void CxImage::SelectionRebuildBox()
{
info.rSelectionBox.left = head.biWidth;
info.rSelectionBox.bottom = head.biHeight;
info.rSelectionBox.right = info.rSelectionBox.top = 0;
if (!pSelection)
return;
long x,y;
for (y=0; y<head.biHeight; y++){
for (x=0; x<info.rSelectionBox.left; x++){
if (pSelection[x+y*head.biWidth]){
info.rSelectionBox.left = x;
continue;
}
}
}
for (y=0; y<head.biHeight; y++){
for (x=head.biWidth-1; x>=info.rSelectionBox.right; x--){
if (pSelection[x+y*head.biWidth]){
info.rSelectionBox.right = x+1;
continue;
}
}
}
for (x=0; x<head.biWidth; x++){
for (y=0; y<info.rSelectionBox.bottom; y++){
if (pSelection[x+y*head.biWidth]){
info.rSelectionBox.bottom = y;
continue;
}
}
}
for (x=0; x<head.biWidth; x++){
for (y=head.biHeight-1; y>=info.rSelectionBox.top; y--){
if (pSelection[x+y*head.biWidth]){
info.rSelectionBox.top = y+1;
continue;
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* Gets the Selection level for a single pixel
* "blind" version assumes that (x,y) is inside to the image.
*/
BYTE CxImage::BlindSelectionGet(const long x,const long y)
{
#ifdef _DEBUG
if (!IsInside(x,y) || (pSelection==0))
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
throw 0;
#else
return 0;
#endif
#endif
return pSelection[x+y*head.biWidth];
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns pointer to selection data for pixel (x,y).
*/
BYTE* CxImage::SelectionGetPointer(const long x,const long y)
{
if (pSelection && IsInside(x,y)) return pSelection+x+y*head.biWidth;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::SelectionFlip()
{
if (!pSelection) return false;
BYTE *buff = (BYTE*)malloc(head.biWidth);
if (!buff) return false;
BYTE *iSrc,*iDst;
iSrc = pSelection + (head.biHeight-1)*head.biWidth;
iDst = pSelection;
for (long i=0; i<(head.biHeight/2); ++i)
{
memcpy(buff, iSrc, head.biWidth);
memcpy(iSrc, iDst, head.biWidth);
memcpy(iDst, buff, head.biWidth);
iSrc-=head.biWidth;
iDst+=head.biWidth;
}
free(buff);
long top = info.rSelectionBox.top;
info.rSelectionBox.top = head.biHeight - info.rSelectionBox.bottom;
info.rSelectionBox.bottom = head.biHeight - top;
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::SelectionMirror()
{
if (!pSelection) return false;
BYTE* pSelection2 = (BYTE*)malloc(head.biWidth * head.biHeight);
if (!pSelection2) return false;
BYTE *iSrc,*iDst;
long wdt=head.biWidth-1;
iSrc=pSelection + wdt;
iDst=pSelection2;
for(long y=0; y < head.biHeight; y++){
for(long x=0; x <= wdt; x++)
*(iDst+x)=*(iSrc-x);
iSrc+=head.biWidth;
iDst+=head.biWidth;
}
free(pSelection);
pSelection=pSelection2;
long left = info.rSelectionBox.left;
info.rSelectionBox.left = head.biWidth - info.rSelectionBox.right;
info.rSelectionBox.right = head.biWidth - left;
return true;
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_WINDOWS
/**
* Converts the selection in a HRGN object.
*/
bool CxImage::SelectionToHRGN(HRGN& region)
{
if (pSelection && region){
for(int y = 0; y < head.biHeight; y++){
HRGN hTemp = NULL;
int iStart = -1;
int x = 0;
for(; x < head.biWidth; x++){
if (pSelection[x + y * head.biWidth] != 0){
if (iStart == -1) iStart = x;
continue;
}else{
if (iStart >= 0){
hTemp = CreateRectRgn(iStart, y, x, y + 1);
CombineRgn(region, hTemp, region, RGN_OR);
DeleteObject(hTemp);
iStart = -1;
}
}
}
if (iStart >= 0){
hTemp = CreateRectRgn(iStart, y, x, y + 1);
CombineRgn(region, hTemp, region, RGN_OR);
DeleteObject(hTemp);
iStart = -1;
}
}
return true;
}
return false;
}
#endif //CXIMAGE_SUPPORT_WINDOWS
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_SELECTION

View File

@@ -1,126 +0,0 @@
/*
* File: ximaska.cpp
* Purpose: Platform Independent SKA Image Class Loader and Writer
* 25/Sep/2007 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximaska.h"
#if CXIMAGE_SUPPORT_SKA
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageSKA::Decode(CxFile *hFile)
{
if (hFile==NULL)
return false;
// read the header
SKAHEADER ska_header;
hFile->Read(&ska_header,sizeof(SKAHEADER),1);
ska_header.Width = ntohs(ska_header.Width);
ska_header.Height = ntohs(ska_header.Height);
ska_header.dwUnknown = ntohl(ska_header.dwUnknown);
// check header
if (ska_header.dwUnknown != 0x01000000 ||
ska_header.Width > 0x7FFF || ska_header.Height > 0x7FFF ||
ska_header.BppExp != 3)
return false;
if (info.nEscape == -1){
head.biWidth = ska_header.Width ;
head.biHeight= ska_header.Height;
info.dwType = CXIMAGE_FORMAT_SKA;
return true;
}
int bpp = 1<<ska_header.BppExp;
Create(ska_header.Width,ska_header.Height,bpp,CXIMAGE_FORMAT_SKA);
if (!IsValid())
return false;
// read the palette
int nColors = 1<<bpp;
rgb_color* ppal = (rgb_color*)malloc(nColors*sizeof(rgb_color));
if (!ppal) return false;
hFile->Read(ppal,nColors*sizeof(rgb_color),1);
SetPalette(ppal,nColors);
free(ppal);
//read the image
hFile->Read(GetBits(),ska_header.Width*ska_header.Height,1);
//reorder rows
if (GetEffWidth() != ska_header.Width){
BYTE *src,*dst;
src = GetBits() + ska_header.Width*(ska_header.Height-1);
dst = GetBits(ska_header.Height-1);
for(int y=0;y<ska_header.Height;y++){
memcpy(dst,src,ska_header.Width);
src -= ska_header.Width;
dst -= GetEffWidth();
}
}
Flip();
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageSKA::Encode(CxFile * hFile)
{
if (EncodeSafeCheck(hFile)) return false;
if(head.biBitCount > 8) {
strcpy(info.szLastError,"SKA Images must be 8 bit or less");
return false;
}
SKAHEADER ska_header;
ska_header.Width = (unsigned short)GetWidth();
ska_header.Height = (unsigned short)GetHeight();
ska_header.BppExp = 3;
ska_header.dwUnknown = 0x01000000;
ska_header.Width = ntohs(ska_header.Width);
ska_header.Height = ntohs(ska_header.Height);
ska_header.dwUnknown = ntohl(ska_header.dwUnknown);
hFile->Write(&ska_header,sizeof(SKAHEADER),1);
ska_header.Width = ntohs(ska_header.Width);
ska_header.Height = ntohs(ska_header.Height);
ska_header.dwUnknown = ntohl(ska_header.dwUnknown);
if (head.biBitCount<8) IncreaseBpp(8);
rgb_color pal[256];
for(int idx=0; idx<256; idx++){
GetPaletteColor(idx,&(pal[idx].r),&(pal[idx].g),&(pal[idx].b));
}
hFile->Write(pal,256*sizeof(rgb_color),1);
BYTE* src = GetBits(ska_header.Height-1);
for(int y=0;y<ska_header.Height;y++){
hFile->Write(src,ska_header.Width,1);
src -= GetEffWidth();
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_SKA

View File

@@ -1,44 +0,0 @@
/*
* File: ximaska.h
* Purpose: SKA Image Class Loader and Writer
*/
/* ==========================================================
* CxImageSKA (c) 25/Sep/2007 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
* ==========================================================
*/
#if !defined(__ximaSKA_h)
#define __ximaSKA_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_SKA
class CxImageSKA: public CxImage
{
#pragma pack(1)
typedef struct tagSkaHeader {
unsigned short Width;
unsigned short Height;
BYTE BppExp;
DWORD dwUnknown;
} SKAHEADER;
#pragma pack()
public:
CxImageSKA(): CxImage(CXIMAGE_FORMAT_SKA) {}
// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_ICO);}
// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_ICO);}
bool Decode(CxFile * hFile);
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile);
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
#endif // CXIMAGE_SUPPORT_ENCODE
};
#endif
#endif

View File

@@ -1,321 +0,0 @@
/*
* File: ximatga.cpp
* Purpose: Platform Independent TGA Image Class Loader and Writer
* 05/Jan/2001 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximatga.h"
#if CXIMAGE_SUPPORT_TGA
#include "ximaiter.h"
// Definitions for image types.
#define TGA_Null 0
#define TGA_Map 1
#define TGA_RGB 2
#define TGA_Mono 3
#define TGA_RLEMap 9
#define TGA_RLERGB 10
#define TGA_RLEMono 11
#define TGA_CompMap 32
#define TGA_CompMap4 33
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageTGA::Decode(CxFile *hFile)
{
if (hFile == NULL) return false;
TGAHEADER tgaHead;
cx_try
{
if (hFile->Read(&tgaHead,sizeof(tgaHead),1)==0)
cx_throw("Not a TGA");
tga_toh(&tgaHead);
bool bCompressed;
switch (tgaHead.ImageType){
case TGA_Map:
case TGA_RGB:
case TGA_Mono:
bCompressed = false;
break;
case TGA_RLEMap:
case TGA_RLERGB:
case TGA_RLEMono:
bCompressed = true;
break;
default:
cx_throw("Unknown TGA image type");
}
if (tgaHead.ImageWidth==0 || tgaHead.ImageHeight==0 || tgaHead.PixelDepth==0 || tgaHead.CmapLength>256)
cx_throw("bad TGA header");
if (tgaHead.PixelDepth!=8 && tgaHead.PixelDepth!=15 && tgaHead.PixelDepth!=16 && tgaHead.PixelDepth!=24 && tgaHead.PixelDepth!=32)
cx_throw("bad TGA header");
if (info.nEscape == -1){
head.biWidth = tgaHead.ImageWidth ;
head.biHeight= tgaHead.ImageHeight;
info.dwType = CXIMAGE_FORMAT_TGA;
return true;
}
if (tgaHead.IdLength>0) hFile->Seek(tgaHead.IdLength,SEEK_CUR); //skip descriptor
Create(tgaHead.ImageWidth, tgaHead.ImageHeight, tgaHead.PixelDepth, CXIMAGE_FORMAT_TGA);
#if CXIMAGE_SUPPORT_ALPHA // <vho>
if (tgaHead.PixelDepth==32) AlphaCreate(); // Image has alpha channel
#endif //CXIMAGE_SUPPORT_ALPHA
if (!IsValid()) cx_throw("TGA Create failed");
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
if (tgaHead.CmapType != 0){ // read the palette
rgb_color pal[256];
hFile->Read(pal,tgaHead.CmapLength*sizeof(rgb_color), 1);
for (int i=0;i<tgaHead.CmapLength; i++) SetPaletteColor((BYTE)i,pal[i].b,pal[i].g,pal[i].r);
}
if (tgaHead.ImageType == TGA_Mono || tgaHead.ImageType == TGA_RLEMono)
SetGrayPalette();
// Bits 4 & 5 of the Image Descriptor byte control the ordering of the pixels.
bool bXReversed = ((tgaHead.ImagDesc & 16) == 16);
bool bYReversed = ((tgaHead.ImagDesc & 32) == 32);
CImageIterator iter(this);
BYTE rleLeftover = 255; //for images with illegal packet boundary
BYTE* pDest;
for (int y=0; y < tgaHead.ImageHeight; y++){
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
if (hFile == NULL || hFile->Eof()) cx_throw("corrupted TGA");
if (bYReversed) pDest = iter.GetRow(tgaHead.ImageHeight-y-1);
else pDest = iter.GetRow(y);
if (bCompressed) rleLeftover = ExpandCompressedLine(pDest,&tgaHead,hFile,tgaHead.ImageWidth,y,rleLeftover);
else ExpandUncompressedLine (pDest,&tgaHead,hFile,tgaHead.ImageWidth,y,0);
}
if (bXReversed) Mirror();
#if CXIMAGE_SUPPORT_ALPHA
if (bYReversed && tgaHead.PixelDepth==32) AlphaFlip(); //<lioucr>
#endif //CXIMAGE_SUPPORT_ALPHA
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageTGA::Encode(CxFile * hFile)
{
if (EncodeSafeCheck(hFile)) return false;
if (head.biBitCount<8){
strcpy(info.szLastError,"Bit depth must be 8 or 24");
return false;
}
TGAHEADER tgaHead;
tgaHead.IdLength = 0; // Image ID Field Length
tgaHead.CmapType = GetPalette()!=0; // Color Map Type
tgaHead.ImageType = (head.biBitCount == 8) ? (BYTE)TGA_Map : (BYTE)TGA_RGB; // Image Type
tgaHead.CmapIndex=0; // First Entry Index
tgaHead.CmapLength=(head.biBitCount == 8) ? 256 : 0; // Color Map Length
tgaHead.CmapEntrySize=(head.biBitCount == 8) ? (BYTE)24 : (BYTE)0; // Color Map Entry Size
tgaHead.X_Origin=0; // X-origin of Image
tgaHead.Y_Origin=0; // Y-origin of Image
tgaHead.ImageWidth=(WORD)head.biWidth; // Image Width
tgaHead.ImageHeight=(WORD)head.biHeight; // Image Height
tgaHead.PixelDepth=(BYTE)head.biBitCount; // Pixel Depth
tgaHead.ImagDesc=0; // Image Descriptor
if (pAlpha && head.biBitCount==24) tgaHead.PixelDepth=32;
tga_toh(&tgaHead);
hFile->Write(&tgaHead,sizeof(TGAHEADER),1);
tga_toh(&tgaHead);
if (head.biBitCount==8){
rgb_color pal[256];
RGBQUAD* ppal = GetPalette();
for (int i=0;i<256; i++){
pal[i].r = ppal[i].rgbBlue;
pal[i].g = ppal[i].rgbGreen;
pal[i].b = ppal[i].rgbRed;
}
hFile->Write(&pal,256*sizeof(rgb_color),1);
}
CImageIterator iter(this);
BYTE* pDest;
if (pAlpha==0 || head.biBitCount==8){
for (int y=0; y < tgaHead.ImageHeight; y++){
pDest = iter.GetRow(y);
hFile->Write(pDest,tgaHead.ImageWidth * (head.biBitCount >> 3),1);
}
} else {
pDest = (BYTE*)malloc(4*tgaHead.ImageWidth);
RGBQUAD c;
for (int y=0; y < tgaHead.ImageHeight; y++){
for(int x=0, x4=0;x<tgaHead.ImageWidth;x++, x4+=4){
c = BlindGetPixelColor(x,y);
pDest[x4+0]=c.rgbBlue;
pDest[x4+1]=c.rgbGreen;
pDest[x4+2]=c.rgbRed;
#if CXIMAGE_SUPPORT_ALPHA // <vho>
pDest[x4+3]=AlphaGet(x,y);
#else
pDest[x4+3]=0;
#endif //CXIMAGE_SUPPORT_ALPHA
}
hFile->Write(pDest,4*tgaHead.ImageWidth,1);
}
free(pDest);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
BYTE CxImageTGA::ExpandCompressedLine(BYTE* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int width, int y, BYTE rleLeftover)
{
BYTE rle;
long filePos=0;
for (int x=0; x<width; ){
if (rleLeftover != 255){
rle = rleLeftover;
rleLeftover = 255;
} else {
hFile->Read(&rle,1,1);
}
if (rle & 128) { // RLE-Encoded packet
rle -= 127; // Calculate real repeat count.
if ((x+rle)>width){
rleLeftover = (BYTE)(128 + (rle - (width - x) - 1));
filePos = hFile->Tell();
rle = (BYTE)(width - x);
}
switch (ptgaHead->PixelDepth)
{
case 32: {
RGBQUAD color;
hFile->Read(&color,4,1);
for (int ix = 0; ix < rle; ix++){
memcpy(&pDest[3*ix],&color,3);
#if CXIMAGE_SUPPORT_ALPHA // <vho>
AlphaSet(ix+x,y,color.rgbReserved);
#endif //CXIMAGE_SUPPORT_ALPHA
}
break;
}
case 24: {
rgb_color triple;
hFile->Read(&triple,3,1);
for (int ix = 0; ix < rle; ix++) memcpy(&pDest[3*ix],&triple,3);
break;
}
case 15:
case 16: {
WORD pixel;
hFile->Read(&pixel,2,1);
rgb_color triple;
triple.r = (BYTE)(( pixel & 0x1F ) * 8); // red
triple.g = (BYTE)(( pixel >> 2 ) & 0x0F8); // green
triple.b = (BYTE)(( pixel >> 7 ) & 0x0F8); // blue
for (int ix = 0; ix < rle; ix++){
memcpy(&pDest[3*ix],&triple,3);
}
break;
}
case 8: {
BYTE pixel;
hFile->Read(&pixel,1,1);
for (int ix = 0; ix < rle; ix++) pDest[ix] = pixel;
}
}
if (rleLeftover!=255) hFile->Seek(filePos, SEEK_SET);
} else { // Raw packet
rle += 1; // Calculate real repeat count.
if ((x+rle)>width){
rleLeftover = (BYTE)(rle - (width - x) - 1);
rle = (BYTE)(width - x);
}
ExpandUncompressedLine(pDest,ptgaHead,hFile,rle,y,x);
}
if (head.biBitCount == 24) pDest += rle*3; else pDest += rle;
x += rle;
}
return rleLeftover;
}
////////////////////////////////////////////////////////////////////////////////
void CxImageTGA::ExpandUncompressedLine(BYTE* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int width, int y, int xoffset)
{
switch (ptgaHead->PixelDepth){
case 8:
hFile->Read(pDest,width,1);
break;
case 15:
case 16:{
BYTE* dst=pDest;
WORD pixel;
for (int x=0; x<width; x++){
hFile->Read(&pixel,2,1);
*dst++ = (BYTE)(( pixel & 0x1F ) * 8); // blue
*dst++ = (BYTE)(( pixel >> 2 ) & 0x0F8); // green
*dst++ = (BYTE)(( pixel >> 7 ) & 0x0F8); // red
}
break;
}
case 24:
hFile->Read(pDest,3*width,1);
break;
case 32:{
BYTE* dst=pDest;
for (int x=0; x<width; x++){
RGBQUAD pixel;
hFile->Read(&pixel,4,1);
*dst++ = pixel.rgbBlue;
*dst++ = pixel.rgbGreen;
*dst++ = pixel.rgbRed;
#if CXIMAGE_SUPPORT_ALPHA // <vho>
AlphaSet(x+xoffset,y,pixel.rgbReserved); //alpha
#endif //CXIMAGE_SUPPORT_ALPHA
}
break;
}
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImageTGA::tga_toh(TGAHEADER* p)
{
p->CmapIndex = ntohs(p->CmapIndex);
p->CmapLength = ntohs(p->CmapLength);
p->X_Origin = ntohs(p->X_Origin);
p->Y_Origin = ntohs(p->Y_Origin);
p->ImageWidth = ntohs(p->ImageWidth);
p->ImageHeight = ntohs(p->ImageHeight);
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_TGA

View File

@@ -1,61 +0,0 @@
/*
* File: ximatga.h
* Purpose: TARGA Image Class Loader and Writer
*/
/* ==========================================================
* CxImageTGA (c) 05/Jan/2002 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
*
* Parts of the code come from Paintlib : Copyright (c) 1996-1998 Ulrich von Zadow
* ==========================================================
*/
#if !defined(__ximaTGA_h)
#define __ximaTGA_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_TGA
class CxImageTGA: public CxImage
{
#pragma pack(1)
typedef struct tagTgaHeader
{
BYTE IdLength; // Image ID Field Length
BYTE CmapType; // Color Map Type
BYTE ImageType; // Image Type
WORD CmapIndex; // First Entry Index
WORD CmapLength; // Color Map Length
BYTE CmapEntrySize; // Color Map Entry Size
WORD X_Origin; // X-origin of Image
WORD Y_Origin; // Y-origin of Image
WORD ImageWidth; // Image Width
WORD ImageHeight; // Image Height
BYTE PixelDepth; // Pixel Depth
BYTE ImagDesc; // Image Descriptor
} TGAHEADER;
#pragma pack()
public:
CxImageTGA(): CxImage(CXIMAGE_FORMAT_TGA) {}
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_TGA);}
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_TGA);}
bool Decode(CxFile * hFile);
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile);
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
#endif // CXIMAGE_SUPPORT_ENCODE
protected:
BYTE ExpandCompressedLine(BYTE* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int width, int y, BYTE rleLeftover);
void ExpandUncompressedLine(BYTE* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int width, int y, int xoffset);
void tga_toh(TGAHEADER* p);
};
#endif
#endif

View File

@@ -1,97 +0,0 @@
#include "ximage.h"
#include "ximath.h"
#include <math.h>
//this module should contain some classes for geometrical transformations
//usable with selections, etc... once it's done, that is. :)
CxPoint2::CxPoint2()
{
x=y=0.0f;
}
CxPoint2::CxPoint2(float const x_, float const y_)
{
x=x_;
y=y_;
}
CxPoint2::CxPoint2(CxPoint2 const &p)
{
x=p.x;
y=p.y;
}
float CxPoint2::Distance(CxPoint2 const p2)
{
return (float)sqrt((x-p2.x)*(x-p2.x)+(y-p2.y)*(y-p2.y));
}
float CxPoint2::Distance(float const x_, float const y_)
{
return (float)sqrt((x-x_)*(x-x_)+(y-y_)*(y-y_));
}
CxRect2::CxRect2()
{
}
CxRect2::CxRect2(float const x1_, float const y1_, float const x2_, float const y2_)
{
botLeft.x=x1_;
botLeft.y=y1_;
topRight.x=x2_;
topRight.y=y2_;
}
CxRect2::CxRect2(CxRect2 const &p)
{
botLeft=p.botLeft;
topRight=p.topRight;
}
float CxRect2::Surface() const
/*
* Returns the surface of rectangle.
*/
{
return (topRight.x-botLeft.x)*(topRight.y-botLeft.y);
}
CxRect2 CxRect2::CrossSection(CxRect2 const &r2) const
/*
* Returns crossection with another rectangle.
*/
{
CxRect2 cs;
cs.botLeft.x=max(botLeft.x, r2.botLeft.x);
cs.botLeft.y=max(botLeft.y, r2.botLeft.y);
cs.topRight.x=min(topRight.x, r2.topRight.x);
cs.topRight.y=min(topRight.y, r2.topRight.y);
if (cs.botLeft.x<=cs.topRight.x && cs.botLeft.y<=cs.topRight.y) {
return cs;
} else {
return CxRect2(0,0,0,0);
}//if
}
CxPoint2 CxRect2::Center() const
/*
* Returns the center point of rectangle.
*/
{
return CxPoint2((topRight.x+botLeft.x)/2.0f, (topRight.y+botLeft.y)/2.0f);
}
float CxRect2::Width() const
//returns rectangle width
{
return topRight.x-botLeft.x;
}
float CxRect2::Height() const
//returns rectangle height
{
return topRight.y-botLeft.y;
}

View File

@@ -1,39 +0,0 @@
#if !defined(__ximath_h)
#define __ximath_h
#include "ximadef.h"
//***bd*** simple floating point point
class DLL_EXP CxPoint2
{
public:
CxPoint2();
CxPoint2(float const x_, float const y_);
CxPoint2(CxPoint2 const &p);
float Distance(CxPoint2 const p2);
float Distance(float const x_, float const y_);
float x,y;
};
//and simple rectangle
class DLL_EXP CxRect2
{
public:
CxRect2();
CxRect2(float const x1_, float const y1_, float const x2_, float const y2_);
CxRect2(CxPoint2 const &bl, CxPoint2 const &tr);
CxRect2(CxRect2 const &p);
float Surface() const;
CxRect2 CrossSection(CxRect2 const &r2) const;
CxPoint2 Center() const;
float Width() const;
float Height() const;
CxPoint2 botLeft;
CxPoint2 topRight;
};
#endif

View File

@@ -1,980 +0,0 @@
/*
* File: ximatif.cpp
* Purpose: Platform Independent TIFF Image Class Loader and Writer
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximatif.h"
#if CXIMAGE_SUPPORT_TIF
#define FIX_16BPP_DARKIMG // + VK: if uncomment, dark 16bpp images are fixed
#include "../tiff/tiffio.h"
#define CVT(x) (((x) * 255L) / ((1L<<16)-1))
#define SCALE(x) (((x)*((1L<<16)-1))/255)
#define CalculateLine(width,bitdepth) (((width * bitdepth) + 7) / 8)
#define CalculatePitch(line) (line + 3 & ~3)
extern "C" TIFF* _TIFFOpenEx(CxFile* stream, const char* mode);
////////////////////////////////////////////////////////////////////////////////
CxImageTIF::~CxImageTIF()
{
if (m_tif2) TIFFClose(m_tif2);
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageTIF::Decode(CxFile * hFile)
{
//Comment this line if you need more information on errors
// TIFFSetErrorHandler(NULL); //<Patrick Hoffmann>
//Open file and fill the TIFF structure
// m_tif = TIFFOpen(imageFileName,"rb");
TIFF* m_tif = _TIFFOpenEx(hFile, "rb");
uint32 height=0;
uint32 width=0;
uint16 bitspersample=1;
uint16 samplesperpixel=1;
uint32 rowsperstrip=(DWORD)-1;
uint16 photometric=0;
uint16 compression=1;
uint16 orientation=ORIENTATION_TOPLEFT; //<vho>
uint16 res_unit; //<Trifon>
uint32 x, y;
float resolution, offset;
BOOL isRGB;
BYTE *bits; //pointer to source data
BYTE *bits2; //pointer to destination data
cx_try
{
//check if it's a tiff file
if (!m_tif)
cx_throw("Error encountered while opening TIFF file");
// <Robert Abram> - 12/2002 : get NumFrames directly, instead of looping
// info.nNumFrames=0;
// while(TIFFSetDirectory(m_tif,(uint16)info.nNumFrames)) info.nNumFrames++;
info.nNumFrames = TIFFNumberOfDirectories(m_tif);
if (!TIFFSetDirectory(m_tif, (uint16)info.nFrame))
cx_throw("Error: page not present in TIFF file");
//get image info
TIFFGetField(m_tif, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(m_tif, TIFFTAG_IMAGELENGTH, &height);
TIFFGetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
TIFFGetField(m_tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
TIFFGetField(m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
TIFFGetField(m_tif, TIFFTAG_PHOTOMETRIC, &photometric);
TIFFGetField(m_tif, TIFFTAG_ORIENTATION, &orientation);
if (info.nEscape == -1) {
// Return output dimensions only
head.biWidth = width;
head.biHeight = height;
info.dwType = CXIMAGE_FORMAT_TIF;
cx_throw("output dimensions returned");
}
TIFFGetFieldDefaulted(m_tif, TIFFTAG_RESOLUTIONUNIT, &res_unit);
if (TIFFGetField(m_tif, TIFFTAG_XRESOLUTION, &resolution))
{
if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f);
SetXDPI((long)resolution);
}
if (TIFFGetField(m_tif, TIFFTAG_YRESOLUTION, &resolution))
{
if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f);
SetYDPI((long)resolution);
}
if (TIFFGetField(m_tif, TIFFTAG_XPOSITION, &offset)) info.xOffset = (long)offset;
if (TIFFGetField(m_tif, TIFFTAG_YPOSITION, &offset)) info.yOffset = (long)offset;
head.biClrUsed=0;
info.nBkgndIndex =-1;
if (rowsperstrip>height){
rowsperstrip=height;
TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
}
isRGB = /*(bitspersample >= 8) && (VK: it is possible so for RGB to have < 8 bpp!)*/
(photometric == PHOTOMETRIC_RGB) ||
(photometric == PHOTOMETRIC_YCBCR) ||
(photometric == PHOTOMETRIC_SEPARATED) ||
(photometric == PHOTOMETRIC_LOGL) ||
(photometric == PHOTOMETRIC_LOGLUV);
if (isRGB){
head.biBitCount=24;
}else{
if ((photometric==PHOTOMETRIC_MINISBLACK)||(photometric==PHOTOMETRIC_MINISWHITE)||(photometric==PHOTOMETRIC_PALETTE)){
if (bitspersample == 1){
head.biBitCount=1; //B&W image
head.biClrUsed =2;
} else if (bitspersample == 4) {
head.biBitCount=4; //16 colors gray scale
head.biClrUsed =16;
} else {
head.biBitCount=8; //gray scale
head.biClrUsed =256;
}
} else if (bitspersample == 4) {
head.biBitCount=4; // 16 colors
head.biClrUsed=16;
} else {
head.biBitCount=8; //256 colors
head.biClrUsed=256;
}
if ((bitspersample > 8) && (photometric==PHOTOMETRIC_PALETTE)) // + VK + (BIG palette! => convert to RGB)
{ head.biBitCount=24;
head.biClrUsed =0;
}
}
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
Create(width,height,head.biBitCount,CXIMAGE_FORMAT_TIF); //image creation
if (!pDib) cx_throw("CxImageTIF can't create image");
#if CXIMAGE_SUPPORT_ALPHA
if (samplesperpixel==4) AlphaCreate(); //add alpha support for 32bpp tiffs
if (samplesperpixel==2 && bitspersample==8) AlphaCreate(); //add alpha support for 8bpp + alpha
#endif //CXIMAGE_SUPPORT_ALPHA
TIFFGetField(m_tif, TIFFTAG_COMPRESSION, &compression);
SetCodecOption(compression); // <DPR> save original compression type
if (isRGB) {
// Read the whole image into one big RGBA buffer using
// the traditional TIFFReadRGBAImage() API that we trust.
uint32* raster; // retrieve RGBA image
uint32 *row;
raster = (uint32*)_TIFFmalloc(width * height * sizeof (uint32));
if (raster == NULL) cx_throw("No space for raster buffer");
// Read the image in one chunk into an RGBA array
if(!TIFFReadRGBAImage(m_tif, width, height, raster, 1)) {
_TIFFfree(raster);
cx_throw("Corrupted TIFF file!");
}
// read the raster lines and save them in the DIB
// with RGB mode, we have to change the order of the 3 samples RGB
row = &raster[0];
bits2 = info.pImage;
for (y = 0; y < height; y++) {
if (info.nEscape){ // <vho> - cancel decoding
_TIFFfree(raster);
cx_throw("Cancelled");
}
bits = bits2;
for (x = 0; x < width; x++) {
*bits++ = (BYTE)TIFFGetB(row[x]);
*bits++ = (BYTE)TIFFGetG(row[x]);
*bits++ = (BYTE)TIFFGetR(row[x]);
#if CXIMAGE_SUPPORT_ALPHA
if (samplesperpixel==4) AlphaSet(x,y,(BYTE)TIFFGetA(row[x]));
#endif //CXIMAGE_SUPPORT_ALPHA
}
row += width;
bits2 += info.dwEffWidth;
}
_TIFFfree(raster);
} else {
int BIG_palette = (bitspersample > 8) && // + VK
(photometric==PHOTOMETRIC_PALETTE);
if (BIG_palette && (bitspersample > 24)) // + VK
cx_throw("Too big palette to handle"); // + VK
RGBQUAD *pal;
pal=(RGBQUAD*)calloc(BIG_palette ? 1<<bitspersample : 256,sizeof(RGBQUAD));
// ! VK: it coasts nothing but more correct to use 256 as temp palette storage
// ! VK: but for case of BIG palette it just copied
if (pal==NULL) cx_throw("Unable to allocate TIFF palette");
int bpp = bitspersample <= 8 ? bitspersample : 8; // + VK (to use instead of bitspersample for case of > 8)
// set up the colormap based on photometric
switch(photometric) {
case PHOTOMETRIC_MINISBLACK: // bitmap and greyscale image types
case PHOTOMETRIC_MINISWHITE:
if (bitspersample == 1) { // Monochrome image
if (photometric == PHOTOMETRIC_MINISBLACK) {
pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
} else {
pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 255;
}
} else { // need to build the scale for greyscale images
if (photometric == PHOTOMETRIC_MINISBLACK) {
for (int i=0; i<(1<<bpp); i++){
pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (BYTE)(i*(255/((1<<bpp)-1)));
}
} else {
for (int i=0; i<(1<<bpp); i++){
pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (BYTE)(255-i*(255/((1<<bpp)-1)));
}
}
}
break;
case PHOTOMETRIC_PALETTE: // color map indexed
uint16 *red;
uint16 *green;
uint16 *blue;
TIFFGetField(m_tif, TIFFTAG_COLORMAP, &red, &green, &blue);
// Is the palette 16 or 8 bits ?
BOOL Palette16Bits = /*FALSE*/ BIG_palette;
if (!BIG_palette) {
int n= 1<<bpp;
while (n-- > 0) {
if (red[n] >= 256 || green[n] >= 256 || blue[n] >= 256) {
Palette16Bits=TRUE;
break;
}
}
}
// load the palette in the DIB
for (int i = (1 << ( BIG_palette ? bitspersample : bpp )) - 1; i >= 0; i--) {
if (Palette16Bits) {
pal[i].rgbRed =(BYTE) CVT(red[i]);
pal[i].rgbGreen = (BYTE) CVT(green[i]);
pal[i].rgbBlue = (BYTE) CVT(blue[i]);
} else {
pal[i].rgbRed = (BYTE) red[i];
pal[i].rgbGreen = (BYTE) green[i];
pal[i].rgbBlue = (BYTE) blue[i];
}
}
break;
}
if (!BIG_palette) { // + VK (BIG palette is stored until image is ready)
SetPalette(pal,/*head.biClrUsed*/ 1<<bpp); //palette assign // * VK
free(pal);
pal = NULL;
}
// read the tiff lines and save them in the DIB
uint32 nrow;
uint32 ys;
int line = CalculateLine(width, bitspersample * samplesperpixel);
long bitsize = TIFFStripSize(m_tif);
//verify bitsize: could be wrong if StripByteCounts is missing.
if (bitsize<(long)(head.biSizeImage*samplesperpixel))
bitsize = head.biSizeImage*samplesperpixel;
if ((bitspersample > 8) && (bitspersample != 16)) // + VK (for bitspersample == 9..15,17..32..64
bitsize *= (bitspersample + 7)/8;
int tiled_image = TIFFIsTiled(m_tif);
uint32 tw=0, tl=0;
BYTE* tilebuf=NULL;
if (tiled_image){
TIFFGetField(m_tif, TIFFTAG_TILEWIDTH, &tw);
TIFFGetField(m_tif, TIFFTAG_TILELENGTH, &tl);
rowsperstrip = tl;
bitsize = TIFFTileSize(m_tif) * (int)(1+width/tw);
tilebuf = (BYTE*)malloc(TIFFTileSize(m_tif));
}
bits = (BYTE*)malloc(bitspersample==16? bitsize*2 : bitsize); // * VK
BYTE * bits16 = NULL; // + VK
int line16 = 0; // + VK
if (!tiled_image && bitspersample==16) { // + VK +
line16 = line;
line = CalculateLine(width, 8 * samplesperpixel);
bits16 = bits;
bits = (BYTE*)malloc(bitsize);
}
if (bits==NULL){
if (bits16) free(bits16); // + VK
if (pal) free(pal); // + VK
if (tilebuf)free(tilebuf); // + VK
cx_throw("CxImageTIF can't allocate memory");
}
#ifdef FIX_16BPP_DARKIMG // + VK: for each line, store shift count bits used to fix it
BYTE* row_shifts = NULL;
if (bits16) row_shifts = (BYTE*)malloc(height);
#endif
for (ys = 0; ys < height; ys += rowsperstrip) {
if (info.nEscape){ // <vho> - cancel decoding
free(bits);
cx_throw("Cancelled");
}
nrow = (ys + rowsperstrip > height ? height - ys : rowsperstrip);
if (tiled_image){
uint32 imagew = TIFFScanlineSize(m_tif);
uint32 tilew = TIFFTileRowSize(m_tif);
int iskew = imagew - tilew;
uint8* bufp = (uint8*) bits;
uint32 colb = 0;
for (uint32 col = 0; col < width; col += tw) {
if (TIFFReadTile(m_tif, tilebuf, col, ys, 0, 0) < 0){
free(tilebuf);
free(bits);
cx_throw("Corrupted tiled TIFF file!");
}
if (colb + tw > imagew) {
uint32 owidth = imagew - colb;
uint32 oskew = tilew - owidth;
TileToStrip(bufp + colb, tilebuf, nrow, owidth, oskew + iskew, oskew );
} else {
TileToStrip(bufp + colb, tilebuf, nrow, tilew, iskew, 0);
}
colb += tilew;
}
} else {
if (TIFFReadEncodedStrip(m_tif, TIFFComputeStrip(m_tif, ys, 0),
(bits16? bits16 : bits), nrow * (bits16 ? line16 : line)) == -1) { // * VK
#ifdef NOT_IGNORE_CORRUPTED
free(bits);
if (bits16) free(bits16); // + VK
cx_throw("Corrupted TIFF file!");
#else
break;
#endif
}
}
for (y = 0; y < nrow; y++) {
long offset=(nrow-y-1)*line;
if ((bitspersample==16) && !BIG_palette) { // * VK
long offset16 = (nrow-y-1)*line16; // + VK
if (bits16) { // + VK +
#ifdef FIX_16BPP_DARKIMG
int the_shift;
BYTE hi_byte, hi_max=0;
DWORD xi;
for (xi=0;xi<(uint32)line;xi++) {
hi_byte = bits16[xi*2+offset16+1];
if(hi_byte>hi_max)
hi_max = hi_byte;
}
the_shift = (hi_max == 0) ? 8 : 0;
if (!the_shift)
while( ! (hi_max & 0x80) ) {
the_shift++;
hi_max <<= 1;
}
row_shifts[height-ys-nrow+y] = the_shift;
the_shift = 8 - the_shift;
for (xi=0;xi<(uint32)line;xi++)
bits[xi+offset]= ((bits16[xi*2+offset16+1]<<8) | bits16[xi*2+offset16]) >> the_shift;
#else
for (DWORD xi=0;xi<(uint32)line;xi++)
bits[xi+offset]=bits16[xi*2+offset16+1];
#endif
} else {
for (DWORD xi=0;xi<width;xi++)
bits[xi+offset]=bits[xi*2+offset+1];
}
}
if (samplesperpixel==1) {
if (BIG_palette)
if (bits16) {
long offset16 = (nrow-y-1)*line16; // + VK
MoveBitsPal( info.pImage + info.dwEffWidth * (height-ys-nrow+y),
bits16 + offset16, width, bitspersample, pal );
} else
MoveBitsPal( info.pImage + info.dwEffWidth * (height-ys-nrow+y),
bits + offset, width, bitspersample, pal );
else if ((bitspersample == head.biBitCount) ||
(bitspersample == 16)) //simple 8bpp, 4bpp image or 16bpp
memcpy(info.pImage+info.dwEffWidth*(height-ys-nrow+y),bits+offset,info.dwEffWidth);
else
MoveBits( info.pImage + info.dwEffWidth * (height-ys-nrow+y),
bits + offset, width, bitspersample );
} else if (samplesperpixel==2) { //8bpp image with alpha layer
int xi=0;
int ii=0;
int yi=height-ys-nrow+y;
#if CXIMAGE_SUPPORT_ALPHA
if (!pAlpha) AlphaCreate(); // + VK
#endif //CXIMAGE_SUPPORT_ALPHA
while (ii<line){
SetPixelIndex(xi,yi,bits[ii+offset]);
#if CXIMAGE_SUPPORT_ALPHA
AlphaSet(xi,yi,bits[ii+offset+1]);
#endif //CXIMAGE_SUPPORT_ALPHA
ii+=2;
xi++;
if (xi>=(int)width){
yi--;
xi=0;
}
}
} else { //photometric==PHOTOMETRIC_CIELAB
if (head.biBitCount!=24){ //fix image
Create(width,height,24,CXIMAGE_FORMAT_TIF);
#if CXIMAGE_SUPPORT_ALPHA
if (samplesperpixel==4) AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA
}
int xi=0;
uint32 ii=0;
int yi=height-ys-nrow+y;
RGBQUAD c;
int l,a,b,bitsoffset;
double p,cx,cy,cz,cr,cg,cb;
while (ii</*line*/width){ // * VK
bitsoffset = ii*samplesperpixel+offset;
l=bits[bitsoffset];
a=bits[bitsoffset+1];
b=bits[bitsoffset+2];
if (a>127) a-=256;
if (b>127) b-=256;
// lab to xyz
p = (l/2.55 + 16) / 116.0;
cx = pow( p + a * 0.002, 3);
cy = pow( p, 3);
cz = pow( p - b * 0.005, 3);
// white point
cx*=0.95047;
//cy*=1.000;
cz*=1.0883;
// xyz to rgb
cr = 3.240479 * cx - 1.537150 * cy - 0.498535 * cz;
cg = -0.969256 * cx + 1.875992 * cy + 0.041556 * cz;
cb = 0.055648 * cx - 0.204043 * cy + 1.057311 * cz;
if ( cr > 0.00304 ) cr = 1.055 * pow(cr,0.41667) - 0.055;
else cr = 12.92 * cr;
if ( cg > 0.00304 ) cg = 1.055 * pow(cg,0.41667) - 0.055;
else cg = 12.92 * cg;
if ( cb > 0.00304 ) cb = 1.055 * pow(cb,0.41667) - 0.055;
else cb = 12.92 * cb;
c.rgbRed =(BYTE)max(0,min(255,(int)(cr*255)));
c.rgbGreen=(BYTE)max(0,min(255,(int)(cg*255)));
c.rgbBlue =(BYTE)max(0,min(255,(int)(cb*255)));
SetPixelColor(xi,yi,c);
#if CXIMAGE_SUPPORT_ALPHA
if (samplesperpixel==4) AlphaSet(xi,yi,bits[bitsoffset+3]);
#endif //CXIMAGE_SUPPORT_ALPHA
ii++;
xi++;
if (xi>=(int)width){
yi--;
xi=0;
}
}
}
}
}
free(bits);
if (bits16) free(bits16);
#ifdef FIX_16BPP_DARKIMG
if (row_shifts && (samplesperpixel == 1) && (bitspersample==16) && !BIG_palette) {
// 1. calculate maximum necessary shift
int min_row_shift = 8;
for( y=0; y<height; y++ ) {
if (min_row_shift > row_shifts[y]) min_row_shift = row_shifts[y];
}
// 2. for rows having less shift value, correct such rows:
for( y=0; y<height; y++ ) {
if (min_row_shift < row_shifts[y]) {
int need_shift = row_shifts[y] - min_row_shift;
BYTE* data = info.pImage + info.dwEffWidth * y;
for( x=0; x<width; x++, data++ )
*data >>= need_shift;
}
}
}
if (row_shifts) free( row_shifts );
#endif
if (tiled_image) free(tilebuf);
if (pal) free(pal);
switch(orientation){
case ORIENTATION_TOPRIGHT: /* row 0 top, col 0 rhs */
Mirror();
break;
case ORIENTATION_BOTRIGHT: /* row 0 bottom, col 0 rhs */
Flip();
Mirror();
break;
case ORIENTATION_BOTLEFT: /* row 0 bottom, col 0 lhs */
Flip();
break;
case ORIENTATION_LEFTTOP: /* row 0 lhs, col 0 top */
RotateRight();
Mirror();
break;
case ORIENTATION_RIGHTTOP: /* row 0 rhs, col 0 top */
RotateLeft();
break;
case ORIENTATION_RIGHTBOT: /* row 0 rhs, col 0 bottom */
RotateLeft();
Mirror();
break;
case ORIENTATION_LEFTBOT: /* row 0 lhs, col 0 bottom */
RotateRight();
break;
}
}
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
if (m_tif) TIFFClose(m_tif);
if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_TIF) return true;
return false;
}
TIFFClose(m_tif);
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageTIF::Encode(CxFile * hFile, bool bAppend)
{
cx_try
{
if (hFile==NULL) cx_throw(CXIMAGE_ERR_NOFILE);
if (pDib==NULL) cx_throw(CXIMAGE_ERR_NOIMAGE);
// <RJ> replaced "w+b" with "a", to append an image directly on an existing file
if (m_tif2==NULL) m_tif2=_TIFFOpenEx(hFile, "a");
if (m_tif2==NULL) cx_throw("initialization fail");
if (bAppend || m_pages) m_multipage=true;
m_pages++;
if (!EncodeBody(m_tif2,m_multipage,m_pages,m_pages)) cx_throw("Error saving TIFF file");
if (bAppend) {
if (!TIFFWriteDirectory(m_tif2)) cx_throw("Error saving TIFF directory");
}
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
if (m_tif2){
TIFFClose(m_tif2);
m_tif2=NULL;
m_multipage=false;
m_pages=0;
}
return false;
}
if (!bAppend){
TIFFClose(m_tif2);
m_tif2=NULL;
m_multipage=false;
m_pages=0;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// Thanks to Abe <God(dot)bless(at)marihuana(dot)com>
bool CxImageTIF::Encode(CxFile * hFile, CxImage ** pImages, int pagecount)
{
cx_try
{
if (hFile==NULL) cx_throw("invalid file pointer");
if (pImages==NULL || pagecount<=0) cx_throw("multipage TIFF, no images!");
int i;
for (i=0; i<pagecount; i++){
if (pImages[i]==NULL)
cx_throw("Bad image pointer");
if (!(pImages[i]->IsValid()))
cx_throw("Empty image");
}
CxImageTIF ghost;
for (i=0; i<pagecount; i++){
ghost.Ghost(pImages[i]);
if (!ghost.Encode(hFile,true)) cx_throw("Error saving TIFF file");
}
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImageTIF::EncodeBody(TIFF *m_tif, bool multipage, int page, int pagecount)
{
uint32 height=head.biHeight;
uint32 width=head.biWidth;
uint16 bitcount=head.biBitCount;
uint16 bitspersample;
uint16 samplesperpixel;
uint16 photometric=0;
uint16 compression;
// uint16 pitch;
// int line;
uint32 x, y;
samplesperpixel = ((bitcount == 24) || (bitcount == 32)) ? (BYTE)3 : (BYTE)1;
#if CXIMAGE_SUPPORT_ALPHA
if (bitcount==24 && AlphaIsValid()) { bitcount=32; samplesperpixel=4; }
#endif //CXIMAGE_SUPPORT_ALPHA
bitspersample = bitcount / samplesperpixel;
//set the PHOTOMETRIC tag
RGBQUAD *rgb = GetPalette();
switch (bitcount) {
case 1:
if (CompareColors(&rgb[0],&rgb[1])<0) {
/* <abe> some viewers do not handle PHOTOMETRIC_MINISBLACK:
* let's transform the image in PHOTOMETRIC_MINISWHITE
*/
//invert the colors
RGBQUAD tempRGB=GetPaletteColor(0);
SetPaletteColor(0,GetPaletteColor(1));
SetPaletteColor(1,tempRGB);
//invert the pixels
BYTE *iSrc=info.pImage;
for (unsigned long i=0;i<head.biSizeImage;i++){
*iSrc=(BYTE)~(*(iSrc));
iSrc++;
}
photometric = PHOTOMETRIC_MINISWHITE;
//photometric = PHOTOMETRIC_MINISBLACK;
} else {
photometric = PHOTOMETRIC_MINISWHITE;
}
break;
case 4: // Check if the DIB has a color or a greyscale palette
case 8:
photometric = PHOTOMETRIC_MINISBLACK; //default to gray scale
for (x = 0; x < head.biClrUsed; x++) {
if ((rgb->rgbRed != x)||(rgb->rgbRed != rgb->rgbGreen)||(rgb->rgbRed != rgb->rgbBlue)){
photometric = PHOTOMETRIC_PALETTE;
break;
}
rgb++;
}
break;
case 24:
case 32:
photometric = PHOTOMETRIC_RGB;
break;
}
#if CXIMAGE_SUPPORT_ALPHA
if (AlphaIsValid() && bitcount==8) samplesperpixel=2; //8bpp + alpha layer
#endif //CXIMAGE_SUPPORT_ALPHA
// line = CalculateLine(width, bitspersample * samplesperpixel);
// pitch = (uint16)CalculatePitch(line);
//prepare the palette struct
RGBQUAD pal[256];
if (GetPalette()){
BYTE b;
memcpy(pal,GetPalette(),GetPaletteSize());
for(WORD a=0;a<head.biClrUsed;a++){ //swap blue and red components
b=pal[a].rgbBlue; pal[a].rgbBlue=pal[a].rgbRed; pal[a].rgbRed=b;
}
}
// handle standard width/height/bpp stuff
TIFFSetField(m_tif, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(m_tif, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
TIFFSetField(m_tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
TIFFSetField(m_tif, TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField(m_tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); // single image plane
TIFFSetField(m_tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
uint32 rowsperstrip = TIFFDefaultStripSize(m_tif, (uint32) -1); //<REC> gives better compression
TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
// handle metrics
TIFFSetField(m_tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
TIFFSetField(m_tif, TIFFTAG_XRESOLUTION, (float)info.xDPI);
TIFFSetField(m_tif, TIFFTAG_YRESOLUTION, (float)info.yDPI);
// TIFFSetField(m_tif, TIFFTAG_XPOSITION, (float)info.xOffset);
// TIFFSetField(m_tif, TIFFTAG_YPOSITION, (float)info.yOffset);
// multi-paging - Thanks to Abe <God(dot)bless(at)marihuana(dot)com>
if (multipage)
{
char page_number[20];
sprintf(page_number, "Page %d", page);
TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
TIFFSetField(m_tif, TIFFTAG_PAGENUMBER, page,pagecount);
TIFFSetField(m_tif, TIFFTAG_PAGENAME, page_number);
} else {
TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, 0);
}
// palettes (image colormaps are automatically scaled to 16-bits)
if (photometric == PHOTOMETRIC_PALETTE) {
uint16 *r, *g, *b;
r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * 256);
g = r + 256;
b = g + 256;
for (int i = 255; i >= 0; i--) {
b[i] = (uint16)SCALE((uint16)pal[i].rgbRed);
g[i] = (uint16)SCALE((uint16)pal[i].rgbGreen);
r[i] = (uint16)SCALE((uint16)pal[i].rgbBlue);
}
TIFFSetField(m_tif, TIFFTAG_COLORMAP, r, g, b);
_TIFFfree(r);
}
// compression
if (GetCodecOption(CXIMAGE_FORMAT_TIF)) {
compression = (WORD)GetCodecOption(CXIMAGE_FORMAT_TIF);
} else {
switch (bitcount) {
case 1 :
compression = COMPRESSION_CCITTFAX4;
break;
case 4 :
case 8 :
compression = COMPRESSION_LZW;
break;
case 24 :
case 32 :
compression = COMPRESSION_JPEG;
break;
default :
compression = COMPRESSION_NONE;
break;
}
}
TIFFSetField(m_tif, TIFFTAG_COMPRESSION, compression);
switch (compression) {
case COMPRESSION_JPEG:
TIFFSetField(m_tif, TIFFTAG_JPEGQUALITY, GetJpegQuality());
TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, ((7+rowsperstrip)>>3)<<3);
break;
case COMPRESSION_LZW:
if (bitcount>=8) TIFFSetField(m_tif, TIFFTAG_PREDICTOR, 2);
break;
}
// read the DIB lines from bottom to top and save them in the TIF
BYTE *bits;
switch(bitcount) {
case 1 :
case 4 :
case 8 :
{
if (samplesperpixel==1){
bits = (BYTE*)malloc(info.dwEffWidth);
if (!bits) return false;
for (y = 0; y < height; y++) {
memcpy(bits,info.pImage + (height - y - 1)*info.dwEffWidth,info.dwEffWidth);
if (TIFFWriteScanline(m_tif,bits, y, 0)==-1){
free(bits);
return false;
}
}
free(bits);
}
#if CXIMAGE_SUPPORT_ALPHA
else { //8bpp + alpha layer
bits = (BYTE*)malloc(2*width);
if (!bits) return false;
for (y = 0; y < height; y++) {
for (x=0;x<width;x++){
bits[2*x]=BlindGetPixelIndex(x,height - y - 1);
bits[2*x+1]=AlphaGet(x,height - y - 1);
}
if (TIFFWriteScanline(m_tif,bits, y, 0)==-1) {
free(bits);
return false;
}
}
free(bits);
}
#endif //CXIMAGE_SUPPORT_ALPHA
break;
}
case 24:
{
BYTE *buffer = (BYTE *)malloc(info.dwEffWidth);
if (!buffer) return false;
for (y = 0; y < height; y++) {
// get a pointer to the scanline
memcpy(buffer, info.pImage + (height - y - 1)*info.dwEffWidth, info.dwEffWidth);
// TIFFs store color data RGB instead of BGR
BYTE *pBuf = buffer;
for (x = 0; x < width; x++) {
BYTE tmp = pBuf[0];
pBuf[0] = pBuf[2];
pBuf[2] = tmp;
pBuf += 3;
}
// write the scanline to disc
if (TIFFWriteScanline(m_tif, buffer, y, 0)==-1){
free(buffer);
return false;
}
}
free(buffer);
break;
}
case 32 :
{
#if CXIMAGE_SUPPORT_ALPHA
BYTE *buffer = (BYTE *)malloc((info.dwEffWidth*4)/3);
if (!buffer) return false;
for (y = 0; y < height; y++) {
// get a pointer to the scanline
memcpy(buffer, info.pImage + (height - y - 1)*info.dwEffWidth, info.dwEffWidth);
// TIFFs store color data RGB instead of BGR
BYTE *pSrc = buffer + 3 * width;
BYTE *pDst = buffer + 4 * width;
for (x = 0; x < width; x++) {
pDst-=4;
pSrc-=3;
pDst[3] = AlphaGet(width-x-1,height-y-1);
pDst[2] = pSrc[0];
pDst[1] = pSrc[1];
pDst[0] = pSrc[2];
}
// write the scanline to disc
if (TIFFWriteScanline(m_tif, buffer, y, 0)==-1){
free(buffer);
return false;
}
}
free(buffer);
#endif //CXIMAGE_SUPPORT_ALPHA
break;
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
void CxImageTIF::TileToStrip(uint8* out, uint8* in, uint32 rows, uint32 cols, int outskew, int inskew)
{
while (rows-- > 0) {
uint32 j = cols;
while (j-- > 0)
*out++ = *in++;
out += outskew;
in += inskew;
}
}
////////////////////////////////////////////////////////////////////////////////
TIFF* CxImageTIF::TIFFOpenEx(CxFile * hFile)
{
if (hFile) return _TIFFOpenEx(hFile, "rb");
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
void CxImageTIF::TIFFCloseEx(TIFF* tif)
{
if (tif) TIFFClose(tif);
}
////////////////////////////////////////////////////////////////////////////////
void CxImageTIF::MoveBits( BYTE* dest, BYTE* from, int count, int bpp )
{ int offbits = 0;
uint16 w;
uint32 d;
if (bpp <= 8) {
while (count-- > 0) {
if (offbits + bpp <= 8)
w = *from >> (8 - offbits - bpp);
else {
w = *from++ << (offbits + bpp - 8);
w |= *from >> (16 - offbits - bpp);
}
offbits += bpp;
if (offbits >= 8) {
offbits -= 8;
if (offbits == 0) from++;
}
*dest++ = (BYTE)w & ((1 << bpp)-1);
}
} else if (bpp < 16) {
while (count-- > 0) {
d = (*from << 24) | (from[1]<<16) | (from[2]<<8) | from[3];
d >>= (24 - offbits);
*dest++ = (BYTE) ( d );
offbits += bpp;
while (offbits >= 8) {
from++;
offbits -= 8;
}
}
} else if (bpp < 32) {
while (count-- > 0) {
d = (*from << 24) | (from[1]<<16) | (from[2]<<8) | from[3];
//d = *(uint32*)from;
*dest++ = (BYTE) ( d >> (offbits + bpp - 8) );
offbits += bpp;
while (offbits >= 8) {
from++;
offbits -= 8;
}
}
} else {
while (count-- > 0) {
d = *(uint32*)from;
*dest++ = (BYTE) (d >> 24);
from += 4;
}
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImageTIF::MoveBitsPal( BYTE* dest, BYTE*from, int count, int bpp, RGBQUAD* pal )
{ int offbits = 0;
uint32 d;
uint16 palidx;
while (count-- > 0) {
d = (*from << 24) | ( *( from + 1 ) << 16 )
| ( *( from + 2 ) << 8 )
| ( *( from + 3 ) );
palidx = (uint16) (d >> (32 - offbits - bpp));
if (bpp < 16) {
palidx <<= 16-bpp;
palidx = (palidx >> 8) | (palidx <<8);
palidx >>= 16-bpp;
} else palidx = (palidx >> 8) | (palidx << 8);
*dest++ = pal[palidx].rgbBlue;
*dest++ = pal[palidx].rgbGreen;
*dest++ = pal[palidx].rgbRed;
offbits += bpp;
while (offbits >= 8) {
from++;
offbits -= 8;
}
}
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_TIF

View File

@@ -1,62 +0,0 @@
/*
* File: ximatif.h
* Purpose: TIFF Image Class Loader and Writer
*/
/* ==========================================================
* CxImageTIF (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
*
* Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
*
* Special thanks to Abe <God(dot)bless(at)marihuana(dot)com> for MultiPageTIFF code.
*
* LibTIFF is:
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
* ==========================================================
*/
#if !defined(__ximatif_h)
#define __ximatif_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_TIF
#include "../tiff/tiffio.h"
class DLL_EXP CxImageTIF: public CxImage
{
public:
CxImageTIF(): CxImage(CXIMAGE_FORMAT_TIF) {m_tif2=NULL; m_multipage=false; m_pages=0;}
~CxImageTIF();
TIFF* TIFFOpenEx(CxFile * hFile);
void TIFFCloseEx(TIFF* tif);
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_TIF);}
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_TIF);}
bool Decode(CxFile * hFile);
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile, bool bAppend=false);
bool Encode(CxFile * hFile, CxImage ** pImages, int pagecount);
bool Encode(FILE *hFile, bool bAppend=false) { CxIOFile file(hFile); return Encode(&file,bAppend); }
bool Encode(FILE *hFile, CxImage ** pImages, int pagecount)
{ CxIOFile file(hFile); return Encode(&file, pImages, pagecount); }
#endif // CXIMAGE_SUPPORT_ENCODE
protected:
void TileToStrip(uint8* out, uint8* in, uint32 rows, uint32 cols, int outskew, int inskew);
bool EncodeBody(TIFF *m_tif, bool multipage=false, int page=0, int pagecount=0);
TIFF *m_tif2;
bool m_multipage;
int m_pages;
void MoveBits( BYTE* dest, BYTE* from, int count, int bpp );
void MoveBitsPal( BYTE* dest, BYTE*from, int count, int bpp, RGBQUAD* pal );
};
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,134 +0,0 @@
/*
* File: ximawbmp.cpp
* Purpose: Platform Independent WBMP Image Class Loader and Writer
* 12/Jul/2002 Davide Pizzolato - www.xdp.it
* CxImage version 6.0.0 02/Feb/2008
*/
#include "ximawbmp.h"
#if CXIMAGE_SUPPORT_WBMP
#include "ximaiter.h"
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageWBMP::Decode(CxFile *hFile)
{
if (hFile == NULL) return false;
WBMPHEADER wbmpHead;
cx_try
{
ReadOctet(hFile, &wbmpHead.Type);
DWORD dat;
ReadOctet(hFile, &dat);
wbmpHead.FixHeader = (BYTE)dat;
ReadOctet(hFile, &wbmpHead.ImageWidth);
ReadOctet(hFile, &wbmpHead.ImageHeight);
if (hFile->Eof())
cx_throw("Not a WBMP");
if (wbmpHead.Type != 0)
cx_throw("Unsupported WBMP type");
head.biWidth = wbmpHead.ImageWidth;
head.biHeight= wbmpHead.ImageHeight;
if (head.biWidth<=0 || head.biHeight<=0)
cx_throw("Corrupted WBMP");
if (info.nEscape == -1){
info.dwType = CXIMAGE_FORMAT_WBMP;
return true;
}
Create(head.biWidth, head.biHeight, 1, CXIMAGE_FORMAT_WBMP);
if (!IsValid()) cx_throw("WBMP Create failed");
SetGrayPalette();
int linewidth=(head.biWidth+7)/8;
CImageIterator iter(this);
iter.Upset();
for (long y=0; y < head.biHeight; y++){
hFile->Read(iter.GetRow(),linewidth,1);
iter.PrevRow();
}
} cx_catch {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
return FALSE;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImageWBMP::ReadOctet(CxFile * hFile, DWORD *data)
{
BYTE c;
*data = 0;
do {
if (hFile->Eof()) return false;
c = (BYTE)hFile->GetC();
*data <<= 7;
*data |= (c & 0x7F);
} while ((c&0x80)!=0);
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageWBMP::Encode(CxFile * hFile)
{
if (EncodeSafeCheck(hFile)) return false;
//check format limits
if (head.biBitCount!=1){
strcpy(info.szLastError,"Can't save this image as WBMP");
return false;
}
WBMPHEADER wbmpHead;
wbmpHead.Type=0;
wbmpHead.FixHeader=0;
wbmpHead.ImageWidth=head.biWidth;
wbmpHead.ImageHeight=head.biHeight;
// Write the file header
hFile->PutC('\0');
hFile->PutC('\0');
WriteOctet(hFile,wbmpHead.ImageWidth);
WriteOctet(hFile,wbmpHead.ImageHeight);
// Write the pixels
int linewidth=(wbmpHead.ImageWidth+7)/8;
CImageIterator iter(this);
iter.Upset();
for (DWORD y=0; y < wbmpHead.ImageHeight; y++){
hFile->Write(iter.GetRow(),linewidth,1);
iter.PrevRow();
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImageWBMP::WriteOctet(CxFile * hFile, const DWORD data)
{
int ns = 0;
while (data>>(ns+7)) ns+=7;
while (ns>0){
if (!hFile->PutC(0x80 | (BYTE)(data>>ns))) return false;
ns-=7;
}
if (!(hFile->PutC((BYTE)(0x7F & data)))) return false;
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_WBMP

View File

@@ -1,49 +0,0 @@
/*
* File: ximawbmp.h
* Purpose: WBMP Image Class Loader and Writer
*/
/* ==========================================================
* CxImageWBMP (c) 12/Jul/2002 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
* ==========================================================
*/
#if !defined(__ximaWBMP_h)
#define __ximaWBMP_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_WBMP
class CxImageWBMP: public CxImage
{
#pragma pack(1)
typedef struct tagWbmpHeader
{
DWORD Type; // 0
BYTE FixHeader; // 0
DWORD ImageWidth; // Image Width
DWORD ImageHeight; // Image Height
} WBMPHEADER;
#pragma pack()
public:
CxImageWBMP(): CxImage(CXIMAGE_FORMAT_WBMP) {}
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_WBMP);}
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_WBMP);}
bool Decode(CxFile * hFile);
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
protected:
bool ReadOctet(CxFile * hFile, DWORD *data);
public:
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile);
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
protected:
bool WriteOctet(CxFile * hFile, const DWORD data);
#endif // CXIMAGE_SUPPORT_ENCODE
};
#endif
#endif

View File

@@ -1,483 +0,0 @@
/*
*********************************************************************
* File: ximawmf.cpp
* Purpose: Windows Metafile Class Loader and Writer
* Author: Volker Horch - vhorch@gmx.de
* created: 13-Jun-2002
*
* Note: If the code below works, i wrote it.
* If it doesn't work, i don't know who wrote it.
*********************************************************************
*/
/*
*********************************************************************
Note by Author:
*********************************************************************
Metafile Formats:
=================
There are 2 kinds of Windows Metafiles:
- Standard Windows Metafile
- Placeable Windows Metafile
A StandardWindows Metafile looks like:
- Metafile Header (MEATAHEADER)
- Metafile Records
A Placeable Metafile looks like:
- Aldus Header (METAFILEHEADER)
- Metafile Header (METAHEADER)
- Metafile Records
The "Metafile Header" and the "Metafile Records" are the same
for both formats. However, the Standard Metafile does not contain any
information about the original dimensions or x/y ratio of the Metafile.
I decided, to allow only placeable Metafiles here. If you also want to
enable Standard Metafiles, you will have to guess the dimensions of
the image.
*********************************************************************
Limitations: see ximawmf.h
you may configure some stuff there
*********************************************************************
*/
#include "ximawmf.h"
#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageWMF::Decode(CxFile *hFile, long nForceWidth, long nForceHeight)
{
if (hFile == NULL) return false;
HENHMETAFILE hMeta;
HDC hDC;
int cx,cy;
//save the current position of the file
long pos = hFile->Tell();
// Read the Metafile and convert to an Enhanced Metafile
METAFILEHEADER mfh;
hMeta = ConvertWmfFiletoEmf(hFile, &mfh);
if (hMeta) { // ok, it's a WMF
/////////////////////////////////////////////////////////////////////
// We use the original WMF size information, because conversion to
// EMF adjusts the Metafile to Full Screen or does not set rclBounds at all
// ENHMETAHEADER emh;
// UINT uRet;
// uRet = GetEnhMetaFileHeader(hMeta, // handle of enhanced metafile
// sizeof(ENHMETAHEADER), // size of buffer, in bytes
// &emh); // address of buffer to receive data
// if (!uRet){
// DeleteEnhMetaFile(hMeta);
// return false;
// }
// // calculate size
// cx = emh.rclBounds.right - emh.rclBounds.left;
// cy = emh.rclBounds.bottom - emh.rclBounds.top;
/////////////////////////////////////////////////////////////////////
// calculate size
// scale the metafile (pixels/inch of metafile => pixels/inch of display)
// mfh.inch already checked to be <> 0
hDC = ::GetDC(0);
int cx1 = ::GetDeviceCaps(hDC, LOGPIXELSX);
int cy1 = ::GetDeviceCaps(hDC, LOGPIXELSY);
::ReleaseDC(0, hDC);
cx = (mfh.inch/2 + (mfh.bbox.right - mfh.bbox.left) * cx1) / mfh.inch;
cy = (mfh.inch/2 + (mfh.bbox.bottom - mfh.bbox.top) * cy1) / mfh.inch;
} else { // maybe it's an EMF...
hFile->Seek(pos,SEEK_SET);
ENHMETAHEADER emh;
hMeta = ConvertEmfFiletoEmf(hFile, &emh);
if (!hMeta){
strcpy(info.szLastError,"corrupted WMF");
return false; // definitively give up
}
// ok, it's an EMF; calculate canvas size
cx = emh.rclBounds.right - emh.rclBounds.left;
cy = emh.rclBounds.bottom - emh.rclBounds.top;
// alternative methods, sometime not so reliable... [DP]
//cx = emh.szlDevice.cx;
//cy = emh.szlDevice.cy;
//
//hDC = ::GetDC(0);
//float hscale = (float)GetDeviceCaps(hDC, HORZRES)/(100.0f * GetDeviceCaps(hDC, HORZSIZE));
//float vscale = (float)GetDeviceCaps(hDC, VERTRES)/(100.0f * GetDeviceCaps(hDC, VERTSIZE));
//::ReleaseDC(0, hDC);
//cx = (long)((emh.rclFrame.right - emh.rclFrame.left) * hscale);
//cy = (long)((emh.rclFrame.bottom - emh.rclFrame.top) * vscale);
}
if (info.nEscape == -1) { // Check if cancelled
head.biWidth = cx;
head.biHeight= cy;
info.dwType = CXIMAGE_FORMAT_WMF;
DeleteEnhMetaFile(hMeta);
strcpy(info.szLastError,"output dimensions returned");
return true;
}
if (!cx || !cy) {
DeleteEnhMetaFile(hMeta);
strcpy(info.szLastError,"empty WMF");
return false;
}
if (nForceWidth) cx=nForceWidth;
if (nForceHeight) cy=nForceHeight;
ShrinkMetafile(cx, cy); // !! Otherwise Bitmap may have bombastic size
HDC hDC0 = ::GetDC(0); // DC of screen
HBITMAP hBitmap = CreateCompatibleBitmap(hDC0, cx, cy); // has # colors of display
hDC = CreateCompatibleDC(hDC0); // memory dc compatible with screen
::ReleaseDC(0, hDC0); // don't need anymore. get rid of it.
if (hDC){
if (hBitmap){
RECT rc = {0,0,cx,cy};
int bpp = ::GetDeviceCaps(hDC, BITSPIXEL);
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hDC, hBitmap);
// clear out the entire bitmap with windows background
// because the MetaFile may not contain background information
DWORD dwBack = XMF_COLOR_BACK;
#if XMF_SUPPORT_TRANSPARENCY
if (bpp == 24) dwBack = XMF_COLOR_TRANSPARENT;
#endif
DWORD OldColor = SetBkColor(hDC, dwBack);
ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
SetBkColor(hDC, OldColor);
//retrieves optional palette entries from the specified enhanced metafile
PLOGPALETTE plogPal;
PBYTE pjTmp;
HPALETTE hPal;
int iEntries = GetEnhMetaFilePaletteEntries(hMeta, 0, NULL);
if (iEntries) {
if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) {
DeleteObject(hBitmap);
DeleteDC(hDC);
DeleteEnhMetaFile(hMeta);
strcpy(info.szLastError,"Cancelled");
return false;
}
plogPal->palVersion = 0x300;
plogPal->palNumEntries = (WORD) iEntries;
pjTmp = (PBYTE) plogPal;
pjTmp += 4;
GetEnhMetaFilePaletteEntries(hMeta, iEntries, (PPALETTEENTRY)pjTmp);
hPal = CreatePalette(plogPal);
GlobalFree(plogPal);
SelectPalette(hDC, hPal, FALSE);
RealizePalette(hDC);
}
// Play the Metafile into Memory DC
BOOL bRet = PlayEnhMetaFile(hDC, // handle to a device context
hMeta, // handle to an enhanced metafile
&rc); // pointer to bounding rectangle
SelectObject(hDC, hBitmapOld);
DeleteEnhMetaFile(hMeta); // we are done with this one
if (info.nEscape) { // Check if cancelled
DeleteObject(hBitmap);
DeleteDC(hDC);
strcpy(info.szLastError,"Cancelled");
return false;
}
// the Bitmap now has the image.
// Create our DIB and convert the DDB into DIB
if (!Create(cx, cy, bpp, CXIMAGE_FORMAT_WMF)) {
DeleteObject(hBitmap);
DeleteDC(hDC);
return false;
}
#if XMF_SUPPORT_TRANSPARENCY
if (bpp == 24) {
RGBQUAD rgbTrans = { XMF_RGBQUAD_TRANSPARENT };
SetTransColor(rgbTrans);
}
#endif
// We're finally ready to get the DIB. Call the driver and let
// it party on our bitmap. It will fill in the color table,
// and bitmap bits of our global memory block.
bRet = GetDIBits(hDC, hBitmap, 0,
(UINT)cy, GetBits(), (LPBITMAPINFO)pDib, DIB_RGB_COLORS);
DeleteObject(hBitmap);
DeleteDC(hDC);
return (bRet!=0);
} else {
DeleteDC(hDC);
}
} else {
if (hBitmap) DeleteObject(hBitmap);
}
DeleteEnhMetaFile(hMeta);
return false;
}
/**********************************************************************
Function: CheckMetafileHeader
Purpose: Check if the Metafileheader of a file is valid
**********************************************************************/
BOOL CxImageWMF::CheckMetafileHeader(METAFILEHEADER *metafileheader)
{
WORD *pw;
WORD cs;
int i;
// check magic #
if (metafileheader->key != 0x9ac6cdd7L) return false;
// test checksum of header
pw = (WORD *)metafileheader;
cs = *pw;
pw++;
for (i = 0; i < 9; i++) {
cs ^= *pw;
pw++;
}
if (cs != metafileheader->checksum) return false;
// check resolution
if ((metafileheader->inch <= 0) || (metafileheader->inch > 2540)) return false;
return true;
}
/**********************************************************************
Function: ConvertWmfFiletoEmf
Purpose: Converts a Windows Metafile into an Enhanced Metafile
**********************************************************************/
HENHMETAFILE CxImageWMF::ConvertWmfFiletoEmf(CxFile *fp, METAFILEHEADER *metafileheader)
{
HENHMETAFILE hMeta;
long lenFile;
long len;
BYTE *p;
METAHEADER mfHeader;
DWORD seekpos;
hMeta = 0;
// get length of the file
lenFile = fp->Size();
// a placeable metafile starts with a METAFILEHEADER
// read it and check metafileheader
len = fp->Read(metafileheader, 1, sizeof(METAFILEHEADER));
if (len < sizeof(METAFILEHEADER)) return (hMeta);
if (CheckMetafileHeader(metafileheader)) {
// This is a placeable metafile
// Convert the placeable format into something that can
// be used with GDI metafile functions
seekpos = sizeof(METAFILEHEADER);
} else {
// Not a placeable wmf. A windows metafile?
// at least not scaleable.
// we could try to convert, but would loose ratio. don't allow this
return (hMeta);
//metafileheader->bbox.right = ?;
//metafileheader->bbox.left = ?;
//metafileheader->bbox.bottom = ?;
//metafileheader->bbox.top = ?;
//metafileheader->inch = ?;
//
//seekpos = 0;
// fp->Seek(0, SEEK_SET); // rewind
}
// At this point we have a metaheader regardless of whether
// the metafile was a windows metafile or a placeable metafile
// so check to see if it is valid. There is really no good
// way to do this so just make sure that the mtType is either
// 1 or 2 (memory or disk file)
// in addition we compare the length of the METAHEADER against
// the length of the file. if filelength < len => no Metafile
len = fp->Read(&mfHeader, 1, sizeof(METAHEADER));
if (len < sizeof(METAHEADER)) return (hMeta);
if ((mfHeader.mtType != 1) && (mfHeader.mtType != 2)) return (hMeta);
// Length in Bytes from METAHEADER
len = mfHeader.mtSize * 2;
if (len > lenFile) return (hMeta);
// Allocate memory for the metafile bits
p = (BYTE *)malloc(len);
if (!p) return (hMeta);
// seek back to METAHEADER and read all the stuff at once
fp->Seek(seekpos, SEEK_SET);
lenFile = fp->Read(p, 1, len);
if (lenFile != len) {
free(p);
return (hMeta);
}
// the following (commented code) works, but adjusts rclBound of the
// Enhanced Metafile to full screen.
// the METAFILEHEADER from above is needed to scale the image
// hMeta = SetWinMetaFileBits(len, p, NULL, NULL);
// scale the metafile (pixels/inch of metafile => pixels/inch of display)
METAFILEPICT mfp;
int cx1, cy1;
HDC hDC;
hDC = ::GetDC(0);
cx1 = ::GetDeviceCaps(hDC, LOGPIXELSX);
cy1 = ::GetDeviceCaps(hDC, LOGPIXELSY);
memset(&mfp, 0, sizeof(mfp));
mfp.mm = MM_ANISOTROPIC;
mfp.xExt = 10000; //(metafileheader->bbox.right - metafileheader->bbox.left) * cx1 / metafileheader->inch;
mfp.yExt = 10000; //(metafileheader->bbox.bottom - metafileheader->bbox.top) * cy1 / metafileheader->inch;
mfp.hMF = 0;
// in MM_ANISOTROPIC mode xExt and yExt are in MM_HIENGLISH
// MM_HIENGLISH means: Each logical unit is converted to 0.001 inch
//mfp.xExt *= 1000;
//mfp.yExt *= 1000;
// ????
//int k = 332800 / ::GetSystemMetrics(SM_CXSCREEN);
//mfp.xExt *= k; mfp.yExt *= k;
// fix for Win9x
while ((mfp.xExt < 6554) && (mfp.yExt < 6554))
{
mfp.xExt *= 10;
mfp.yExt *= 10;
}
hMeta = SetWinMetaFileBits(len, p, hDC, &mfp);
if (!hMeta){ //try 2nd conversion using a different mapping
mfp.mm = MM_TEXT;
hMeta = SetWinMetaFileBits(len, p, hDC, &mfp);
}
::ReleaseDC(0, hDC);
// Free Memory
free(p);
return (hMeta);
}
/////////////////////////////////////////////////////////////////////
HENHMETAFILE CxImageWMF::ConvertEmfFiletoEmf(CxFile *pFile, ENHMETAHEADER *pemfh)
{
HENHMETAFILE hMeta;
long iLen = pFile->Size();
// Check the header first: <km>
long pos = pFile->Tell();
long iLenRead = pFile->Read(pemfh, 1, sizeof(ENHMETAHEADER));
if (iLenRead < sizeof(ENHMETAHEADER)) return NULL;
if (pemfh->iType != EMR_HEADER) return NULL;
if (pemfh->dSignature != ENHMETA_SIGNATURE) return NULL;
//if (pemfh->nBytes != (DWORD)iLen) return NULL;
pFile->Seek(pos,SEEK_SET);
BYTE* pBuff = (BYTE *)malloc(iLen);
if (!pBuff) return (FALSE);
// Read the Enhanced Metafile
iLenRead = pFile->Read(pBuff, 1, iLen);
if (iLenRead != iLen) {
free(pBuff);
return NULL;
}
// Make it a Memory Metafile
hMeta = SetEnhMetaFileBits(iLen, pBuff);
free(pBuff); // finished with this one
if (!hMeta) return NULL; // oops.
// Get the Enhanced Metafile Header
UINT uRet = GetEnhMetaFileHeader(hMeta, // handle of enhanced metafile
sizeof(ENHMETAHEADER), // size of buffer, in bytes
pemfh); // address of buffer to receive data
if (!uRet) {
DeleteEnhMetaFile(hMeta);
return NULL;
}
return (hMeta);
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
/////////////////////////////////////////////////////////////////////
bool CxImageWMF::Encode(CxFile * hFile)
{
if (hFile == NULL) return false;
strcpy(info.szLastError, "Save WMF not supported");
return false;
}
#endif // CXIMAGE_SUPPORT_ENCODE
/////////////////////////////////////////////////////////////////////
/**********************************************************************
Function: ShrinkMetafile
Purpose: Shrink the size of a metafile to be not larger than
the definition
**********************************************************************/
void CxImageWMF::ShrinkMetafile(int &cx, int &cy)
{
int xScreen = XMF_MAXSIZE_CX;
int yScreen = XMF_MAXSIZE_CY;
if (cx > xScreen){
cy = cy * xScreen / cx;
cx = xScreen;
}
if (cy > yScreen){
cx = cx * yScreen / cy;
cy = yScreen;
}
}
#endif // CIMAGE_SUPPORT_WMF

View File

@@ -1,154 +0,0 @@
/*
*********************************************************************
* File: ximawmf.h
* Purpose: Windows Metafile Class Loader and Writer
* Author: Volker Horch - vhorch@gmx.de
* created: 13-Jun-2002
*********************************************************************
*/
/*
*********************************************************************
Notes by Author:
*********************************************************************
Limitations:
============
a) Transparency:
A Metafile is vector graphics, which has transparency by design.
This class always converts into a Bitmap format. Transparency is
supported, but there is no good way to find out, which parts
of the Metafile are transparent. There are two ways how we can
handle this:
- Clear the Background of the Bitmap with the background color
you like (i have used COLOR_WINDOW) and don't support transparency.
below #define XMF_SUPPORT_TRANSPARENCY 0
#define XMF_COLOR_BACK RGB(Background color you like)
- Clear the Background of the Bitmap with a very unusual color
(which one ?) and use this color as the transparent color
below #define XMF_SUPPORT_TRANSPARENCY 1
#define XMF_COLOR_TRANSPARENT_R ...
#define XMF_COLOR_TRANSPARENT_G ...
#define XMF_COLOR_TRANSPARENT_B ...
b) Resolution
Once we have converted the Metafile into a Bitmap and we zoom in
or out, the image may not look very good. If we still had the
original Metafile, zooming would produce good results always.
c) Size
Although the filesize of a Metafile may be very small, it might
produce a Bitmap with a bombastic size. Assume you have a Metafile
with an image size of 6000*4000, which contains just one Metafile
record ((e.g. a line from (0,0) to (6000, 4000)). The filesize
of this Metafile would be let's say 100kB. If we convert it to
a 6000*4000 Bitmap with 24 Bits/Pixes, the Bitmap would consume
about 68MB of memory.
I have chosen to limit the size of the Bitmap to max.
screensize, to avoid memory problems.
If you want something else,
modify #define XMF_MAXSIZE_CX / XMF_MAXSIZE_CY below
*********************************************************************
*/
#ifndef _XIMAWMF_H
#define _XIMAWMF_H
#include "ximage.h"
#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS
class CxImageWMF: public CxImage
{
#pragma pack(1)
typedef struct tagRECT16
{
short int left;
short int top;
short int right;
short int bottom;
} RECT16;
// taken from Windos 3.11 SDK Documentation (Programmer's Reference Volume 4: Resources)
typedef struct tagMETAFILEHEADER
{
DWORD key; // always 0x9ac6cdd7
WORD reserved1; // reserved = 0
RECT16 bbox; // bounding rectangle in metafile units as defined in "inch"
WORD inch; // number of metafile units per inch (should be < 1440)
DWORD reserved2; // reserved = 0
WORD checksum; // sum of the first 10 WORDS (using XOR operator)
} METAFILEHEADER;
#pragma pack()
public:
CxImageWMF(): CxImage(CXIMAGE_FORMAT_WMF) { }
bool Decode(CxFile * hFile, long nForceWidth=0, long nForceHeight=0);
bool Decode(FILE *hFile, long nForceWidth=0, long nForceHeight=0)
{ CxIOFile file(hFile); return Decode(&file,nForceWidth,nForceHeight); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile);
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
#endif // CXIMAGE_SUPPORT_ENCODE
protected:
void ShrinkMetafile(int &cx, int &cy);
BOOL CheckMetafileHeader(METAFILEHEADER *pmetafileheader);
HENHMETAFILE ConvertWmfFiletoEmf(CxFile *pFile, METAFILEHEADER *pmetafileheader);
HENHMETAFILE ConvertEmfFiletoEmf(CxFile *pFile, ENHMETAHEADER *pemfh);
};
#define METAFILEKEY 0x9ac6cdd7L
// Background color definition (if no transparency). see Notes above
#define XMF_COLOR_BACK GetSysColor(COLOR_WINDOW)
// alternatives
//#define XMF_COLOR_BACK RGB(192, 192, 192) // lite gray
//#define XMF_COLOR_BACK RGB( 0, 0, 0) // black
//#define XMF_COLOR_BACK RGB(255, 255, 255) // white
// transparency support. see Notes above
#define XMF_SUPPORT_TRANSPARENCY 0
#define XMF_COLOR_TRANSPARENT_R 211
#define XMF_COLOR_TRANSPARENT_G 121
#define XMF_COLOR_TRANSPARENT_B 112
// don't change
#define XMF_COLOR_TRANSPARENT RGB (XMF_COLOR_TRANSPARENT_R, \
XMF_COLOR_TRANSPARENT_G, \
XMF_COLOR_TRANSPARENT_B)
// don't change
#define XMF_RGBQUAD_TRANSPARENT XMF_COLOR_TRANSPARENT_B, \
XMF_COLOR_TRANSPARENT_G, \
XMF_COLOR_TRANSPARENT_R, \
0
// max. size. see Notes above
// alternatives
//#define XMF_MAXSIZE_CX (GetSystemMetrics(SM_CXSCREEN)-10)
//#define XMF_MAXSIZE_CY (GetSystemMetrics(SM_CYSCREEN)-50)
//#define XMF_MAXSIZE_CX (2*GetSystemMetrics(SM_CXSCREEN)/3)
//#define XMF_MAXSIZE_CY (2*GetSystemMetrics(SM_CYSCREEN)/3)
#define XMF_MAXSIZE_CX 4000
#define XMF_MAXSIZE_CY 4000
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,125 +0,0 @@
#if !defined(__xiofile_h)
#define __xiofile_h
#include "xfile.h"
//#include <TCHAR.h>
class DLL_EXP CxIOFile : public CxFile
{
public:
CxIOFile(FILE* fp = NULL)
{
m_fp = fp;
m_bCloseFile = (bool)(fp==0);
}
~CxIOFile()
{
Close();
}
//////////////////////////////////////////////////////////
bool Open(LPCTSTR filename, LPCTSTR mode)
{
if (m_fp) return false; // Can't re-open without closing first
m_fp = _tfopen(filename, mode);
if (!m_fp) return false;
m_bCloseFile = true;
return true;
}
//////////////////////////////////////////////////////////
virtual bool Close()
{
int iErr = 0;
if ( (m_fp) && (m_bCloseFile) ){
iErr = fclose(m_fp);
m_fp = NULL;
}
return (bool)(iErr==0);
}
//////////////////////////////////////////////////////////
virtual size_t Read(void *buffer, size_t size, size_t count)
{
if (!m_fp) return 0;
return fread(buffer, size, count, m_fp);
}
//////////////////////////////////////////////////////////
virtual size_t Write(const void *buffer, size_t size, size_t count)
{
if (!m_fp) return 0;
return fwrite(buffer, size, count, m_fp);
}
//////////////////////////////////////////////////////////
virtual bool Seek(long offset, int origin)
{
if (!m_fp) return false;
return (bool)(fseek(m_fp, offset, origin) == 0);
}
//////////////////////////////////////////////////////////
virtual long Tell()
{
if (!m_fp) return 0;
return ftell(m_fp);
}
//////////////////////////////////////////////////////////
virtual long Size()
{
if (!m_fp) return -1;
long pos,size;
pos = ftell(m_fp);
fseek(m_fp, 0, SEEK_END);
size = ftell(m_fp);
fseek(m_fp, pos,SEEK_SET);
return size;
}
//////////////////////////////////////////////////////////
virtual bool Flush()
{
if (!m_fp) return false;
return (bool)(fflush(m_fp) == 0);
}
//////////////////////////////////////////////////////////
virtual bool Eof()
{
if (!m_fp) return true;
return (bool)(feof(m_fp) != 0);
}
//////////////////////////////////////////////////////////
virtual long Error()
{
if (!m_fp) return -1;
return ferror(m_fp);
}
//////////////////////////////////////////////////////////
virtual bool PutC(unsigned char c)
{
if (!m_fp) return false;
return (bool)(fputc(c, m_fp) == c);
}
//////////////////////////////////////////////////////////
virtual long GetC()
{
if (!m_fp) return EOF;
return getc(m_fp);
}
//////////////////////////////////////////////////////////
virtual char * GetS(char *string, int n)
{
if (!m_fp) return NULL;
return fgets(string,n,m_fp);
}
//////////////////////////////////////////////////////////
virtual long Scanf(const char *format, void* output)
{
if (!m_fp) return EOF;
return fscanf(m_fp, format, output);
}
//////////////////////////////////////////////////////////
protected:
FILE *m_fp;
bool m_bCloseFile;
};
#endif

View File

@@ -1,202 +0,0 @@
#include "xmemfile.h"
//////////////////////////////////////////////////////////
CxMemFile::CxMemFile(BYTE* pBuffer, DWORD size)
{
m_pBuffer = pBuffer;
m_Position = 0;
m_Size = m_Edge = size;
m_bFreeOnClose = (bool)(pBuffer==0);
}
//////////////////////////////////////////////////////////
CxMemFile::~CxMemFile()
{
Close();
}
//////////////////////////////////////////////////////////
bool CxMemFile::Close()
{
if ( (m_pBuffer) && (m_bFreeOnClose) ){
free(m_pBuffer);
m_pBuffer = NULL;
m_Size = 0;
}
return true;
}
//////////////////////////////////////////////////////////
bool CxMemFile::Open()
{
if (m_pBuffer) return false; // Can't re-open without closing first
m_Position = m_Size = m_Edge = 0;
m_pBuffer=(BYTE*)malloc(1);
m_bFreeOnClose = true;
return (m_pBuffer!=0);
}
//////////////////////////////////////////////////////////
BYTE* CxMemFile::GetBuffer(bool bDetachBuffer)
{
//can only detach, avoid inadvertantly attaching to
// memory that may not be ours [Jason De Arte]
if( bDetachBuffer )
m_bFreeOnClose = false;
return m_pBuffer;
}
//////////////////////////////////////////////////////////
size_t CxMemFile::Read(void *buffer, size_t size, size_t count)
{
if (buffer==NULL) return 0;
if (m_pBuffer==NULL) return 0;
if (m_Position >= (long)m_Size) return 0;
long nCount = (long)(count*size);
if (nCount == 0) return 0;
long nRead;
if (m_Position + nCount > (long)m_Size)
nRead = (m_Size - m_Position);
else
nRead = nCount;
memcpy(buffer, m_pBuffer + m_Position, nRead);
m_Position += nRead;
return (size_t)(nRead/size);
}
//////////////////////////////////////////////////////////
size_t CxMemFile::Write(const void *buffer, size_t size, size_t count)
{
if (m_pBuffer==NULL) return 0;
if (buffer==NULL) return 0;
long nCount = (long)(count*size);
if (nCount == 0) return 0;
if (m_Position + nCount > m_Edge){
if (!Alloc(m_Position + nCount)){
return false;
}
}
memcpy(m_pBuffer + m_Position, buffer, nCount);
m_Position += nCount;
if (m_Position > (long)m_Size) m_Size = m_Position;
return count;
}
//////////////////////////////////////////////////////////
bool CxMemFile::Seek(long offset, int origin)
{
if (m_pBuffer==NULL) return false;
long lNewPos = m_Position;
if (origin == SEEK_SET) lNewPos = offset;
else if (origin == SEEK_CUR) lNewPos += offset;
else if (origin == SEEK_END) lNewPos = m_Size + offset;
else return false;
if (lNewPos < 0) lNewPos = 0;
m_Position = lNewPos;
return true;
}
//////////////////////////////////////////////////////////
long CxMemFile::Tell()
{
if (m_pBuffer==NULL) return -1;
return m_Position;
}
//////////////////////////////////////////////////////////
long CxMemFile::Size()
{
if (m_pBuffer==NULL) return -1;
return m_Size;
}
//////////////////////////////////////////////////////////
bool CxMemFile::Flush()
{
if (m_pBuffer==NULL) return false;
return true;
}
//////////////////////////////////////////////////////////
bool CxMemFile::Eof()
{
if (m_pBuffer==NULL) return true;
return (m_Position >= (long)m_Size);
}
//////////////////////////////////////////////////////////
long CxMemFile::Error()
{
if (m_pBuffer==NULL) return -1;
return (m_Position > (long)m_Size);
}
//////////////////////////////////////////////////////////
bool CxMemFile::PutC(unsigned char c)
{
if (m_pBuffer==NULL) return false;
if (m_Position >= m_Edge){
if (!Alloc(m_Position + 1)){
return false;
}
}
m_pBuffer[m_Position++] = c;
if (m_Position > (long)m_Size) m_Size = m_Position;
return true;
}
//////////////////////////////////////////////////////////
long CxMemFile::GetC()
{
if (Eof()) return EOF;
return *(BYTE*)((BYTE*)m_pBuffer + m_Position++);
}
//////////////////////////////////////////////////////////
char * CxMemFile::GetS(char *string, int n)
{
n--;
long c,i=0;
while (i<n){
c = GetC();
if (c == EOF) return 0;
string[i++] = (char)c;
if (c == '\n') break;
}
string[i] = 0;
return string;
}
//////////////////////////////////////////////////////////
long CxMemFile::Scanf(const char *format, void* output)
{
return 0;
}
//////////////////////////////////////////////////////////
bool CxMemFile::Alloc(DWORD dwNewLen)
{
if (dwNewLen > (DWORD)m_Edge)
{
// find new buffer size
DWORD dwNewBufferSize = (DWORD)(((dwNewLen>>16)+1)<<16);
// allocate new buffer
if (m_pBuffer == NULL) m_pBuffer = (BYTE*)malloc(dwNewBufferSize);
else m_pBuffer = (BYTE*)realloc(m_pBuffer, dwNewBufferSize);
// I own this buffer now (caller knows nothing about it)
m_bFreeOnClose = true;
m_Edge = dwNewBufferSize;
}
return (m_pBuffer!=0);
}
//////////////////////////////////////////////////////////
void CxMemFile::Free()
{
Close();
}
//////////////////////////////////////////////////////////

View File

@@ -1,41 +0,0 @@
#if !defined(__xmemfile_h)
#define __xmemfile_h
#include "xfile.h"
//////////////////////////////////////////////////////////
class DLL_EXP CxMemFile : public CxFile
{
public:
CxMemFile(BYTE* pBuffer = NULL, DWORD size = 0);
~CxMemFile();
bool Open();
BYTE* GetBuffer(bool bDetachBuffer = true);
virtual bool Close();
virtual size_t Read(void *buffer, size_t size, size_t count);
virtual size_t Write(const void *buffer, size_t size, size_t count);
virtual bool Seek(long offset, int origin);
virtual long Tell();
virtual long Size();
virtual bool Flush();
virtual bool Eof();
virtual long Error();
virtual bool PutC(unsigned char c);
virtual long GetC();
virtual char * GetS(char *string, int n);
virtual long Scanf(const char *format, void* output);
protected:
bool Alloc(DWORD nBytes);
void Free();
BYTE* m_pBuffer;
DWORD m_Size;
bool m_bFreeOnClose;
long m_Position; //current position
long m_Edge; //buffer size
};
#endif

View File

@@ -1,266 +0,0 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "CxImage"=".\cximage\cximage.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "CxImageCrtDll"=".\CxImage\CxImageDLL\CxImageCrtDll.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name j2k
End Project Dependency
Begin Project Dependency
Project_Dep_Name jbig
End Project Dependency
Begin Project Dependency
Project_Dep_Name jpeg
End Project Dependency
Begin Project Dependency
Project_Dep_Name png
End Project Dependency
Begin Project Dependency
Project_Dep_Name tiff
End Project Dependency
Begin Project Dependency
Project_Dep_Name zlib
End Project Dependency
Begin Project Dependency
Project_Dep_Name jasper
End Project Dependency
Begin Project Dependency
Project_Dep_Name mng
End Project Dependency
Begin Project Dependency
Project_Dep_Name libdcr
End Project Dependency
}}}
###############################################################################
Project: "CxImageMfcDll"=".\CxImage\CxImageDLL\cximagemfcdll.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name j2k
End Project Dependency
Begin Project Dependency
Project_Dep_Name jbig
End Project Dependency
Begin Project Dependency
Project_Dep_Name jpeg
End Project Dependency
Begin Project Dependency
Project_Dep_Name png
End Project Dependency
Begin Project Dependency
Project_Dep_Name tiff
End Project Dependency
Begin Project Dependency
Project_Dep_Name zlib
End Project Dependency
Begin Project Dependency
Project_Dep_Name jasper
End Project Dependency
Begin Project Dependency
Project_Dep_Name mng
End Project Dependency
Begin Project Dependency
Project_Dep_Name libdcr
End Project Dependency
}}}
###############################################################################
Project: "demo"=".\demo\demo.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name CxImage
End Project Dependency
Begin Project Dependency
Project_Dep_Name Jpeg
End Project Dependency
Begin Project Dependency
Project_Dep_Name png
End Project Dependency
Begin Project Dependency
Project_Dep_Name Tiff
End Project Dependency
Begin Project Dependency
Project_Dep_Name zlib
End Project Dependency
Begin Project Dependency
Project_Dep_Name mng
End Project Dependency
Begin Project Dependency
Project_Dep_Name j2000
End Project Dependency
Begin Project Dependency
Project_Dep_Name jbig
End Project Dependency
Begin Project Dependency
Project_Dep_Name cximagedll
End Project Dependency
Begin Project Dependency
Project_Dep_Name j2k
End Project Dependency
Begin Project Dependency
Project_Dep_Name jasper
End Project Dependency
Begin Project Dependency
Project_Dep_Name libdcr
End Project Dependency
}}}
###############################################################################
Project: "demoDll"=".\demo\demoDLL.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name CxImageCrtDll
End Project Dependency
}}}
###############################################################################
Project: "jasper"=".\jasper\jasper.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "jbig"=".\jbig\jbig.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "jpeg"=".\jpeg\Jpeg.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "libdcr"=".\raw\libdcr.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "mng"=".\mng\mng.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "png"=".\png\png.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "tiff"=".\tiff\Tiff.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "zlib"=".\zlib\zlib.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -1,46 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual C++ Express 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CxImage", "cximage\cximage.vcproj", "{02D7821F-046E-4114-8981-2E7B672A578F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jpeg", "jpeg\Jpeg.vcproj", "{8B8F1DE6-ADB6-40A2-B9D2-7481BD13583B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "zlib\zlib.vcproj", "{BCD0DF12-7BE3-4F35-AD6D-A43F89781758}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
Unicode Debug|Win32 = Unicode Debug|Win32
Unicode Release|Win32 = Unicode Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{02D7821F-046E-4114-8981-2E7B672A578F}.Debug|Win32.ActiveCfg = Debug|Win32
{02D7821F-046E-4114-8981-2E7B672A578F}.Debug|Win32.Build.0 = Debug|Win32
{02D7821F-046E-4114-8981-2E7B672A578F}.Release|Win32.ActiveCfg = Release|Win32
{02D7821F-046E-4114-8981-2E7B672A578F}.Release|Win32.Build.0 = Release|Win32
{02D7821F-046E-4114-8981-2E7B672A578F}.Unicode Debug|Win32.ActiveCfg = Unicode Debug|Win32
{02D7821F-046E-4114-8981-2E7B672A578F}.Unicode Debug|Win32.Build.0 = Unicode Debug|Win32
{02D7821F-046E-4114-8981-2E7B672A578F}.Unicode Release|Win32.ActiveCfg = Unicode Release|Win32
{02D7821F-046E-4114-8981-2E7B672A578F}.Unicode Release|Win32.Build.0 = Unicode Release|Win32
{8B8F1DE6-ADB6-40A2-B9D2-7481BD13583B}.Debug|Win32.ActiveCfg = Debug|Win32
{8B8F1DE6-ADB6-40A2-B9D2-7481BD13583B}.Debug|Win32.Build.0 = Debug|Win32
{8B8F1DE6-ADB6-40A2-B9D2-7481BD13583B}.Release|Win32.ActiveCfg = Release|Win32
{8B8F1DE6-ADB6-40A2-B9D2-7481BD13583B}.Release|Win32.Build.0 = Release|Win32
{8B8F1DE6-ADB6-40A2-B9D2-7481BD13583B}.Unicode Debug|Win32.ActiveCfg = Unicode Debug|Win32
{8B8F1DE6-ADB6-40A2-B9D2-7481BD13583B}.Unicode Debug|Win32.Build.0 = Unicode Debug|Win32
{8B8F1DE6-ADB6-40A2-B9D2-7481BD13583B}.Unicode Release|Win32.ActiveCfg = Unicode Release|Win32
{8B8F1DE6-ADB6-40A2-B9D2-7481BD13583B}.Unicode Release|Win32.Build.0 = Unicode Release|Win32
{BCD0DF12-7BE3-4F35-AD6D-A43F89781758}.Debug|Win32.ActiveCfg = Debug|Win32
{BCD0DF12-7BE3-4F35-AD6D-A43F89781758}.Debug|Win32.Build.0 = Debug|Win32
{BCD0DF12-7BE3-4F35-AD6D-A43F89781758}.Release|Win32.ActiveCfg = Release|Win32
{BCD0DF12-7BE3-4F35-AD6D-A43F89781758}.Release|Win32.Build.0 = Release|Win32
{BCD0DF12-7BE3-4F35-AD6D-A43F89781758}.Unicode Debug|Win32.ActiveCfg = Unicode Debug|Win32
{BCD0DF12-7BE3-4F35-AD6D-A43F89781758}.Unicode Debug|Win32.Build.0 = Unicode Debug|Win32
{BCD0DF12-7BE3-4F35-AD6D-A43F89781758}.Unicode Release|Win32.ActiveCfg = Unicode Release|Win32
{BCD0DF12-7BE3-4F35-AD6D-A43F89781758}.Unicode Release|Win32.Build.0 = Unicode Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -1,13 +0,0 @@
Yanked from FreeCAD forum posts by wmayer 17 July and 22 August 2014
http://forum.freecadweb.org/viewtopic.php?f=10&t=7054
http://forum.freecadweb.org/viewtopic.php?f=17&t=7432
The CxImage is only used for a Windows thumbnailer. The utility
"ThumbnailProvider" is a DLL which can be registered to Windows as a so called
shell extension. This utility is able to create a preview image of an FCStd
project file and CxImage is needed to convert the data into a format that
Windows expects.
The format Windows accepts is a BITMAP handle for which Qt could also be used.
But this requires a dependency of two rather heavy DLLs (QtCore, QtGui) and
with a statically linked CxImage we don't have this problem.

View File

@@ -1,62 +0,0 @@
Libpng 1.2.24 - December 14, 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.24.tar.gz
libpng-1.2.24.tar.bz2
Source files with LF line endings (for Unix/Linux) without the
"configure" script
libpng-1.2.24-no-config.tar.gz
libpng-1.2.24-no-config.tar.bz2
Source files with CRLF line endings (for Windows), without the
"configure" script
lpng1224.zip
lpng1224.tar.bz2
Project files
libpng-1.2.24-project-netware.zip
libpng-1.2.24-project-wince.zip
Other information:
libpng-1.2.24-README.txt
libpng-1.2.24-KNOWNBUGS.txt
libpng-1.2.24-LICENSE.txt
libpng-1.2.24-Y2K-compliance.txt
Changes since the last public release (1.2.23):
version 1.2.24 [December 14, 2007]
Moved misplaced test for malloc failure in png_set_sPLT(). This bug was
introduced in libpng-1.2.20.
Ifdef out avg_row etc from png.h and pngwrite.c when PNG_NO_WRITE_FILTER
Do not use png_ptr->free_fn and png_ptr->mem_fn in png_destroy_read_struct()
when png_ptr is NULL (Marshall Clow).
Updated handling of symbol prefixes in Makefile.am and configure.ac (Mike
Frysinger).
Removed a useless test and fixed incorrect test in png_set_cHRM_fixed()
(David Hill).
Make sure not to redefine _BSD_SOURCE in pngconf.h
Revised gather.sh and makefile.std in contrib/pngminim to avoid compiling
unused files.
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

File diff suppressed because it is too large Load Diff

View File

@@ -1,219 +0,0 @@
Installing libpng version 1.2.24 - December 14, 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.24" 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.24)
makefile.linux => Linux/ELF makefile
(gcc, creates libpng12.so.0.1.2.24)
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.24)
makefile.sunos => Sun makefile
makefile.solaris => Solaris 2.X makefile (gcc,
creates libpng12.so.0.1.2.24)
makefile.solaris-x86 => Solaris/intelMMX 2.X makefile (gcc,
creates libpng12.so.0.1.2.24)
makefile.so9 => Solaris 9 makefile (gcc,
creates libpng12.so.0.1.2.24)
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.vcwin32 => makefile for Microsoft Visual C++ 4.0 and later
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.
Using the ./configure script -- 16 December 2002.
=================================================
The ./configure script should work compatibly with what scripts/makefile.*
did, however there are some options you need to add to configure explicitly,
which previously was done semi-automatically (if you didn't edit
scripts/makefile.* yourself, that is)
CFLAGS="-Wall -O -funroll-loops \
-malign-loops=2 -malign-functions=2" ./configure --prefix=/usr/include \
--with-pkgconfigdir=/usr/lib/pkgconfig --includedir=/usr/include
You can alternatively specify --includedir=/usr/include, /usr/local/include,
/usr/include/png12, or whatever.

View File

@@ -1,22 +0,0 @@
Known bugs in libpng version 1.2.24
1. 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.4.0.
2. 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.
3. September 4, 2007: There is a report that pngtest crashes on MacOS 10.
STATUS: workarounds are
1) Compile without optimization (crashes are observed with
-arch i386 and -O2 or -O3, using gcc-4.0.1).
2) Compile pngtest.c with PNG_DEBUG defined (the bug goes away if
you try to look at it).
3) Ignore the crash. The library itself seems to be OK.

View File

@@ -1,109 +0,0 @@
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.24, December 14, 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
December 14, 2007

View File

@@ -1,263 +0,0 @@
README for libpng version 1.2.24 - December 14, 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_<chunk> and
png_get_<chunk> 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-mng-misc at lists.sourceforge.net, subscription required, visit
https://lists.sourceforge.net/lists/listinfo/png-mng-implement to subscribe)
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 twelve 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-*-*-diff.txt => Diff from previous release
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
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.24)
makefile.linux => Linux/ELF makefile
(gcc, creates libpng12.so.0.1.2.24)
makefile.gcmmx => Linux/ELF makefile
(gcc, creates libpng12.so.0.1.2.24,
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.24)
makefile.sunos => Sun makefile
makefile.solaris => Solaris 2.X makefile
(gcc, creates libpng12.so.0.1.2.24)
makefile.so9 => Solaris 9 makefile
(gcc, creates libpng12.so.0.1.2.24)
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

View File

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

View File

@@ -1,55 +0,0 @@
Y2K compliance in libpng:
=========================
December 14, 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.24 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

File diff suppressed because it is too large Load Diff

View File

@@ -1,798 +0,0 @@
/* png.c - location for general purpose libpng functions
*
* Last changed in libpng 1.2.21 October 4, 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
#define PNG_NO_EXTERN
#include "png.h"
/* Generate a compiler error if there is an old png.h in the search path. */
typedef version_1_2_24 Your_png_h_is_not_version_1_2_24;
/* Version information for C files. This had better match the version
* string defined in png.h. */
#ifdef PNG_USE_GLOBAL_ARRAYS
/* png_libpng_ver was changed to a function in version 1.0.5c */
PNG_CONST char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING;
#ifdef PNG_READ_SUPPORTED
/* png_sig was changed to a function in version 1.0.5c */
/* Place to hold the signature string for a PNG file. */
PNG_CONST png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
#endif /* PNG_READ_SUPPORTED */
/* Invoke global declarations for constant strings for known chunk types */
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_sCAL;
PNG_pHYs;
PNG_sBIT;
PNG_sPLT;
PNG_sRGB;
PNG_tEXt;
PNG_tIME;
PNG_tRNS;
PNG_zTXt;
#ifdef PNG_READ_SUPPORTED
/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* start of interlace block */
PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
/* offset to next interlace block */
PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
/* start of interlace block in the y direction */
PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
/* offset to next interlace block in the y direction */
PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
/* Height of interlace block. This is not currently used - if you need
* it, uncomment it here and in png.h
PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
*/
/* Mask to determine which pixels are valid in a pass */
PNG_CONST int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
/* Mask to determine which pixels to overwrite while displaying */
PNG_CONST int FARDATA png_pass_dsp_mask[]
= {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
#endif /* PNG_READ_SUPPORTED */
#endif /* PNG_USE_GLOBAL_ARRAYS */
/* Tells libpng that we have already handled the first "num_bytes" bytes
* of the PNG file signature. If the PNG data is embedded into another
* stream we can set num_bytes = 8 so that libpng will not attempt to read
* or write any of the magic bytes before it starts on the IHDR.
*/
#ifdef PNG_READ_SUPPORTED
void PNGAPI
png_set_sig_bytes(png_structp png_ptr, int num_bytes)
{
if(png_ptr == NULL) return;
png_debug(1, "in png_set_sig_bytes\n");
if (num_bytes > 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 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];
png_snprintf6(near_time_buf,29,"%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
png_snprintf6(png_ptr->time_buffer,29,"%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 */
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
png_charp PNGAPI
png_get_copyright(png_structp png_ptr)
{
png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
return ((png_charp) "\n libpng version 1.2.24 - December 14, 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");
}
/* 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 */
png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
return ((png_charp) PNG_LIBPNG_VER_STRING);
}
png_charp PNGAPI
png_get_header_ver(png_structp png_ptr)
{
/* Version of *.h files used when building libpng */
png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
return ((png_charp) PNG_LIBPNG_VER_STRING);
}
png_charp PNGAPI
png_get_header_version(png_structp png_ptr)
{
/* Returns longer string containing both version and date */
png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
return ((png_charp) PNG_HEADER_VERSION_STRING
#ifndef PNG_READ_SUPPORTED
" (NO READ SUPPORT)"
#endif
"\n");
}
#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)
/* this function was added to libpng 1.2.0 */
int PNGAPI
png_mmx_support(void)
{
/* obsolete, to be removed from libpng-1.4.0 */
return -1;
}
#endif /* PNG_1_0_X */
#endif /* PNG_READ_SUPPORTED && PNG_ASSEMBLER_CODE_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) */

View File

@@ -1,224 +0,0 @@
# Microsoft Developer Studio Project File - Name="png" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=png - Win32 Unicode 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 "png.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 "png.mak" CFG="png - Win32 Unicode Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "png - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "png - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "png - Win32 Unicode Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "png - Win32 Unicode Release" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "png - 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 2
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\zlib" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_CRT_SECURE_NO_DEPRECATE" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x809
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "png - 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 2
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\zlib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_CRT_SECURE_NO_DEPRECATE" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x809
# ADD RSC /l 0x809
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "png - Win32 Unicode Debug"
# PROP BASE Use_MFC 2
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "png___Win32_Unicode_Debug"
# PROP BASE Intermediate_Dir "png___Win32_Unicode_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 2
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Unicode_Debug"
# PROP Intermediate_Dir "Unicode_Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\zlib" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_AFXDLL" /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\zlib" /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "_CRT_SECURE_NO_DEPRECATE" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x809 /d "_AFXDLL"
# ADD RSC /l 0x809
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "png - Win32 Unicode Release"
# PROP BASE Use_MFC 2
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "png___Win32_Unicode_Release"
# PROP BASE Intermediate_Dir "png___Win32_Unicode_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 2
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Unicode_Release"
# PROP Intermediate_Dir "Unicode_Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "..\zlib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_AFXDLL" /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\zlib" /D "_WINDOWS" /D "WIN32" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "_CRT_SECURE_NO_DEPRECATE" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x809 /d "_AFXDLL"
# ADD RSC /l 0x809
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "png - Win32 Debug"
# Name "png - Win32 Release"
# Name "png - Win32 Unicode Debug"
# Name "png - Win32 Unicode Release"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# 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
# 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;fi;fd"
# 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;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -1,29 +0,0 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "png"=.\png.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,343 +0,0 @@
/* pngerror.c - stub functions for i/o and memory allocation
*
* Last changed in libpng 1.2.22 [October 13, 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 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));
#ifndef PNG_NO_WARNINGS
static void /* PRIVATE */
png_default_warning PNGARG((png_structp png_ptr,
png_const_charp warning_message));
#endif /* PNG_NO_WARNINGS */
/* 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.
*/
#ifndef PNG_NO_ERROR_TEXT
void PNGAPI
png_error(png_structp png_ptr, png_const_charp error_message)
{
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
char msg[16];
if (png_ptr != NULL)
{
if (png_ptr->flags&
(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
{
if (*error_message == '#')
{
int offset;
for (offset=1; offset<15; offset++)
if (*(error_message+offset) == ' ')
break;
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
{
int i;
for (i=0; i<offset-1; i++)
msg[i]=error_message[i+1];
msg[i]='\0';
error_message=msg;
}
else
error_message+=offset;
}
else
{
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
{
msg[0]='0';
msg[1]='\0';
error_message=msg;
}
}
}
}
#endif
if (png_ptr != NULL && png_ptr->error_fn != NULL)
(*(png_ptr->error_fn))(png_ptr, error_message);
/* If the custom handler doesn't exist, or if it returns,
use the default handler, which will not return. */
png_default_error(png_ptr, error_message);
}
#else
void PNGAPI
png_err(png_structp png_ptr)
{
if (png_ptr != NULL && png_ptr->error_fn != NULL)
(*(png_ptr->error_fn))(png_ptr, '\0');
/* If the custom handler doesn't exist, or if it returns,
use the default handler, which will not return. */
png_default_error(png_ptr, '\0');
}
#endif /* PNG_NO_ERROR_TEXT */
#ifndef PNG_NO_WARNINGS
/* 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);
}
#endif /* PNG_NO_WARNINGS */
/* These utilities are used internally to build an error message that relates
* to the current chunk. The chunk name comes from png_ptr->chunk_name,
* this is used to prefix the message. The message is limited in length
* to 63 bytes, the name characters are output as hex digits wrapped in []
* if the character is invalid.
*/
#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
static PNG_CONST char png_digit[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'
};
#define PNG_MAX_ERROR_TEXT 64
#if !defined(PNG_NO_WARNINGS) || !defined(PNG_NO_ERROR_TEXT)
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_memcpy(buffer+iout, error_message, PNG_MAX_ERROR_TEXT);
buffer[iout+PNG_MAX_ERROR_TEXT-1] = '\0';
}
}
#ifdef PNG_READ_SUPPORTED
void PNGAPI
png_chunk_error(png_structp png_ptr, png_const_charp error_message)
{
char msg[18+PNG_MAX_ERROR_TEXT];
if (png_ptr == NULL)
png_error(png_ptr, error_message);
else
{
png_format_buffer(png_ptr, msg, error_message);
png_error(png_ptr, msg);
}
}
#endif /* PNG_READ_SUPPORTED */
#endif /* !defined(PNG_NO_WARNINGS) || !defined(PNG_NO_ERROR_TEXT) */
#ifndef PNG_NO_WARNINGS
void PNGAPI
png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
{
char msg[18+PNG_MAX_ERROR_TEXT];
if (png_ptr == NULL)
png_warning(png_ptr, warning_message);
else
{
png_format_buffer(png_ptr, msg, warning_message);
png_warning(png_ptr, msg);
}
}
#endif /* PNG_NO_WARNINGS */
/* 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
error_message = error_message; /* make compiler happy */
#endif
}
#ifndef PNG_NO_WARNINGS
/* 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
warning_message = warning_message; /* make compiler happy */
#endif
png_ptr = png_ptr; /* make compiler happy */
}
#endif /* PNG_NO_WARNINGS */
/* 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 */

View File

@@ -1,101 +0,0 @@
/* pnggccrd.c was removed from libpng-1.2.20. */
/* This code snippet is for use by configure's compilation test. */
#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
defined(PNG_MMX_CODE_SUPPORTED)
int PNGAPI png_dummy_mmx_support(void);
static int _mmx_supported = 2; // 0: no MMX; 1: MMX supported; 2: not tested
int PNGAPI
png_dummy_mmx_support(void) __attribute__((noinline));
int PNGAPI
png_dummy_mmx_support(void)
{
int result;
#if defined(PNG_MMX_CODE_SUPPORTED) // superfluous, but what the heck
__asm__ __volatile__ (
#if defined(__x86_64__)
"pushq %%rbx \n\t" // rbx gets clobbered by CPUID instruction
"pushq %%rcx \n\t" // so does rcx...
"pushq %%rdx \n\t" // ...and rdx (but rcx & rdx safe on Linux)
"pushfq \n\t" // save Eflag to stack
"popq %%rax \n\t" // get Eflag from stack into rax
"movq %%rax, %%rcx \n\t" // make another copy of Eflag in rcx
"xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
"pushq %%rax \n\t" // save modified Eflag back to stack
"popfq \n\t" // restore modified value to Eflag reg
"pushfq \n\t" // save Eflag to stack
"popq %%rax \n\t" // get Eflag from stack
"pushq %%rcx \n\t" // save original Eflag to stack
"popfq \n\t" // restore original Eflag
#else
"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)
"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
"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
#endif
"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
#if defined(__x86_64__)
"popq %%rdx \n\t" // restore rdx
"popq %%rcx \n\t" // restore rcx
"popq %%rbx \n\t" // restore rbx
#else
"popl %%edx \n\t" // restore edx
"popl %%ecx \n\t" // restore ecx
"popl %%ebx \n\t" // restore ebx
#endif
// "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

View File

@@ -1,901 +0,0 @@
/* 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);
}
return (0);
}
#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);
}
return (0);
}
#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)
{
/* obsolete, to be removed from libpng-1.4.0 */
return (png_ptr? 0L: 0L);
}
/* 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)
{
/* obsolete, to be removed from libpng-1.4.0 */
flag_select=flag_select;
return 0L;
}
/* 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)
{
/* obsolete, to be removed from libpng-1.4.0 */
flag_select=flag_select;
*compilerID = -1; /* unknown (i.e., no asm/MMX code compiled) */
return 0L;
}
/* this function was added to libpng 1.2.0 */
png_byte PNGAPI
png_get_mmx_bitdepth_threshold (png_structp png_ptr)
{
/* obsolete, to be removed from libpng-1.4.0 */
return (png_ptr? 0: 0);
}
/* this function was added to libpng 1.2.0 */
png_uint_32 PNGAPI
png_get_mmx_rowbytes_threshold (png_structp png_ptr)
{
/* obsolete, to be removed from libpng-1.4.0 */
return (png_ptr? 0L: 0L);
}
#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 */

View File

@@ -1,608 +0,0 @@
/* 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 */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,167 +0,0 @@
/* 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 */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,662 +0,0 @@
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
*
* 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"
#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)
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
};
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
};
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 */

View File

@@ -1 +0,0 @@
/* pnggvrd.c was removed from libpng-1.2.20. */

View File

@@ -1,234 +0,0 @@
/* 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-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 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 */

File diff suppressed because it is too large Load Diff

View File

@@ -1,572 +0,0 @@
/* 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 */

File diff suppressed because it is too large Load Diff

View File

@@ -1,855 +0,0 @@
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 <memory.h> 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 <info@winimage.com>
386 asm code replacing longest_match().
contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
A C++ I/O streams interface to the zlib gz* functions
contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
Another C++ I/O streams interface
contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
A very simple tar.gz file extractor using zlib
contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
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()

View File

@@ -1,339 +0,0 @@
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 <zlib.h>, 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.

View File

@@ -1,125 +0,0 @@
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 <zlib@gzip.org>, or to Gilles Vollant
<info@winimage.com> 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 <markn@ieee.org> 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 <pmqs@cpan.org> 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 <amk@amk.ca> 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 <a.kupries@westend.com> 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 <info@winimage.com>, 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.

View File

@@ -1,149 +0,0 @@
/* 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);
}

View File

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

View File

@@ -1,79 +0,0 @@
/* 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;
}

View File

@@ -1,423 +0,0 @@
/* 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 <rbrown64@csc.com.au> 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 <stdio.h>
# 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 <limits.h>
# 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;
}

View File

@@ -1,441 +0,0 @@
/* 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
}
};

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