This commit is contained in:
Kulikova Svetlana
2021-03-25 16:08:08 +03:00
parent 3b84a04b3a
commit cd943c43fd
21 changed files with 19 additions and 3570 deletions

View File

@ -23,20 +23,20 @@ SOURCES += \
$$PWD/../hunspell/src/hunspell/suggestmgr.cxx
HEADERS += \
$$PWD/../hunspell/src/hunspell/affentry.hxx \
$$PWD/../hunspell/src/hunspell/affixmgr.hxx \
$$PWD/../hunspell/src/hunspell/atypes.hxx \
$$PWD/../hunspell/src/hunspell/baseaffix.hxx \
$$PWD/../hunspell/src/hunspell/csutil.hxx \
$$PWD/../hunspell/src/hunspell/dictmgr.hxx \
$$PWD/../hunspell/src/hunspell/filemgr.hxx \
$$PWD/../hunspell/src/hunspell/hashmgr.hxx \
$$PWD/../hunspell/src/hunspell/htypes.hxx \
$$PWD/../hunspell/src/hunspell/hunspell.h \
$$PWD/../hunspell/src/hunspell/hunspell.hxx \
$$PWD/../hunspell/src/hunspell/hunzip.hxx \
$$PWD/../hunspell/src/hunspell/langnum.hxx \
$$PWD/../hunspell/src/hunspell/phonet.hxx \
$$PWD/../hunspell/src/hunspell/replist.hxx \
$$PWD/../hunspell/src/hunspell/suggestmgr.hxx \
$$PWD/../hunspell/src/hunspell/w_char.hxx
$$PWD/../hunspell/affentry.hxx \
$$PWD/../hunspell/affixmgr.hxx \
$$PWD/../hunspell/atypes.hxx \
$$PWD/../hunspell/baseaffix.hxx \
$$PWD/../hunspell/csutil.hxx \
$$PWD/../hunspell/dictmgr.hxx \
$$PWD/../hunspell/filemgr.hxx \
$$PWD/../hunspell/hashmgr.hxx \
$$PWD/../hunspell/htypes.hxx \
$$PWD/../hunspell/hunspell.h \
$$PWD/../hunspell/hunspell.hxx \
$$PWD/../hunspell/hunzip.hxx \
$$PWD/../hunspell/langnum.hxx \
$$PWD/../hunspell/phonet.hxx \
$$PWD/../hunspell/replist.hxx \
$$PWD/../hunspell/suggestmgr.hxx \
$$PWD/../hunspell/w_char.hxx

View File

@ -102,9 +102,6 @@ typedef T_ULONG64 UINT64;
#else
#if (!defined (_MAC) && (!defined(MIDL_PASS) || defined(__midl)) && (!defined(_M_IX86) || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64)))
#ifdef BUILDING_WASM_MODULE
#define __int64 long long
#endif
typedef __int64 T_LONG64;
typedef unsigned __int64 T_ULONG64;
typedef T_ULONG64 ULONG64;

View File

@ -65,6 +65,7 @@ extern "C" {
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types

View File

@ -21,7 +21,6 @@
/////////////////////////////////////////////////////////////////////////////
// CxImage supported formats
#define CXIMAGE_SUPPORT_BMP 1
#define CXIMAGE_SUPPORT_GIF 1
#define CXIMAGE_SUPPORT_JPG 1

View File

@ -1,28 +0,0 @@
#ifndef __xfile_h
#define __xfile_h
#include "ximadef.h"
class CxFile
{
public:
CxFile() {}
virtual ~CxFile() {}
virtual bool Close() = 0;
virtual size_t Read(void* buffer, size_t size, size_t count, void* limit_start = NULL, void* limit_end = NULL) = 0;
virtual size_t Write(const void* buffer, size_t size, size_t count) = 0;
virtual bool Seek(int32_t offset, int32_t origin) = 0;
virtual int32_t Tell() = 0;
virtual bool Flush() = 0;
virtual int32_t Error() = 0;
virtual bool PutC(uint8_t c)
{
// Default implementation
size_t nWrote = Write(&c, 1, 1);
return (bool)(nWrote == 1);
}
virtual int32_t GetC() = 0;
};
#endif //__xfile_h

View File

@ -1,55 +0,0 @@
#ifndef __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
#if defined(_WIN32) || defined (_WIN64)
#define CXIMAGE_SUPPORT_LAYERS 1
#else
#define CXIMAGE_SUPPORT_LAYERS 0
#endif
#define CXIMAGE_SUPPORT_INTERPOLATION 1
#define CXIMAGE_SUPPORT_DECODE 1
#define CXIMAGE_SUPPORT_ENCODE 1
#define CXIMAGE_SUPPORT_EXIF 1
// CxImage supported formats
#define CXIMAGE_SUPPORT_BMP 0
#define CXIMAGE_SUPPORT_GIF 0
#define CXIMAGE_SUPPORT_JPG 1
#define CXIMAGE_SUPPORT_PNG 0
#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
#define CXIMAGE_SUPPORT_MNG 0
#define CXIMAGE_SUPPORT_SKA 0
#define CXIMAGE_SUPPORT_RAW 0
#define CXIMAGE_SUPPORT_PSD 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
#define RGB2GRAY(r, g, b) (((b) * 117 + (g) * 601 + (r) * 306) >> 10)
#endif // __ximacfg_h

View File

@ -1,48 +0,0 @@
#ifndef __ximadef_h
#define __ximadef_h
#include "ximacfg.h"
#include <string>
#if defined(WIN32) || defined(_WIN32_WCE)
#include "stdint.h"
#endif
#ifndef BOOL
typedef int BOOL;
#endif
typedef struct tagRECT
{
int32_t left;
int32_t top;
int32_t right;
int32_t bottom;
} RECT;
typedef struct tagRGBQUAD
{
uint8_t rgbBlue;
uint8_t rgbGreen;
uint8_t rgbRed;
uint8_t rgbReserved;
} RGBQUAD;
typedef struct tagBITMAPINFOHEADER
{
uint32_t biSize;
int32_t biWidth;
int32_t biHeight;
uint16_t biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
int32_t biXPelsPerMeter;
int32_t biYPelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
} BITMAPINFOHEADER;
#define BI_RGB 0L
#endif //__ximadef_h

View File

@ -1,763 +0,0 @@
#include "ximage.h"
#if CXIMAGE_SUPPORT_JPG
#include "ximajpg.h"
#endif
#if CXIMAGE_SUPPORT_GIF
#include "ximagif.h"
#endif
#if CXIMAGE_SUPPORT_PNG
#include "ximapng.h"
#endif
#if CXIMAGE_SUPPORT_MNG
#include "ximamng.h"
#endif
#if CXIMAGE_SUPPORT_BMP
#include "ximabmp.h"
#endif
#if CXIMAGE_SUPPORT_ICO
#include "ximaico.h"
#endif
#if CXIMAGE_SUPPORT_TIF
#include "ximatif.h"
#endif
#if CXIMAGE_SUPPORT_TGA
#include "ximatga.h"
#endif
#if CXIMAGE_SUPPORT_PCX
#include "ximapcx.h"
#endif
#if CXIMAGE_SUPPORT_WBMP
#include "ximawbmp.h"
#endif
#if CXIMAGE_SUPPORT_WMF
#include "ximawmf.h"
#endif
#if CXIMAGE_SUPPORT_JBG
#include "ximajbg.h"
#endif
#if CXIMAGE_SUPPORT_JASPER
#include "ximajas.h"
#endif
#if CXIMAGE_SUPPORT_SKA
#include "ximaska.h"
#endif
#if CXIMAGE_SUPPORT_RAW
#include "ximaraw.h"
#endif
#if CXIMAGE_SUPPORT_PSD
#include "ximapsd.h"
#endif
#if CXIMAGE_SUPPORT_DECODE
CxImage::CxImage(uint8_t* buffer, uint32_t size, uint32_t imagetype)
{
Startup(imagetype);
CxMemFile stream(buffer, size);
Decode(&stream, imagetype);
}
bool CxImage::Decode(uint8_t* buffer, uint32_t size, uint32_t imagetype)
{
CxMemFile file(buffer,size);
return Decode(&file, imagetype);
}
bool CxImage::Decode(CxFile* hFile, uint32_t imagetype)
{
if (hFile == NULL)
{
strcpy(info.szLastError, CXIMAGE_ERR_NOFILE);
return false;
}
uint32_t pos = hFile->Tell();
#if CXIMAGE_SUPPORT_BMP
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_BMP==imagetype){
CxImageBMP *newima = new CxImageBMP;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_JPG
if (CXIMAGE_FORMAT_UNKNOWN == imagetype || CXIMAGE_FORMAT_JPG == imagetype)
{
CxImageJPG *newima = new CxImageJPG;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile))
{
Transfer(*newima);
delete newima;
return true;
}
else
{
strcpy(info.szLastError, newima->GetLastError());
hFile->Seek(pos, SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN != imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_ICO
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_ICO==imagetype){
CxImageICO *newima = new CxImageICO;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
info.nNumFrames = newima->info.nNumFrames;
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_GIF
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_GIF==imagetype){
CxImageGIF *newima = new CxImageGIF;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
info.nNumFrames = newima->info.nNumFrames;
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_PNG
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_PNG==imagetype){
CxImagePNG *newima = new CxImagePNG;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_TIF
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_TIF==imagetype){
CxImageTIF *newima = new CxImageTIF;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
info.nNumFrames = newima->info.nNumFrames;
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_MNG
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_MNG==imagetype){
CxImageMNG *newima = new CxImageMNG;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
info.nNumFrames = newima->info.nNumFrames;
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_TGA
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_TGA==imagetype){
CxImageTGA *newima = new CxImageTGA;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_PCX
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_PCX==imagetype){
CxImagePCX *newima = new CxImagePCX;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_WBMP
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_WBMP==imagetype){
CxImageWBMP *newima = new CxImageWBMP;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_WMF==imagetype){
CxImageWMF *newima = new CxImageWMF;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_JBG
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_JBG==imagetype){
CxImageJBG *newima = new CxImageJBG;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_JASPER
if (CXIMAGE_FORMAT_UNKNOWN==imagetype ||
#if CXIMAGE_SUPPORT_JP2
CXIMAGE_FORMAT_JP2==imagetype ||
#endif
#if CXIMAGE_SUPPORT_JPC
CXIMAGE_FORMAT_JPC==imagetype ||
#endif
#if CXIMAGE_SUPPORT_PGX
CXIMAGE_FORMAT_PGX==imagetype ||
#endif
#if CXIMAGE_SUPPORT_PNM
CXIMAGE_FORMAT_PNM==imagetype ||
#endif
#if CXIMAGE_SUPPORT_RAS
CXIMAGE_FORMAT_RAS==imagetype ||
#endif
false ){
CxImageJAS *newima = new CxImageJAS;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_SKA
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_SKA==imagetype){
CxImageSKA *newima = new CxImageSKA;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_RAW
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_RAW==imagetype){
CxImageRAW *newima = new CxImageRAW;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_PSD
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_PSD==imagetype){
CxImagePSD *newima = new CxImagePSD;
if (!newima)
return false;
newima->CopyInfo(*this);
if (newima->Decode(hFile)) {
Transfer(*newima);
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif
strcpy(info.szLastError, "Decode: Unknown or wrong format");
return false;
}
#endif // CXIMAGE_SUPPORT_DECODE
#if CXIMAGE_SUPPORT_ENCODE
bool CxImage::EncodeSafeCheck(CxFile* hFile)
{
if (hFile == NULL)
{
strcpy(info.szLastError, CXIMAGE_ERR_NOFILE);
return true;
}
if (pDib == NULL)
{
strcpy(info.szLastError, CXIMAGE_ERR_NOIMAGE);
return true;
}
return false;
}
bool CxImage::Encode(uint8_t* &buffer, int32_t &size, uint32_t imagetype)
{
/*
if (buffer != NULL)
{
strcpy(info.szLastError, "the buffer must be empty");
return false;
}
*/
CxMemFile file;
file.Open();
if (Encode(&file, imagetype))
{
buffer = file.GetBuffer();
size = file.Size();
return true;
}
return false;
}
bool CxImage::Encode(CxFile* hFile, uint32_t imagetype)
{
#if CXIMAGE_SUPPORT_BMP
if (CXIMAGE_FORMAT_BMP==imagetype){
CxImageBMP *newima = new CxImageBMP;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_ICO
if (CXIMAGE_FORMAT_ICO==imagetype){
CxImageICO *newima = new CxImageICO;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_TIF
if (CXIMAGE_FORMAT_TIF==imagetype){
CxImageTIF *newima = new CxImageTIF;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_JPG
if (CXIMAGE_FORMAT_JPG == imagetype)
{
CxImageJPG* newima = new CxImageJPG;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile))
{
delete newima;
return true;
}
else
{
strcpy(info.szLastError, newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_GIF
if (CXIMAGE_FORMAT_GIF==imagetype){
CxImageGIF *newima = new CxImageGIF;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_PNG
if (CXIMAGE_FORMAT_PNG==imagetype){
CxImagePNG *newima = new CxImagePNG;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_MNG
if (CXIMAGE_FORMAT_MNG==imagetype){
CxImageMNG *newima = new CxImageMNG;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_TGA
if (CXIMAGE_FORMAT_TGA==imagetype){
CxImageTGA *newima = new CxImageTGA;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_PCX
if (CXIMAGE_FORMAT_PCX==imagetype){
CxImagePCX *newima = new CxImagePCX;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_WBMP
if (CXIMAGE_FORMAT_WBMP==imagetype){
CxImageWBMP *newima = new CxImageWBMP;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS // <vho> - WMF/EMF support
if (CXIMAGE_FORMAT_WMF==imagetype){
CxImageWMF *newima = new CxImageWMF;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_JBG
if (CXIMAGE_FORMAT_JBG==imagetype){
CxImageJBG *newima = new CxImageJBG;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_JASPER
if (
#if CXIMAGE_SUPPORT_JP2
CXIMAGE_FORMAT_JP2==imagetype ||
#endif
#if CXIMAGE_SUPPORT_JPC
CXIMAGE_FORMAT_JPC==imagetype ||
#endif
#if CXIMAGE_SUPPORT_PGX
CXIMAGE_FORMAT_PGX==imagetype ||
#endif
#if CXIMAGE_SUPPORT_PNM
CXIMAGE_FORMAT_PNM==imagetype ||
#endif
#if CXIMAGE_SUPPORT_RAS
CXIMAGE_FORMAT_RAS==imagetype ||
#endif
false ){
CxImageJAS *newima = new CxImageJAS;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile,imagetype)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_SKA
if (CXIMAGE_FORMAT_SKA==imagetype){
CxImageSKA *newima = new CxImageSKA;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_RAW
if (CXIMAGE_FORMAT_RAW==imagetype){
CxImageRAW *newima = new CxImageRAW;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_PSD
if (CXIMAGE_FORMAT_PSD==imagetype){
CxImagePSD *newima = new CxImagePSD;
if (!newima) return false;
newima->Ghost(this);
if (newima->Encode(hFile)){
delete newima;
return true;
} else {
strcpy(info.szLastError,newima->GetLastError());
delete newima;
return false;
}
}
#endif
strcpy(info.szLastError, "Encode: Unknown format");
return false;
}
bool CxImage::Encode2RGBA(uint8_t* &buffer, int32_t &size, bool bFlipY)
{
if (buffer != NULL)
{
strcpy(info.szLastError, "the buffer must be empty");
return false;
}
CxMemFile file;
file.Open();
if (Encode2RGBA(&file, bFlipY))
{
buffer = file.GetBuffer();
size = file.Size();
return true;
}
return false;
}
bool CxImage::Encode2RGBA(CxFile* hFile, bool bFlipY)
{
if (EncodeSafeCheck(hFile)) return false;
for (int32_t y1 = 0; y1 < head.biHeight; y1++)
{
int32_t y = bFlipY ? head.biHeight - 1 - y1 : y1;
for (int32_t x = 0; x < head.biWidth; x++)
{
RGBQUAD color = BlindGetPixelColor(x, y);
hFile->PutC(color.rgbRed);
hFile->PutC(color.rgbGreen);
hFile->PutC(color.rgbBlue);
hFile->PutC(color.rgbReserved);
}
}
return true;
}
#endif //CXIMAGE_SUPPORT_ENCODE

View File

@ -1,852 +0,0 @@
#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 (int32_t 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, int32_t nReadMode)
{
int32_t a;
int32_t HaveCom = FALSE;
a = hFile->GetC();
if (a != 0xff || hFile->GetC() != M_SOI)
return FALSE;
for (;;)
{
int32_t itemlen;
int32_t marker = 0;
int32_t ll, lh, got;
uint8_t* 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 = (uint8_t *)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] = (uint8_t)lh;
Data[1] = (uint8_t)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)
{
int32_t 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 = (uint8_t*)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) && itemlen >= 6 && memcmp(Data + 2, "Exif", 4) == 0)
m_exifinfo->IsExif = process_EXIF((uint8_t*)Data + 2, itemlen - 2);
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:
if (itemlen < 8)
return false;
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;
}
bool CxImageJPG::CxExifInfo::process_EXIF(uint8_t* CharBuf, uint32_t 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 */
if (length < 6)
return false;
ExifImageWidth = 0;
{ /* Check the EXIF header component */
static const uint8_t ExifHeader[] = "Exif\0\0";
if (memcmp(CharBuf + 0, ExifHeader, 6))
{
strcpy(m_szLastError, "Incorrect Exif header");
return false;
}
}
if (length < 8)
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;
}
}
if (length < 14)
return false;
/* Check the next two values for correctness. */
if (Get16u(CharBuf + 8) != 0x2a)
{
strcpy(m_szLastError, "Invalid Exif start (1)");
return false;
}
int32_t 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;
}*/
uint8_t * LastExifRefd = CharBuf;
#if 0
/* 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;
}
#else
CSafeReader reader(CharBuf, length);
/* First directory starts 16 bytes in. Offsets start at 8 bytes in. */
if (!ProcessExifDir2(reader.Offset(14), reader.Offset(6), length - 6, m_exifinfo, &LastExifRefd))
return false;
/* <Richard Collins> give a chance for a second directory */
if (FirstOffset > 8)
{
if (!ProcessExifDir2(reader.Offset(14 + FirstOffset - 8), reader.Offset(6), length - 6, m_exifinfo, &LastExifRefd))
return false;
}
#endif
/* This is how far the interesting (non thumbnail) part of the exif went. */
// int32_t 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;
}
int32_t CxImageJPG::CxExifInfo::Get16u(void* Short)
{
if (MotorolaOrder)
return (((uint8_t*)Short)[0] << 8) | ((uint8_t*)Short)[1];
else
return (((uint8_t*)Short)[1] << 8) | ((uint8_t*)Short)[0];
}
int32_t CxImageJPG::CxExifInfo::Get16m(void * Short)
{
return (((uint8_t *)Short)[0] << 8) | ((uint8_t *)Short)[1];
}
int32_t CxImageJPG::CxExifInfo::Get32s(void* Long)
{
if (MotorolaOrder)
return ((( char*)Long)[0] << 24) | (((uint8_t*)Long)[1] << 16)
| (((uint8_t*)Long)[2] << 8) | (((uint8_t*)Long)[3] << 0);
else
return ((( char*)Long)[3] << 24) | (((uint8_t*)Long)[2] << 16)
| (((uint8_t*)Long)[1] << 8) | (((uint8_t*)Long)[0] << 0);
}
uint32_t CxImageJPG::CxExifInfo::Get32u(void* Long)
{
return (uint32_t)Get32s(Long) & 0xffffffff;
}
/* Describes format descriptor */
static const int32_t 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
bool CxImageJPG::CxExifInfo::ProcessExifDir2(CSafeReader DirStart, CSafeReader OffsetBase, unsigned ExifLength,
EXIFINFO* const m_exifinfo, uint8_t** const LastExifRefdP, int32_t NestingLevel)
{
int32_t de;
int32_t a;
int32_t NumDirEntries;
unsigned ThumbnailOffset = 0;
unsigned ThumbnailSize = 0;
if (NestingLevel > 4)
{
strcpy(m_szLastError,"Maximum directory nesting exceeded (corrupt exif header)");
return false;
}
NumDirEntries = DirStart.Check(2) ? Get16u(DirStart.GetData(0)) : 0;
if ((DirStart.GetData(2 + NumDirEntries * 12 + 2)) > (OffsetBase.GetData(ExifLength)))
{
strcpy(m_szLastError, "Illegally sized directory");
return false;
}
for (de = 0; de < NumDirEntries; de++)
{
int32_t Tag, Format, Components;
CSafeReader 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.
*/
int32_t ByteCount;
CSafeReader DirEntry = DirStart.Offset(2 + 12 * de);
Tag = DirEntry.Check(2) ? Get16u(DirEntry.GetData(0)) : 0;
Format = DirEntry.Check(2, 2) ? Get16u(DirEntry.GetData(2)) : 0;
Components = DirEntry.Check(4, 4) ? Get32u(DirEntry.GetData(4)) : 0;
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 = DirEntry.Check(8, 4) ? Get32u(DirEntry.GetData(8)) : 0;
/* 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.Offset(OffsetVal);
}
else
{
/* 4 bytes or less and value is in the dir entry itself */
ValuePtr = DirEntry.Offset(8);
}
if (*LastExifRefdP < ValuePtr.GetData(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.GetData(ByteCount);
}
/* Extract useful components of tag */
switch(Tag)
{
case TAG_MAKE:
if (ValuePtr.Check(31)) strncpy(m_exifinfo->CameraMake, (char*)ValuePtr.GetData(0), 31);
break;
case TAG_MODEL:
if (ValuePtr.Check(39)) strncpy(m_exifinfo->CameraModel, (char*)ValuePtr.GetData(0), 39);
break;
case TAG_EXIF_VERSION:
if (ValuePtr.Check(4)) strncpy(m_exifinfo->Version,(char*)ValuePtr.GetData(0), 4);
break;
case TAG_DATETIME_ORIGINAL:
if (ValuePtr.Check(19)) strncpy(m_exifinfo->DateTime, (char*)ValuePtr.GetData(0), 19);
break;
case TAG_USERCOMMENT:
// Olympus has this padded with trailing spaces. Remove these first.
if (ValuePtr.Check(ByteCount))
{
for (a = ByteCount;;)
{
a--;
if (*((char*)ValuePtr.GetData(a)) == ' ')
*((char*)ValuePtr.GetData(a)) = '\0';
else
break;
if (a == 0) break;
}
}
/* Copy the comment */
if (ValuePtr.Check(5) && memcmp(ValuePtr.GetData(0), "ASCII", 5) == 0)
{
for (a = 5; a < 10; a++)
{
char c;
c = *((char*)ValuePtr.GetData(a));
if (c != '\0' && c != ' ')
{
if (ValuePtr.Check(a, 199))
strncpy(m_exifinfo->Comments, (char*)ValuePtr.GetData(a), 199);
break;
}
}
}
else if (ValuePtr.Check(199))
strncpy(m_exifinfo->Comments, (char*)ValuePtr.GetData(0), 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)ConvertAnyFormat2(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(ConvertAnyFormat2(ValuePtr, Format)*log(2.0f)*0.5);
}
break;
case TAG_BRIGHTNESS:
m_exifinfo->Brightness = (float)ConvertAnyFormat2(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)ConvertAnyFormat2(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)ConvertAnyFormat2(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)ConvertAnyFormat2(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(ConvertAnyFormat2(ValuePtr, Format) * log(2.0f)));
}
break;
case TAG_FLASH:
if ((int32_t)ConvertAnyFormat2(ValuePtr, Format) & 7)
m_exifinfo->FlashUsed = 1;
else
m_exifinfo->FlashUsed = 0;
break;
case TAG_ORIENTATION:
m_exifinfo->Orientation = (int32_t)ConvertAnyFormat2(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 = (int32_t)ConvertAnyFormat2(ValuePtr, Format);
if (ExifImageWidth < a) ExifImageWidth = a;
break;
case TAG_FOCALPLANEXRES:
m_exifinfo->FocalplaneXRes = (float)ConvertAnyFormat2(ValuePtr, Format);
break;
case TAG_FOCALPLANEYRES:
m_exifinfo->FocalplaneYRes = (float)ConvertAnyFormat2(ValuePtr, Format);
break;
case TAG_RESOLUTIONUNIT:
switch ((int32_t)ConvertAnyFormat2(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 ((int32_t)ConvertAnyFormat2(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) ConvertAnyFormat2(ValuePtr, Format);
break;
case TAG_WHITEBALANCE:
m_exifinfo->Whitebalance = (int32_t)ConvertAnyFormat2(ValuePtr, Format);
break;
case TAG_METERING_MODE:
m_exifinfo->MeteringMode = (int32_t)ConvertAnyFormat2(ValuePtr, Format);
break;
case TAG_EXPOSURE_PROGRAM:
m_exifinfo->ExposureProgram = (int32_t)ConvertAnyFormat2(ValuePtr, Format);
break;
case TAG_ISO_EQUIVALENT:
m_exifinfo->ISOequivalent = (int32_t)ConvertAnyFormat2(ValuePtr, Format);
if ( m_exifinfo->ISOequivalent < 50 ) m_exifinfo->ISOequivalent *= 200;
break;
case TAG_COMPRESSION_LEVEL:
m_exifinfo->CompressionLevel = (int32_t)ConvertAnyFormat2(ValuePtr, Format);
break;
case TAG_XRESOLUTION:
m_exifinfo->Xresolution = (float)ConvertAnyFormat2(ValuePtr, Format);
break;
case TAG_YRESOLUTION:
m_exifinfo->Yresolution = (float)ConvertAnyFormat2(ValuePtr, Format);
break;
case TAG_THUMBNAIL_OFFSET:
ThumbnailOffset = (unsigned)ConvertAnyFormat2(ValuePtr, Format);
break;
case TAG_THUMBNAIL_LENGTH:
ThumbnailSize = (unsigned)ConvertAnyFormat2(ValuePtr, Format);
break;
}
if (Tag == TAG_EXIF_OFFSET || Tag == TAG_INTEROP_OFFSET)
{
unsigned Offset = ValuePtr.Check(4) ? Get32u(ValuePtr.GetData(0)) : 0;
if (Offset > 8)
{
if (!OffsetBase.Check(Offset))
{
strcpy(m_szLastError, "Illegal subdirectory link");
return false;
}
ProcessExifDir2(OffsetBase.Offset(Offset), 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 Offset;
Offset = DirStart.Check(2 + 12 * NumDirEntries, 2) ? Get16u(DirStart.GetData(2 + 12 * NumDirEntries)) : 0;
if (Offset)
{
if (!OffsetBase.Check(Offset))
{
strcpy(m_szLastError, "Illegal subdirectory link");
return false;
}
ProcessExifDir2(OffsetBase.Offset(Offset), 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.GetData(ThumbnailOffset);
m_exifinfo->ThumbnailSize = ThumbnailSize;
}
}
return true;
}
double CxImageJPG::CxExifInfo::ConvertAnyFormat2(CSafeReader& reader, int32_t Format)
{
double Value;
Value = 0;
switch (Format)
{
case FMT_SBYTE:
case FMT_BYTE: if (!reader.Check(1)) {return Value;} break;
case FMT_USHORT:
case FMT_SSHORT: if (!reader.Check(2)) {return Value;} break;
case FMT_ULONG:
case FMT_SLONG: if (!reader.Check(4)) {return Value;} break;
case FMT_URATIONAL:
case FMT_SRATIONAL: if (!reader.Check(8)) {return Value;} break;
case FMT_SINGLE: if (!reader.Check(sizeof(float))) {return Value;} break;
case FMT_DOUBLE: if (!reader.Check(sizeof(double))) {return Value;} break;
default: break;
}
void * ValuePtr = (void*)reader.GetData(0);
switch(Format)
{
case FMT_SBYTE: Value = *(signed char *)ValuePtr; break;
case FMT_BYTE: Value = *(uint8_t *)ValuePtr; break;
case FMT_USHORT: Value = Get16u(ValuePtr); break;
case FMT_ULONG: Value = Get32u(ValuePtr); break;
case FMT_URATIONAL:
case FMT_SRATIONAL:
{
int32_t Num,Den;
Num = Get32s(ValuePtr);
Den = Get32s(4 + (char*)ValuePtr);
Value = Den == 0 ? 0 : (double)Num / Den;
break;
}
case FMT_SSHORT: Value = (int16_t)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 uint8_t* Data, int32_t length)
{
int32_t ch;
char Comment[MAX_COMMENT + 1];
int32_t nch;
int32_t 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' && (a < (length - 1) && Data[a + 1] == '\n')) continue; // Remove cr followed by lf.
Comment[nch++] = (isprint(ch) || ch == '\n' || ch == '\t') ? (char)ch : '?';
}
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 uint8_t* Data, int32_t marker)
{
int32_t 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];
m_exifinfo->IsColor = num_components == 3 ? 1 : 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);
}
bool CxImageJPG::CxExifInfo::EncodeExif(CxFile * hFile)
{
int32_t 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 uint8_t 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((uint8_t)(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;
int32_t 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(int32_t SectionType)
{
int32_t 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,207 +0,0 @@
#include "ximage.h"
void CxImage::Startup(uint32_t imagetype)
{
//init pointers
pDib = pDibLimit = 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;
info.nJpegScale = 1;
SetXDPI(CXIMAGE_DEFAULT_DPI);
SetYDPI(CXIMAGE_DEFAULT_DPI);
int16_t test = 1;
info.bLittleEndianHost = (*((char *) &test) == 1);
}
CxImage::CxImage(uint32_t imagetype)
{
Startup(imagetype);
}
bool CxImage::Destroy()
{
//free this only if it's valid and it's not a ghost
if (info.pGhost==NULL)
{
if (ppLayers)
{
for (int32_t 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 (int32_t n = 0; n < info.nNumFrames; n++) delete ppFrames[n];
delete[] ppFrames; ppFrames = NULL; info.nNumFrames = 0;
}
return true;
}
return false;
}
void CxImage::CopyInfo(const CxImage &src)
{
if (pDib == NULL) memcpy(&info, &src.info, sizeof(CXIMAGEINFO));
}
void* CxImage::Create(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32_t 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
if ((((float)dwWidth * (float)dwHeight * (float)wBpp) / 8.0f) > (float)CXIMAGE_MAX_MEMORY)
{
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 = (uint16_t)wBpp; // from parameter
head.biCompression = BI_RGB;
head.biSizeImage = info.dwEffWidth * dwHeight;
pDib = malloc(GetSize()); // alloc memory block to store our bitmap
if (!pDib)
{
strcpy(info.szLastError, "CxImage::Create can't allocate memory");
return NULL;
}
pDibLimit = (void*)((uint8_t*)pDib + GetSize());
//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
}
uint8_t* CxImage::GetBits(uint32_t row)
{
if (pDib)
{
if (row)
{
if (row < (uint32_t)head.biHeight)
return ((uint8_t*)pDib + *(uint32_t*)pDib + GetPaletteSize() + (info.dwEffWidth * row));
return NULL;
}
return ((uint8_t*)pDib + *(uint32_t*)pDib + GetPaletteSize());
}
return NULL;
}
uint32_t CxImage::GetSize()
{
uint64_t size64 = head.biSize + head.biSizeImage + GetPaletteSize();
if (size64 > 0xFFFFFFFF)
return 0xFFFFFFFF;
return (uint32_t)size64;
}
bool CxImage::IsInside(int32_t x, int32_t y)
{
return (0 <= y && y < head.biHeight && 0 <= x && x < head.biWidth);
}
bool CxImage::Transfer(CxImage &from, bool bTransferFrames)
{
if (!Destroy())
return false;
memcpy(&head, &from.head, sizeof(BITMAPINFOHEADER));
memcpy(&info, &from.info, sizeof(CXIMAGEINFO));
pDib = from.pDib;
pDibLimit = from.pDibLimit;
pSelection = from.pSelection;
pAlpha = from.pAlpha;
ppLayers = from.ppLayers;
memset(&from.head, 0, sizeof(BITMAPINFOHEADER));
memset(&from.info, 0, sizeof(CXIMAGEINFO));
from.pDib = from.pDibLimit = from.pSelection = from.pAlpha = NULL;
from.ppLayers = NULL;
if (bTransferFrames)
{
DestroyFrames();
ppFrames = from.ppFrames;
from.ppFrames = NULL;
}
return true;
}
void CxImage::Ghost(const CxImage* from)
{
if (from)
{
memcpy(&head, &from->head, sizeof(BITMAPINFOHEADER));
memcpy(&info, &from->info, sizeof(CXIMAGEINFO));
pDib = from->pDib;
pDibLimit = from->pDibLimit;
pSelection = from->pSelection;
pAlpha = from->pAlpha;
ppLayers = from->ppLayers;
ppFrames = from->ppFrames;
info.pGhost = (CxImage*)from;
}
}

View File

@ -1,254 +0,0 @@
#ifndef __ximage_h
#define __ximage_h
#include "xmemfile.h"
#include "ximadef.h"
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
#if CXIMAGE_SUPPORT_PSD
CXIMAGE_FORMAT_PSD = 20,
#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 + CXIMAGE_SUPPORT_PSD + 1
};
#if CXIMAGE_SUPPORT_EXIF
#define MAX_COMMENT 255
#define MAX_SECTIONS 20
typedef struct tag_ExifInfo
{
char Version [5];
char CameraMake [32];
char CameraModel [40];
char DateTime [20];
int32_t Height, Width;
int32_t Orientation;
int32_t IsColor;
int32_t Process;
int32_t FlashUsed;
float FocalLength;
float ExposureTime;
float ApertureFNumber;
float Distance;
float CCDWidth;
float ExposureBias;
int32_t Whitebalance;
int32_t MeteringMode;
int32_t ExposureProgram;
int32_t ISOequivalent;
int32_t CompressionLevel;
float FocalplaneXRes;
float FocalplaneYRes;
float FocalplaneUnits;
float Xresolution;
float Yresolution;
float ResolutionUnit;
float Brightness;
char Comments[MAX_COMMENT + 1];
uint8_t* ThumbnailPointer;
unsigned ThumbnailSize;
bool IsExif;
} EXIFINFO;
#endif //CXIMAGE_SUPPORT_EXIF
class CxImage
{
typedef struct tagCxImageInfo
{
uint32_t dwEffWidth;
uint8_t* pImage;
CxImage* pGhost;
CxImage* pParent;
uint32_t dwType;
char szLastError[256];
int32_t nProgress;
int32_t nEscape;
int32_t nBkgndIndex;
RGBQUAD nBkgndColor;
float fQuality;
uint8_t nJpegScale;
int32_t nFrame;
int32_t nNumFrames;
uint32_t dwFrameDelay;
int32_t xDPI;
int32_t yDPI;
RECT rSelectionBox;
uint8_t nAlphaMax;
bool bAlphaPaletteEnabled;
bool bEnabled;
int32_t xOffset;
int32_t yOffset;
uint32_t dwCodecOpt[CMAX_IMAGE_FORMATS];
RGBQUAD last_c;
uint8_t last_c_index;
bool last_c_isvalid;
int32_t nNumLayers;
uint32_t dwFlags;
uint8_t dispmeth;
bool bGetAllFrames;
bool bLittleEndianHost;
#if CXIMAGE_SUPPORT_EXIF
EXIFINFO ExifInfo;
#endif
} CXIMAGEINFO;
public:
CxImage(uint32_t imagetype = 0);
#if CXIMAGE_SUPPORT_DECODE
CxImage(uint8_t* buffer, uint32_t size, uint32_t imagetype);
#endif // CXIMAGE_SUPPORT_DECODE
virtual ~CxImage() { DestroyFrames(); Destroy(); };
void* Create(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32_t imagetype = 0);
bool Destroy();
bool DestroyFrames();
bool Transfer(CxImage& from, bool bTransferFrames = true);
uint32_t GetSize();
uint8_t* GetBits(uint32_t row = 0);
uint32_t GetHeight() const;
uint32_t GetWidth() const;
uint32_t GetEffWidth() const;
uint32_t GetType() const;
const char* GetLastError();
uint8_t GetJpegQuality() const;
uint8_t GetJpegScale() const;
int32_t GetXDPI() const;
int32_t GetYDPI() const;
void SetXDPI(int32_t dpi);
void SetYDPI(int32_t dpi);
uint32_t GetCodecOption(uint32_t imagetype = 0);
static uint32_t GetTypeIndexFromId(const uint32_t id);
bool IsGrayScale();
uint32_t GetPaletteSize();
RGBQUAD* GetPalette() const;
RGBQUAD GetPaletteColor(uint8_t idx);
void SetGrayPalette();
void SetPalette(uint32_t n, uint8_t* r, uint8_t* g, uint8_t* b);
bool IsInside(int32_t x, int32_t y);
protected:
uint8_t BlindGetPixelIndex(const int32_t x, const int32_t y);
RGBQUAD BlindGetPixelColor(const int32_t x, const int32_t y, bool bGetAlpha = true);
#if CXIMAGE_SUPPORT_DECODE
public:
bool Decode(CxFile* hFile, uint32_t imagetype);
bool Decode(uint8_t* buffer, uint32_t size, uint32_t imagetype);
#endif //CXIMAGE_SUPPORT_DECODE
#if CXIMAGE_SUPPORT_ENCODE
protected:
bool EncodeSafeCheck(CxFile* hFile);
public:
bool Encode(CxFile* hFile, uint32_t imagetype);
bool Encode(uint8_t* &buffer, int32_t &size, uint32_t imagetype);
bool Encode2RGBA(CxFile* hFile, bool bFlipY = false);
bool Encode2RGBA(uint8_t* &buffer, int32_t &size, bool bFlipY = false);
#endif //CXIMAGE_SUPPORT_ENCODE
#if CXIMAGE_SUPPORT_SELECTION
public:
bool SelectionDelete();
#endif //CXIMAGE_SUPPORT_SELECTION
#if CXIMAGE_SUPPORT_ALPHA
public:
void AlphaDelete();
protected:
uint8_t BlindAlphaGet(const int32_t x,const int32_t y);
#endif //CXIMAGE_SUPPORT_ALPHA
protected:
void Startup(uint32_t imagetype = 0);
void CopyInfo(const CxImage& src);
void Ghost (const CxImage* src);
void RGBtoBGR(uint8_t* buffer, int32_t length);
void* pDib;
void* pDibLimit;
BITMAPINFOHEADER head;
CXIMAGEINFO info;
uint8_t* pSelection;
uint8_t* pAlpha;
CxImage** ppLayers;
CxImage** ppFrames;
};
#endif // __ximage_h

View File

@ -1,126 +0,0 @@
#include "ximage.h"
int32_t CxImage::GetXDPI() const
{
return info.xDPI;
}
int32_t CxImage::GetYDPI() const
{
return info.yDPI;
}
void CxImage::SetXDPI(int32_t dpi)
{
if (dpi <= 0) dpi = CXIMAGE_DEFAULT_DPI;
info.xDPI = dpi;
head.biXPelsPerMeter = (int32_t) floor(dpi * 10000.0 / 254.0 + 0.5);
if (pDib) ((BITMAPINFOHEADER*)pDib)->biXPelsPerMeter = head.biXPelsPerMeter;
}
void CxImage::SetYDPI(int32_t dpi)
{
if (dpi <= 0) dpi = CXIMAGE_DEFAULT_DPI;
info.yDPI = dpi;
head.biYPelsPerMeter = (int32_t) floor(dpi * 10000.0 / 254.0 + 0.5);
if (pDib) ((BITMAPINFOHEADER*)pDib)->biYPelsPerMeter = head.biYPelsPerMeter;
}
uint32_t CxImage::GetCodecOption(uint32_t imagetype)
{
imagetype = GetTypeIndexFromId(imagetype);
if (imagetype == 0)
imagetype = GetTypeIndexFromId(GetType());
return info.dwCodecOpt[imagetype];
}
uint32_t CxImage::GetHeight() const
{
return head.biHeight;
}
uint32_t CxImage::GetWidth() const
{
return head.biWidth;
}
uint32_t CxImage::GetEffWidth() const
{
return info.dwEffWidth;
}
uint32_t CxImage::GetType() const
{
return info.dwType;
}
uint32_t CxImage::GetTypeIndexFromId(const uint32_t id)
{
uint32_t 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
#if CXIMAGE_SUPPORT_PSD
n++; if (id == CXIMAGE_FORMAT_PSD) return n;
#endif
return 0;
}
uint8_t CxImage::GetJpegQuality() const
{
return (uint8_t)(info.fQuality + 0.5f);
}
uint8_t CxImage::GetJpegScale() const
{
return info.nJpegScale;
}
const char* CxImage::GetLastError()
{
return info.szLastError;
}

View File

@ -1,74 +0,0 @@
#ifndef __ximaiter_h
#define __ximaiter_h
#include "ximage.h"
#include "ximadef.h"
#include <algorithm>
class CImageIterator
{
friend class CxImage;
protected:
int32_t Itx, Ity; // Counters
int32_t Stepx, Stepy;
uint8_t* IterImage; // Image pointer
CxImage* ima;
public:
// Constructors
CImageIterator();
CImageIterator(CxImage* image);
operator CxImage* ();
void Upset();
void SetRow(uint8_t* buf, int32_t n);
void GetRow(uint8_t* buf, int32_t n);
uint8_t* GetRow();
BOOL PrevRow();
};
inline CImageIterator::CImageIterator()
{
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 void CImageIterator::Upset()
{
Itx = 0;
Ity = ima->GetHeight() - 1;
IterImage = ima->GetBits() + ima->GetEffWidth() * (ima->GetHeight() - 1);
}
inline void CImageIterator::SetRow(uint8_t* buf, int32_t n)
{
if (n < 0) n = (int32_t)ima->GetEffWidth();
else n = (std::min)(n, (int32_t)ima->GetEffWidth());
if ((IterImage != NULL) && (buf != NULL) && (n > 0)) memcpy(IterImage, buf, n);
}
inline void CImageIterator::GetRow(uint8_t* buf, int32_t n)
{
if ((IterImage != NULL) && (buf != NULL) && (n > 0))
memcpy(buf, IterImage, (std::min)(n, (int32_t)ima->GetEffWidth()));
}
inline BOOL CImageIterator::PrevRow()
{
if (--Ity < 0) return 0;
IterImage -= ima->GetEffWidth();
return 1;
}
inline uint8_t* CImageIterator::GetRow()
{
return IterImage;
}
#endif // __ximaiter_h

View File

@ -1,485 +0,0 @@
#include "ximajpg.h"
#if CXIMAGE_SUPPORT_JPG
#include "../../../../../cximage/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;
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(&info.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(&info.ExifInfo);
if (m_exif)
{
int32_t pos = hFile->Tell();
m_exif->DecodeExif(hFile);
hFile->Seek(pos, SEEK_SET);
return m_exif->m_exifinfo->IsExif;
}
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 */
int32_t 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;
CxFileJpg src(hFile);
/* 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);
cinfo.src = &src;
/* Step 3: read file parameters with jpeg_read_header() */
(void) jpeg_read_header(&cinfo, TRUE);
/* Step 4 <chupeev> handle decoder options*/
uint32_t dwCodecOptions = GetCodecOption(CXIMAGE_FORMAT_JPG); //[nm_114]
if ((dwCodecOptions & DECODE_GRAYSCALE) != 0)
cinfo.out_color_space = JCS_GRAYSCALE;
if ((dwCodecOptions & DECODE_QUANTIZE) != 0) {
cinfo.quantize_colors = TRUE;
cinfo.desired_number_of_colors = GetJpegQuality();
}
if ((dwCodecOptions & DECODE_DITHER) != 0)
cinfo.dither_mode = m_nDither;
if ((dwCodecOptions & DECODE_ONEPASS) != 0)
cinfo.two_pass_quantize = FALSE;
if ((dwCodecOptions & 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>
cinfo.scale_num = 1;
// 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 ((info.ExifInfo.Xresolution != 0.0) && (info.ExifInfo.ResolutionUnit != 0))
SetXDPI((int32_t)(info.ExifInfo.Xresolution/info.ExifInfo.ResolutionUnit));
if ((info.ExifInfo.Yresolution != 0.0) && (info.ExifInfo.ResolutionUnit != 0))
SetYDPI((int32_t)(info.ExifInfo.Yresolution/info.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((int32_t)(GetXDPI()*(float(cinfo.Y_density)/float(cinfo.X_density))));
break;
case 2: // [andy] fix: cinfo.X/Y_density is pixels per centimeter
SetXDPI((int32_t)floor(cinfo.X_density * 2.54 + 0.5));
SetYDPI((int32_t)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 = (int32_t)(100*cinfo.output_scanline/cinfo.output_height);
//<DP> Step 6a: CMYK->RGB */
if ((cinfo.num_components==4)&&(cinfo.quantize_colors==FALSE)){
uint8_t k,*dst,*src;
dst = iter.GetRow();
src = buffer[0];
for(int32_t x3=0,x4=0; x3<(int32_t)info.dwEffWidth && x4<row_stride; x3+=3, x4+=4){
k=src[x4+3];
dst[x3] =(uint8_t)((k * src[x4+2])/255);
dst[x3+1]=(uint8_t)((k * src[x4+1])/255);
dst[x3+2]=(uint8_t)((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)){
uint8_t* r0=GetBits();
for(int32_t 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
int32_t 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 int32_t 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 */
int32_t 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:
*/
uint32_t dwCodecOptions = GetCodecOption(CXIMAGE_FORMAT_JPG); //[nm_114]
//#ifdef C_ARITH_CODING_SUPPORTED
if ((dwCodecOptions & ENCODE_ARITHMETIC) != 0)
cinfo.arith_code = TRUE;
//#endif
//#ifdef ENTROPY_OPT_SUPPORTED
if ((dwCodecOptions & ENCODE_OPTIMIZE) != 0)
cinfo.optimize_coding = TRUE;
//#endif
if ((dwCodecOptions & ENCODE_GRAYSCALE) != 0)
jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE);
if ((dwCodecOptions & ENCODE_SMOOTHING) != 0)
cinfo.smoothing_factor = m_nSmoothing;
jpeg_set_quality(&cinfo, GetJpegQuality(), (dwCodecOptions & ENCODE_BASELINE) != 0);
//#ifdef C_PROGRESSIVE_SUPPORTED
if ((dwCodecOptions & ENCODE_PROGRESSIVE) != 0)
jpeg_simple_progression(&cinfo);
//#endif
#ifdef C_LOSSLESS_SUPPORTED
if ((dwCodecOptions & 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 ((dwCodecOptions & 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 ((dwCodecOptions & 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 = (uint16_t)GetXDPI();
cinfo.Y_density = (uint16_t)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 = (int32_t)(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,278 +0,0 @@
#ifndef __ximajpg_h
#define __ximajpg_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_JPG
#define CXIMAGEJPG_SUPPORT_EXIF CXIMAGE_SUPPORT_EXIF
extern "C"
{
#include "../../../../../cximage/jpeg/jpeglib.h"
#include "../../../../../cximage/jpeg/jerror.h"
}
class CxImageJPG: public CxImage
{
public:
CxImageJPG();
~CxImageJPG();
bool Decode(CxFile * hFile);
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile);
#endif // CXIMAGE_SUPPORT_ENCODE
#if CXIMAGEJPG_SUPPORT_EXIF
#define M_SOF0 0xC0
#define M_SOF1 0xC1
#define M_SOF2 0xC2
#define M_SOF3 0xC3
#define M_SOF5 0xC5
#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
#define M_EOI 0xD9
#define M_SOS 0xDA
#define M_JFIF 0xE0
#define M_EXIF 0xE1
#define M_COM 0xFE
#define PSEUDO_IMAGE_MARKER 0x123;
#define EXIF_READ_EXIF 0x01
#define EXIF_READ_IMAGE 0x02
class CxExifInfo
{
typedef struct tag_Section_t
{
uint8_t* Data;
int32_t Type;
unsigned Size;
} Section_t;
public:
class CSafeReader
{
private:
uint8_t* data;
unsigned int len;
public:
CSafeReader(uint8_t* _data = NULL, unsigned int _len = 0)
{
data = _data;
len = _len;
}
CSafeReader(const CSafeReader& src)
{
data = src.data;
len = src.len;
}
CSafeReader& operator=(const CSafeReader& src)
{
data = src.data;
len = src.len;
return *this;
}
CSafeReader Offset(unsigned int offset)
{
if (offset > len)
offset = len;
CSafeReader reader(data, len);
reader.data += offset;
reader.len -= offset;
return reader;
}
bool Check(unsigned int size)
{
if (len >= size)
return true;
return false;
}
bool Check(unsigned int offset, unsigned int size)
{
return Check(offset + size);
}
uint8_t* GetData(unsigned int offset)
{
return data + offset;
}
};
public:
EXIFINFO* m_exifinfo;
char m_szLastError[256];
CxExifInfo(EXIFINFO* info = NULL);
~CxExifInfo();
bool DecodeExif(CxFile* hFile, int32_t nReadMode = EXIF_READ_EXIF);
bool EncodeExif(CxFile* hFile);
void DiscardAllButExif();
protected:
bool process_EXIF(uint8_t* CharBuf, uint32_t length);
void process_COM (const uint8_t* Data, int32_t length);
void process_SOFn(const uint8_t* Data, int32_t marker);
int32_t Get16u(void* Short);
int32_t Get16m(void* Short);
int32_t Get32s(void* Long);
uint32_t Get32u(void* Long);
double ConvertAnyFormat2(CSafeReader& reader, int32_t Format);
void* FindSection(int32_t SectionType);
bool ProcessExifDir2(CSafeReader DirStart, CSafeReader OffsetBase, unsigned ExifLength,
EXIFINFO* const pInfo, uint8_t** const LastExifRefdP, int32_t NestingLevel = 0);
int32_t ExifImageWidth;
int32_t MotorolaOrder;
Section_t Sections[MAX_SECTIONS];
int32_t SectionsRead;
bool freeinfo;
};
CxExifInfo* m_exif;
bool DecodeExif(CxFile* hFile);
#endif //CXIMAGEJPG_SUPPORT_EXIF
// 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 uint8_t[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 > (int32_t)pSource->bytes_in_buffer){
num_bytes -= (int32_t)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)
{
return;
}
protected:
CxFile* m_pFile;
uint8_t* 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
};
int32_t m_nPredictor;
int32_t m_nPointTransform;
int32_t m_nSmoothing;
int32_t m_nQuantize;
J_DITHER_MODE m_nDither;
};
#endif // CXIMAGE_SUPPORT_JPG
#endif // __ximajpg_h

View File

@ -1,20 +0,0 @@
#include "ximage.h"
#if CXIMAGE_SUPPORT_ALPHA
void CxImage::AlphaDelete()
{
if (pAlpha) { free(pAlpha); pAlpha=0; }
}
uint8_t CxImage::BlindAlphaGet(const int32_t x, const int32_t 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];
}
#endif //CXIMAGE_SUPPORT_ALPHA

View File

@ -1,138 +0,0 @@
#include "ximage.h"
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#endif
void CxImage::RGBtoBGR(uint8_t* buffer, int32_t length)
{
if (buffer && (head.biClrUsed == 0))
{
uint8_t temp;
length = min(length,(int32_t)info.dwEffWidth);
length = min(length,(int32_t)(3 * head.biWidth));
for (int32_t i = 0; i < length; i += 3)
{
temp = buffer[i];
buffer[i] = buffer[i + 2];
buffer[i + 2] = temp;
}
}
}
uint32_t CxImage::GetPaletteSize()
{
return (head.biClrUsed * sizeof(RGBQUAD));
}
RGBQUAD* CxImage::GetPalette() const
{
if ((pDib) && (head.biClrUsed))
return (RGBQUAD*)((uint8_t*)pDib + sizeof(BITMAPINFOHEADER));
return NULL;
}
RGBQUAD CxImage::GetPaletteColor(uint8_t idx)
{
RGBQUAD rgb = {0, 0, 0, 0};
if ((pDib) && (head.biClrUsed))
{
uint8_t* iDst = (uint8_t*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx < head.biClrUsed)
{
int32_t ldx = idx * sizeof(RGBQUAD);
rgb.rgbBlue = iDst[ldx++];
rgb.rgbGreen = iDst[ldx++];
rgb.rgbRed = iDst[ldx++];
rgb.rgbReserved = iDst[ldx];
}
}
return rgb;
}
uint8_t CxImage::BlindGetPixelIndex(const int32_t x, const int32_t y)
{
#ifdef _DEBUG
if ((pDib == NULL) || (head.biClrUsed == 0) || !IsInside(x,y))
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
throw 0;
#else
return 0;
#endif // CXIMAGE_SUPPORT_EXCEPTION_HANDLING
#endif // _DEBUG
if (head.biBitCount == 8)
return info.pImage[y * info.dwEffWidth + x];
uint8_t pos;
uint8_t iDst = info.pImage[y * info.dwEffWidth + (x * head.biBitCount >> 3)];
if (head.biBitCount == 4)
{
pos = (uint8_t)(4 * (1 - x % 2));
iDst &= (0x0F << pos);
return (uint8_t)(iDst >> pos);
}
else if (head.biBitCount==1)
{
pos = (uint8_t)(7 - x % 8);
iDst &= (0x01 << pos);
return (uint8_t)(iDst >> pos);
}
return 0;
}
RGBQUAD CxImage::BlindGetPixelColor(const int32_t x, const int32_t 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 // CXIMAGE_SUPPORT_EXCEPTION_HANDLING
#endif // _DEBUG
if (head.biClrUsed)
rgb = GetPaletteColor(BlindGetPixelIndex(x,y));
else
{
uint8_t* 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;
}
void CxImage::SetGrayPalette()
{
if ((pDib == NULL) || (head.biClrUsed == 0)) return;
RGBQUAD* pal = GetPalette();
for (uint32_t ni = 0; ni < head.biClrUsed; ni++)
pal[ni].rgbBlue = pal[ni].rgbGreen = pal[ni].rgbRed = (uint8_t)(ni * (255 / (head.biClrUsed - 1)));
}
void CxImage::SetPalette(uint32_t n, uint8_t* r, uint8_t* g, uint8_t* b)
{
if ((!r) || (pDib == NULL) || (head.biClrUsed == 0)) return;
if (!g) g = r;
if (!b) b = g;
RGBQUAD* ppal = GetPalette();
uint32_t m = min(n,head.biClrUsed);
for (uint32_t 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;
}
bool CxImage::IsGrayScale()
{
RGBQUAD* ppal = GetPalette();
if (!(pDib && ppal && head.biClrUsed)) return false;
for (uint32_t i = 0; i < head.biClrUsed; i++)
if (ppal[i].rgbBlue != i || ppal[i].rgbGreen != i || ppal[i].rgbRed != i)
return false;
return true;
}

View File

@ -1,18 +0,0 @@
#include "ximage.h"
#if CXIMAGE_SUPPORT_SELECTION
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;
}
#endif //CXIMAGE_SUPPORT_SELECTION

View File

@ -1,165 +0,0 @@
#include "xmemfile.h"
CxMemFile::CxMemFile(uint8_t* pBuffer, uint32_t size)
{
m_pBuffer = pBuffer;
m_Position = 0;
m_Size = m_Edge = size;
m_bFreeOnClose = (pBuffer == 0);
m_bEOF = false;
}
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 = (uint8_t*)malloc(1);
m_bFreeOnClose = true;
return (m_pBuffer != 0);
}
uint8_t* CxMemFile::GetBuffer(bool bDetachBuffer)
{
if (bDetachBuffer)
m_bFreeOnClose = false;
return m_pBuffer;
}
size_t CxMemFile::Read(void* buffer, size_t size, size_t count, void* limit_start, void* limit_end)
{
if (buffer == NULL) return 0;
if (m_pBuffer == NULL) return 0;
if (m_Position >= (int32_t)m_Size)
{
m_bEOF = true;
return 0;
}
int32_t nCount = (int32_t)(count * size);
if (nCount == 0) return 0;
int32_t nRead;
if (m_Position + nCount > (int32_t)m_Size)
{
m_bEOF = true;
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)
{
m_bEOF = false;
if (m_pBuffer == NULL) return 0;
if (buffer == NULL) return 0;
int32_t nCount = (int32_t)(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 > (int32_t)m_Size) m_Size = m_Position;
return count;
}
bool CxMemFile::Seek(int32_t offset, int32_t origin)
{
m_bEOF = false;
if (m_pBuffer == NULL) return false;
int32_t 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;
}
int32_t CxMemFile::Tell()
{
if (m_pBuffer == NULL) return -1;
return m_Position;
}
int32_t CxMemFile::Size()
{
if (m_pBuffer == NULL) return -1;
return m_Size;
}
bool CxMemFile::Flush()
{
return m_pBuffer != NULL;
}
int32_t CxMemFile::Error()
{
if (m_pBuffer == NULL) return -1;
return (m_Position > (int32_t)m_Size);
}
bool CxMemFile::PutC(uint8_t c)
{
m_bEOF = false;
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 > (int32_t)m_Size) m_Size = m_Position;
return true;
}
int32_t CxMemFile::GetC()
{
if (m_pBuffer == NULL || m_Position >= (int32_t)m_Size)
{
m_bEOF = true;
return EOF;
}
return *(uint8_t*)((uint8_t*)m_pBuffer + m_Position++);
}
bool CxMemFile::Alloc(uint32_t dwNewLen)
{
if (dwNewLen > (uint32_t)m_Edge)
{
// find new buffer size
uint32_t dwNewBufferSize = (uint32_t)(((dwNewLen >> 16) + 1)<<16);
// allocate new buffer
if (m_pBuffer == NULL) m_pBuffer = (uint8_t*)malloc(dwNewBufferSize);
else m_pBuffer = (uint8_t*)realloc(m_pBuffer, dwNewBufferSize);
// I own this buffer now (caller knows nothing about it)
m_bFreeOnClose = true;
m_Edge = dwNewBufferSize;
}
return (m_pBuffer != 0);
}

View File

@ -1,37 +0,0 @@
#ifndef __xmemfile_h
#define __xmemfile_h
#include "xfile.h"
class CxMemFile : public CxFile
{
public:
CxMemFile(uint8_t* pBuffer = NULL, uint32_t size = 0);
~CxMemFile();
bool Open();
uint8_t* GetBuffer(bool bDetachBuffer = true);
virtual bool Close();
virtual size_t Read(void* buffer, size_t size, size_t count, void* limit_start = NULL, void* limit_end = NULL);
virtual size_t Write(const void* buffer, size_t size, size_t count);
virtual bool Seek(int32_t offset, int32_t origin);
virtual int32_t Tell();
virtual int32_t Size();
virtual bool Flush();
virtual int32_t Error();
virtual bool PutC(uint8_t c);
virtual int32_t GetC();
protected:
bool Alloc(uint32_t nBytes);
uint8_t* m_pBuffer;
uint32_t m_Size;
bool m_bFreeOnClose;
int32_t m_Position;
int32_t m_Edge;
bool m_bEOF;
};
#endif // __xmemfile_h

View File

@ -148,7 +148,7 @@ sources.append("wasm/src/base.cpp")
compiler_flags.append("-I../../../../OfficeUtils/src/zlib-1.2.11")
compiler_flags.append("-I" + libJasper_src_path + "/include")
compiler_flags.append("-DBUILDING_WASM_MODULE -D_tcsnicmp=strncmp -D_lseek=lseek -D_getcwd=getcwd")
compiler_flags.append("-D__linux__ -DBUILDING_WASM_MODULE -D_tcsnicmp=strncmp -D_lseek=lseek -D_getcwd=getcwd")
# arguments
arguments = ""