mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ec882b6ecd | |||
| 4bcab7e8ce | |||
| 13c9a5e872 | |||
| 2368e794ba | |||
| d297d7852c | |||
| 84221f619e | |||
| 7b55e13263 | |||
| 7d32d74022 | |||
| 46a7372ccf | |||
| 5f0f6ec9bc | |||
| 251a3e58b0 | |||
| c5b5fbb763 | |||
| 214c2e00f1 | |||
| 4d316781ec | |||
| 47a453a745 | |||
| 8b594be2ab | |||
| 88cf60a3ed | |||
| 9a9d60031e | |||
| 66a6b7a111 | |||
| a09de43723 | |||
| b17d5e860f | |||
| 4cd2bd34ce | |||
| 0b3502afdd | |||
| 829fa21ecb |
@ -141,6 +141,8 @@ core_mac {
|
||||
DEFINES += LINUX _LINUX MAC _MAC
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.11
|
||||
QMAKE_LFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH
|
||||
|
||||
QMAKE_CFLAGS += "-Wno-implicit-function-declaration"
|
||||
}
|
||||
|
||||
# PREFIXES
|
||||
@ -149,6 +151,7 @@ core_windows {
|
||||
QMAKE_CXXFLAGS_RELEASE -= -Zc:strictStrings
|
||||
QMAKE_CXXFLAGS -= -Zc:strictStrings
|
||||
QMAKE_CXXFLAGS += /MP
|
||||
DEFINES += WINDOWS_IGNORE_PACKING_MISMATCH
|
||||
|
||||
equals(TEMPLATE, app) {
|
||||
console {
|
||||
|
||||
@ -159,60 +159,90 @@ namespace NSFile
|
||||
else if (0x00 == (byteMain & 0x20))
|
||||
{
|
||||
// 2 byte
|
||||
int val = (int)(((byteMain & 0x1F) << 6) |
|
||||
(pBuffer[lIndex + 1] & 0x3F));
|
||||
int val = 0;
|
||||
if ((lIndex + 1) < lCount)
|
||||
{
|
||||
val = (int)(((byteMain & 0x1F) << 6) |
|
||||
(pBuffer[lIndex + 1] & 0x3F));
|
||||
}
|
||||
|
||||
pUnicodeString[lIndexUnicode++] = (WCHAR)(val);
|
||||
lIndex += 2;
|
||||
}
|
||||
else if (0x00 == (byteMain & 0x10))
|
||||
{
|
||||
// 3 byte
|
||||
int val = (int)(((byteMain & 0x0F) << 12) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 2] & 0x3F));
|
||||
int val = 0;
|
||||
if ((lIndex + 2) < lCount)
|
||||
{
|
||||
val = (int)(((byteMain & 0x0F) << 12) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 2] & 0x3F));
|
||||
}
|
||||
|
||||
pUnicodeString[lIndexUnicode++] = (WCHAR)(val);
|
||||
lIndex += 3;
|
||||
}
|
||||
else if (0x00 == (byteMain & 0x0F))
|
||||
{
|
||||
// 4 byte
|
||||
int val = (int)(((byteMain & 0x07) << 18) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 3] & 0x3F));
|
||||
int val = 0;
|
||||
if ((lIndex + 3) < lCount)
|
||||
{
|
||||
val = (int)(((byteMain & 0x07) << 18) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 3] & 0x3F));
|
||||
}
|
||||
|
||||
pUnicodeString[lIndexUnicode++] = (WCHAR)(val);
|
||||
lIndex += 4;
|
||||
}
|
||||
else if (0x00 == (byteMain & 0x08))
|
||||
{
|
||||
// 4 byte
|
||||
int val = (int)(((byteMain & 0x07) << 18) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 3] & 0x3F));
|
||||
int val = 0;
|
||||
if ((lIndex + 3) < lCount)
|
||||
{
|
||||
val = (int)(((byteMain & 0x07) << 18) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 3] & 0x3F));
|
||||
}
|
||||
|
||||
pUnicodeString[lIndexUnicode++] = (WCHAR)(val);
|
||||
lIndex += 4;
|
||||
}
|
||||
else if (0x00 == (byteMain & 0x04))
|
||||
{
|
||||
// 5 byte
|
||||
int val = (int)(((byteMain & 0x03) << 24) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 18) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 3] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 4] & 0x3F));
|
||||
int val = 0;
|
||||
if ((lIndex + 4) < lCount)
|
||||
{
|
||||
val = (int)(((byteMain & 0x03) << 24) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 18) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 3] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 4] & 0x3F));
|
||||
}
|
||||
|
||||
pUnicodeString[lIndexUnicode++] = (WCHAR)(val);
|
||||
lIndex += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 6 byte
|
||||
int val = (int)(((byteMain & 0x01) << 30) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 24) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 18) |
|
||||
((pBuffer[lIndex + 3] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 4] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 5] & 0x3F));
|
||||
int val = 0;
|
||||
if ((lIndex + 5) < lCount)
|
||||
{
|
||||
val = (int)(((byteMain & 0x01) << 30) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 24) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 18) |
|
||||
((pBuffer[lIndex + 3] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 4] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 5] & 0x3F));
|
||||
}
|
||||
|
||||
pUnicodeString[lIndexUnicode++] = (WCHAR)(val);
|
||||
lIndex += 5;
|
||||
}
|
||||
@ -242,17 +272,26 @@ namespace NSFile
|
||||
else if (0x00 == (byteMain & 0x20))
|
||||
{
|
||||
// 2 byte
|
||||
int val = (int)(((byteMain & 0x1F) << 6) |
|
||||
(pBuffer[lIndex + 1] & 0x3F));
|
||||
int val = 0;
|
||||
if ((lIndex + 1) < lCount)
|
||||
{
|
||||
val = (int)(((byteMain & 0x1F) << 6) |
|
||||
(pBuffer[lIndex + 1] & 0x3F));
|
||||
}
|
||||
|
||||
*pUnicodeString++ = (WCHAR)(val);
|
||||
lIndex += 2;
|
||||
}
|
||||
else if (0x00 == (byteMain & 0x10))
|
||||
{
|
||||
// 3 byte
|
||||
int val = (int)(((byteMain & 0x0F) << 12) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 2] & 0x3F));
|
||||
int val = 0;
|
||||
if ((lIndex + 2) < lCount)
|
||||
{
|
||||
val = (int)(((byteMain & 0x0F) << 12) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 2] & 0x3F));
|
||||
}
|
||||
|
||||
WriteUtf16_WCHAR(val, pUnicodeString);
|
||||
lIndex += 3;
|
||||
@ -260,10 +299,14 @@ namespace NSFile
|
||||
else if (0x00 == (byteMain & 0x0F))
|
||||
{
|
||||
// 4 byte
|
||||
int val = (int)(((byteMain & 0x07) << 18) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 3] & 0x3F));
|
||||
int val = 0;
|
||||
if ((lIndex + 3) < lCount)
|
||||
{
|
||||
val = (int)(((byteMain & 0x07) << 18) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 3] & 0x3F));
|
||||
}
|
||||
|
||||
WriteUtf16_WCHAR(val, pUnicodeString);
|
||||
lIndex += 4;
|
||||
@ -271,10 +314,14 @@ namespace NSFile
|
||||
else if (0x00 == (byteMain & 0x08))
|
||||
{
|
||||
// 4 byte
|
||||
int val = (int)(((byteMain & 0x07) << 18) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 3] & 0x3F));
|
||||
int val = 0;
|
||||
if ((lIndex + 3) < lCount)
|
||||
{
|
||||
val = (int)(((byteMain & 0x07) << 18) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 3] & 0x3F));
|
||||
}
|
||||
|
||||
WriteUtf16_WCHAR(val, pUnicodeString);
|
||||
lIndex += 4;
|
||||
@ -282,11 +329,15 @@ namespace NSFile
|
||||
else if (0x00 == (byteMain & 0x04))
|
||||
{
|
||||
// 5 byte
|
||||
int val = (int)(((byteMain & 0x03) << 24) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 18) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 3] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 4] & 0x3F));
|
||||
int val = 0;
|
||||
if ((lIndex + 4) < lCount)
|
||||
{
|
||||
val = (int)(((byteMain & 0x03) << 24) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 18) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 3] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 4] & 0x3F));
|
||||
}
|
||||
|
||||
WriteUtf16_WCHAR(val, pUnicodeString);
|
||||
lIndex += 5;
|
||||
@ -294,12 +345,16 @@ namespace NSFile
|
||||
else
|
||||
{
|
||||
// 6 byte
|
||||
int val = (int)(((byteMain & 0x01) << 30) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 24) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 18) |
|
||||
((pBuffer[lIndex + 3] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 4] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 5] & 0x3F));
|
||||
int val = 0;
|
||||
if ((lIndex + 5) < lCount)
|
||||
{
|
||||
val = (int)(((byteMain & 0x01) << 30) |
|
||||
((pBuffer[lIndex + 1] & 0x3F) << 24) |
|
||||
((pBuffer[lIndex + 2] & 0x3F) << 18) |
|
||||
((pBuffer[lIndex + 3] & 0x3F) << 12) |
|
||||
((pBuffer[lIndex + 4] & 0x3F) << 6) |
|
||||
(pBuffer[lIndex + 5] & 0x3F));
|
||||
}
|
||||
|
||||
WriteUtf16_WCHAR(val, pUnicodeString);
|
||||
lIndex += 5;
|
||||
|
||||
@ -49,11 +49,11 @@
|
||||
class DLL_EXP CxFile
|
||||
{
|
||||
public:
|
||||
CxFile(void) { };
|
||||
virtual ~CxFile() { };
|
||||
CxFile(void) { }
|
||||
virtual ~CxFile() { }
|
||||
|
||||
virtual bool Close() = 0;
|
||||
virtual size_t Read(void *buffer, size_t size, size_t count) = 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;
|
||||
@ -72,4 +72,27 @@ public:
|
||||
virtual int32_t Scanf(const char *format, void* output) = 0;
|
||||
};
|
||||
|
||||
static void clamp_buffer(void*& buffer, size_t& size, void* limit_start, void* limit_end)
|
||||
{
|
||||
if (NULL == limit_start || NULL == limit_end)
|
||||
return;
|
||||
|
||||
uint8_t* _buffer = (uint8_t*)buffer;
|
||||
uint8_t* _limit_start = (uint8_t*)limit_start;
|
||||
uint8_t* _limit_end = (uint8_t*)limit_end;
|
||||
|
||||
if (_buffer > _limit_end)
|
||||
{
|
||||
buffer = limit_end;
|
||||
size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_buffer < _limit_start)
|
||||
_buffer = _limit_start;
|
||||
|
||||
if ((_buffer + size) > _limit_end)
|
||||
size = (_limit_end - _buffer);
|
||||
}
|
||||
|
||||
#endif //__xfile_h
|
||||
|
||||
@ -133,7 +133,7 @@ bool CxImageBMP::Decode(CxFile * hFile)
|
||||
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);
|
||||
hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBTRIPLE),1,GetDIB(),GetDIBLimit());
|
||||
for (int32_t i=DibNumColors(&head)-1; i>=0; i--){
|
||||
pRgb[i].rgbRed = ((RGBTRIPLE *)pRgb)[i].rgbtRed;
|
||||
pRgb[i].rgbBlue = ((RGBTRIPLE *)pRgb)[i].rgbtBlue;
|
||||
@ -141,7 +141,7 @@ bool CxImageBMP::Decode(CxFile * hFile)
|
||||
pRgb[i].rgbReserved = (uint8_t)0;
|
||||
}
|
||||
} else {
|
||||
hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBQUAD),1);
|
||||
hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBQUAD),1,GetDIB(),GetDIBLimit());
|
||||
//force rgbReserved=0, to avoid problems with some WinXp bitmaps
|
||||
for (uint32_t i=0; i<head.biClrUsed; i++) pRgb[i].rgbReserved=0;
|
||||
}
|
||||
@ -195,7 +195,7 @@ bool CxImageBMP::Decode(CxFile * hFile)
|
||||
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
|
||||
hFile->Read(info.pImage, head.biSizeImage,1,GetDIB(),GetDIBLimit()); // read in the pixels
|
||||
} else cx_throw("unknown compression");
|
||||
break;
|
||||
case 16 :
|
||||
@ -210,7 +210,7 @@ bool CxImageBMP::Decode(CxFile * hFile)
|
||||
// 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);
|
||||
hFile->Read(info.pImage, head.biHeight*((head.biWidth+1)/2)*4,1,GetDIB(),GetDIBLimit());
|
||||
// transform into RGB
|
||||
Bitfield2RGB(info.pImage,bfmask[0],bfmask[1],bfmask[2],16);
|
||||
break;
|
||||
@ -229,7 +229,7 @@ bool CxImageBMP::Decode(CxFile * hFile)
|
||||
}
|
||||
switch (dwCompression) {
|
||||
case BI_RGB :
|
||||
hFile->Read(info.pImage, head.biSizeImage,1); // read in the pixels
|
||||
hFile->Read(info.pImage, head.biSizeImage,1,GetDIB(),GetDIBLimit()); // read in the pixels
|
||||
break;
|
||||
case BI_RLE4 :
|
||||
{
|
||||
@ -355,7 +355,7 @@ bool CxImageBMP::Decode(CxFile * hFile)
|
||||
break;
|
||||
}
|
||||
default :
|
||||
hFile->Read((void *)(iter.GetRow(scanline) + bits), sizeof(uint8_t) * status_byte, 1);
|
||||
hFile->Read((void *)(iter.GetRow(scanline) + bits), sizeof(uint8_t) * status_byte, 1,GetDIB(),GetDIBLimit());
|
||||
// align run length to even number of bytes
|
||||
if ((status_byte & 1) == 1)
|
||||
hFile->Read(&second_byte, sizeof(uint8_t), 1);
|
||||
|
||||
@ -165,7 +165,7 @@ bool CxImageJPG::CxExifInfo::DecodeExif(CxFile * hFile, int32_t nReadMode)
|
||||
// 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){
|
||||
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.
|
||||
@ -187,6 +187,8 @@ bool CxImageJPG::CxExifInfo::DecodeExif(CxFile * hFile, int32_t nReadMode)
|
||||
case M_SOF13:
|
||||
case M_SOF14:
|
||||
case M_SOF15:
|
||||
if (itemlen < 8)
|
||||
return false;
|
||||
process_SOFn(Data, marker);
|
||||
break;
|
||||
default:
|
||||
@ -208,6 +210,9 @@ bool CxImageJPG::CxExifInfo::process_EXIF(uint8_t * CharBuf, uint32_t length)
|
||||
/* 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 */
|
||||
@ -218,6 +223,9 @@ bool CxImageJPG::CxExifInfo::process_EXIF(uint8_t * CharBuf, uint32_t length)
|
||||
}
|
||||
}
|
||||
|
||||
if (length < 8)
|
||||
return false;
|
||||
|
||||
if (memcmp(CharBuf+6,"II",2) == 0){
|
||||
MotorolaOrder = 0;
|
||||
}else{
|
||||
@ -229,6 +237,9 @@ bool CxImageJPG::CxExifInfo::process_EXIF(uint8_t * CharBuf, uint32_t length)
|
||||
}
|
||||
}
|
||||
|
||||
if (length < 14)
|
||||
return false;
|
||||
|
||||
/* Check the next two values for correctness. */
|
||||
if (Get16u(CharBuf+8) != 0x2a){
|
||||
strcpy(m_szLastError,"Invalid Exif start (1)");
|
||||
@ -246,6 +257,7 @@ bool CxImageJPG::CxExifInfo::process_EXIF(uint8_t * CharBuf, uint32_t length)
|
||||
|
||||
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;
|
||||
@ -255,6 +267,18 @@ bool CxImageJPG::CxExifInfo::process_EXIF(uint8_t * CharBuf, uint32_t length)
|
||||
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;
|
||||
@ -692,6 +716,322 @@ bool CxImageJPG::CxExifInfo::ProcessExifDir(uint8_t * DirStart, uint8_t * Offset
|
||||
|
||||
return true;
|
||||
}
|
||||
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;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/*--------------------------------------------------------------------------
|
||||
Evaluate number, be it int32_t, rational, or float from directory.
|
||||
@ -732,6 +1072,58 @@ double CxImageJPG::CxExifInfo::ConvertAnyFormat(void * ValuePtr, int32_t Format)
|
||||
}
|
||||
return Value;
|
||||
}
|
||||
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);
|
||||
if (Den == 0){
|
||||
Value = 0;
|
||||
}else{
|
||||
Value = (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)
|
||||
{
|
||||
@ -747,7 +1139,7 @@ void CxImageJPG::CxExifInfo::process_COM (const uint8_t * Data, int32_t length)
|
||||
for (a=2;a<length;a++){
|
||||
ch = Data[a];
|
||||
|
||||
if (ch == '\r' && Data[a+1] == '\n') continue; // Remove cr followed by lf.
|
||||
if (ch == '\r' && (a < (length - 1) && Data[a+1] == '\n')) continue; // Remove cr followed by lf.
|
||||
|
||||
if (isprint(ch) || ch == '\n' || ch == '\t'){
|
||||
Comment[nch++] = (char)ch;
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
void CxImage::Startup(uint32_t imagetype)
|
||||
{
|
||||
//init pointers
|
||||
pDib = pSelection = pAlpha = NULL;
|
||||
pDib = pDibLimit = pSelection = pAlpha = NULL;
|
||||
ppLayers = ppFrames = NULL;
|
||||
//init structures
|
||||
memset(&head,0,sizeof(BITMAPINFOHEADER));
|
||||
@ -232,6 +232,7 @@ void* CxImage::Create(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32
|
||||
strcpy(info.szLastError,"CxImage::Create can't allocate memory");
|
||||
return NULL;
|
||||
}
|
||||
pDibLimit = (void*)((uint8_t*)pDib + GetSize());
|
||||
|
||||
//clear the palette
|
||||
RGBQUAD* pal=GetPalette();
|
||||
@ -278,9 +279,12 @@ uint8_t* CxImage::GetBits(uint32_t row)
|
||||
/**
|
||||
* \return the size in bytes of the internal pDib object
|
||||
*/
|
||||
int32_t CxImage::GetSize()
|
||||
uint32_t CxImage::GetSize()
|
||||
{
|
||||
return head.biSize + head.biSizeImage + GetPaletteSize();
|
||||
uint64_t size64 = head.biSize + head.biSizeImage + GetPaletteSize();
|
||||
if (size64 > 0xFFFFFFFF)
|
||||
return 0xFFFFFFFF;
|
||||
return (uint32_t)size64;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
@ -324,13 +328,14 @@ bool CxImage::Transfer(CxImage &from, bool bTransferFrames /*=true*/)
|
||||
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.pSelection = from.pAlpha = NULL;
|
||||
from.pDib = from.pDibLimit = from.pSelection = from.pAlpha = NULL;
|
||||
from.ppLayers = NULL;
|
||||
|
||||
if (bTransferFrames){
|
||||
@ -352,6 +357,7 @@ void CxImage::Ghost(const CxImage *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;
|
||||
|
||||
@ -289,10 +289,11 @@ public:
|
||||
//@}
|
||||
|
||||
/** \addtogroup Attributes */ //@{
|
||||
int32_t GetSize();
|
||||
uint32_t GetSize();
|
||||
uint8_t* GetBits(uint32_t row = 0);
|
||||
uint8_t GetColorType();
|
||||
void* GetDIB() const;
|
||||
void* GetDIBLimit() const;
|
||||
uint32_t GetHeight() const;
|
||||
uint32_t GetWidth() const;
|
||||
uint32_t GetEffWidth() const;
|
||||
@ -796,6 +797,8 @@ protected:
|
||||
void bihtoh(BITMAPINFOHEADER* bih);
|
||||
|
||||
void* pDib; //contains the header, the palette, the pixels
|
||||
void* pDibLimit;
|
||||
|
||||
BITMAPINFOHEADER head; //standard header
|
||||
CXIMAGEINFO info; //extended information
|
||||
uint8_t* pSelection; //selected region
|
||||
|
||||
@ -95,9 +95,15 @@ bool CxImageICO::Decode(CxFile *hFile)
|
||||
// read the palette
|
||||
RGBQUAD pal[256];
|
||||
if (bih.biClrUsed)
|
||||
hFile->Read(pal,bih.biClrUsed*sizeof(RGBQUAD), 1);
|
||||
{
|
||||
uint32_t _count = bih.biClrUsed; if (_count > 256) _count = 256;
|
||||
hFile->Read(pal,_count*sizeof(RGBQUAD), 1);
|
||||
}
|
||||
else
|
||||
hFile->Read(pal,head.biClrUsed*sizeof(RGBQUAD), 1);
|
||||
{
|
||||
uint32_t _count = head.biClrUsed; if (_count > 256) _count = 256;
|
||||
hFile->Read(pal,_count*sizeof(RGBQUAD), 1);
|
||||
}
|
||||
|
||||
SetPalette(pal,head.biClrUsed); //palette assign
|
||||
|
||||
|
||||
@ -181,6 +181,10 @@ void* CxImage::GetDIB() const
|
||||
{
|
||||
return pDib;
|
||||
}
|
||||
void* CxImage::GetDIBLimit() const
|
||||
{
|
||||
return pDibLimit;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint32_t CxImage::GetHeight() const
|
||||
{
|
||||
|
||||
@ -101,6 +101,55 @@ typedef struct tag_Section_t{
|
||||
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];
|
||||
@ -118,9 +167,12 @@ protected:
|
||||
int32_t Get32s(void * Long);
|
||||
uint32_t Get32u(void * Long);
|
||||
double ConvertAnyFormat(void * ValuePtr, int32_t Format);
|
||||
double ConvertAnyFormat2(CSafeReader& reader, int32_t Format);
|
||||
void* FindSection(int32_t SectionType);
|
||||
bool ProcessExifDir(uint8_t * DirStart, uint8_t * OffsetBase, unsigned ExifLength,
|
||||
EXIFINFO * const pInfo, uint8_t ** const LastExifRefdP, int32_t NestingLevel=0);
|
||||
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];
|
||||
|
||||
@ -50,6 +50,9 @@ bool CxImagePCX::Decode(CxFile *hFile)
|
||||
info.xDPI = pcxHeader.Hres;
|
||||
info.yDPI = pcxHeader.Vres;
|
||||
|
||||
if (Width <= 0 || Height <= 0)
|
||||
cx_throw("Error: Not a PCX file");
|
||||
|
||||
if (info.nEscape == -1){
|
||||
head.biWidth = Width;
|
||||
head.biHeight= Height;
|
||||
@ -76,7 +79,11 @@ bool CxImagePCX::Decode(CxFile *hFile)
|
||||
|
||||
//Read the image and check if it's ok
|
||||
nbytes = pcxHeader.BytesPerLine * pcxHeader.ColorPlanes * Height;
|
||||
uint32_t pcximage_size = nbytes;
|
||||
lpHead1 = pcximage = (uint8_t*)malloc(nbytes);
|
||||
if (!pcximage)
|
||||
cx_throw("Cancelled");
|
||||
|
||||
while (nbytes > 0){
|
||||
if (hFile == NULL || hFile->Eof()) cx_throw("corrupted PCX");
|
||||
|
||||
@ -119,6 +126,9 @@ bool CxImagePCX::Decode(CxFile *hFile)
|
||||
for (uint32_t idx=0; idx<head.biClrUsed; idx++) SetPaletteColor((uint8_t)idx,ColorMap[idx][0],ColorMap[idx][1],ColorMap[idx][2]);
|
||||
|
||||
lpHead2 = pcxpixels = (uint8_t *)malloc(Width + pcxHeader.BytesPerLine * 8);
|
||||
if (!pcxpixels)
|
||||
cx_throw("Cancelled");
|
||||
|
||||
// Convert the image
|
||||
for (y = 0; y < Height; y++){
|
||||
|
||||
@ -138,7 +148,11 @@ bool CxImagePCX::Decode(CxFile *hFile)
|
||||
} 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]);
|
||||
|
||||
uint32_t alphaIndex = 3*pcxHeader.BytesPerLine + x;
|
||||
|
||||
if (alphaIndex < pcximage_size)
|
||||
AlphaSet(x,y2,pcxplanes[alphaIndex]);
|
||||
}
|
||||
continue;
|
||||
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||
|
||||
@ -301,7 +301,8 @@ bool CxImageTIF::Decode(CxFile * hFile)
|
||||
tilebuf = (uint8_t*)malloc(TIFFTileSize(m_tif));
|
||||
}
|
||||
|
||||
bits = (uint8_t*)malloc(bitspersample==16? bitsize*2 : bitsize); // * VK
|
||||
int32_t bitsize_correct = bitspersample==16? bitsize*2 : bitsize;
|
||||
bits = (uint8_t*)malloc(bitsize_correct); // * VK
|
||||
uint8_t * bits16 = NULL; // + VK
|
||||
int32_t line16 = 0; // + VK
|
||||
|
||||
@ -309,6 +310,7 @@ bool CxImageTIF::Decode(CxFile * hFile)
|
||||
line16 = line;
|
||||
line = CalculateLine(width, 8 * samplesperpixel);
|
||||
bits16 = bits;
|
||||
bitsize_correct = bitsize;
|
||||
bits = (uint8_t*)malloc(bitsize);
|
||||
}
|
||||
|
||||
@ -454,9 +456,18 @@ bool CxImageTIF::Decode(CxFile * hFile)
|
||||
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 (bitsoffset + 2 < bitsize_correct)
|
||||
{
|
||||
l=bits[bitsoffset];
|
||||
a=bits[bitsoffset+1];
|
||||
b=bits[bitsoffset+2];
|
||||
}
|
||||
else
|
||||
{
|
||||
l=0;
|
||||
a=0;
|
||||
b=0;
|
||||
}
|
||||
if (a>127) a-=256;
|
||||
if (b>127) b-=256;
|
||||
// lab to xyz
|
||||
|
||||
@ -59,9 +59,10 @@ public:
|
||||
return (bool)(iErr==0);
|
||||
}
|
||||
//////////////////////////////////////////////////////////
|
||||
virtual size_t Read(void *buffer, size_t size, size_t count)
|
||||
virtual size_t Read(void *buffer, size_t size, size_t count, void* limit_start = NULL, void* limit_end = NULL)
|
||||
{
|
||||
if (!m_fp) return 0;
|
||||
clamp_buffer(buffer, size, limit_start, limit_end);
|
||||
return fread(buffer, size, count, m_fp);
|
||||
}
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
@ -45,7 +45,7 @@ uint8_t* CxMemFile::GetBuffer(bool bDetachBuffer)
|
||||
return m_pBuffer;
|
||||
}
|
||||
//////////////////////////////////////////////////////////
|
||||
size_t CxMemFile::Read(void *buffer, size_t size, size_t count)
|
||||
size_t CxMemFile::Read(void *buffer, size_t size, size_t count, void* limit_start, void* limit_end)
|
||||
{
|
||||
if (buffer==NULL) return 0;
|
||||
|
||||
@ -53,7 +53,7 @@ size_t CxMemFile::Read(void *buffer, size_t size, size_t count)
|
||||
if (m_Position >= (int32_t)m_Size){
|
||||
m_bEOF = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t nCount = (int32_t)(count*size);
|
||||
if (nCount == 0) return 0;
|
||||
|
||||
@ -14,7 +14,7 @@ public:
|
||||
uint8_t* GetBuffer(bool bDetachBuffer = true);
|
||||
|
||||
virtual bool Close();
|
||||
virtual size_t Read(void *buffer, size_t size, size_t count);
|
||||
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();
|
||||
|
||||
@ -2171,7 +2171,12 @@ int jpc_ppxstab_insert(jpc_ppxstab_t *tab, jpc_ppxstabent_t *ent)
|
||||
int inspt;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tab->numents; ++i) {
|
||||
// check on MAX_INT
|
||||
int correct_num_ents = tab->numents;
|
||||
if (correct_num_ents > 0x7FFFFFFE)
|
||||
correct_num_ents = 0x7FFFFFFE;
|
||||
|
||||
for (i = 0; i < correct_num_ents; ++i) {
|
||||
if (tab->ents[i]->ind > ent->ind) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3518,20 +3518,21 @@ void DCR_CLASS dcr_cam_xyz_coeff (DCRAW* p, double cam_xyz[4][3])
|
||||
{
|
||||
double cam_rgb[4][3], inverse[4][3], num;
|
||||
int i, j, k;
|
||||
|
||||
for (i=0; i < p->colors; i++) /* Multiply out XYZ colorspace */
|
||||
int max_colors = p->colors;
|
||||
if (max_colors > 4) max_colors = 4;
|
||||
for (i=0; i < max_colors; i++) /* Multiply out XYZ colorspace */
|
||||
for (j=0; j < 3; j++)
|
||||
for (cam_rgb[i][j] = k=0; k < 3; k++)
|
||||
cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
|
||||
|
||||
for (i=0; i < p->colors; i++) { /* Normalize cam_rgb so that */
|
||||
for (i=0; i < max_colors; i++) { /* Normalize cam_rgb so that */
|
||||
for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
|
||||
num += cam_rgb[i][j];
|
||||
for (j=0; j < 3; j++)
|
||||
cam_rgb[i][j] /= num;
|
||||
p->pre_mul[i] = 1 / (float)num;
|
||||
}
|
||||
dcr_pseudoinverse (cam_rgb, inverse, p->colors);
|
||||
dcr_pseudoinverse (cam_rgb, inverse, max_colors);
|
||||
for (p->raw_color = i=0; i < 3; i++)
|
||||
for (j=0; j < p->colors; j++)
|
||||
p->rgb_cam[i][j] = (float)inverse[j][i];
|
||||
@ -5391,9 +5392,12 @@ void DCR_CLASS dcr_parse_tiff (DCRAW* p, int base)
|
||||
p->tiff_ifd[raw].phint == 1) p->is_raw = 0;
|
||||
if (p->tiff_bps == 8 && p->tiff_samples == 4) p->is_raw = 0;
|
||||
for (i=0; i < (int)p->tiff_nifds; i++)
|
||||
{
|
||||
int sqr_1 = SQR(p->tiff_ifd[i].bps+1); if (sqr_1 == 0) sqr_1 = 1;
|
||||
int sqr_2 = SQR(p->thumb_misc+1); if (sqr_2 == 0) sqr_2 = 1;
|
||||
if (i != raw && p->tiff_ifd[i].samples == max_samp &&
|
||||
p->tiff_ifd[i].width * p->tiff_ifd[i].height / SQR(p->tiff_ifd[i].bps+1) >
|
||||
(int)(p->thumb_width * p->thumb_height / SQR(p->thumb_misc+1))) {
|
||||
p->tiff_ifd[i].width * p->tiff_ifd[i].height / sqr_1 >
|
||||
(int)(p->thumb_width * p->thumb_height / sqr_2)) {
|
||||
p->thumb_width = p->tiff_ifd[i].width;
|
||||
p->thumb_height = p->tiff_ifd[i].height;
|
||||
p->thumb_offset = p->tiff_ifd[i].offset;
|
||||
@ -5401,6 +5405,7 @@ void DCR_CLASS dcr_parse_tiff (DCRAW* p, int base)
|
||||
p->thumb_misc = p->tiff_ifd[i].bps;
|
||||
thm = i;
|
||||
}
|
||||
}
|
||||
if (thm >= 0) {
|
||||
p->thumb_misc |= p->tiff_ifd[thm].samples << 5;
|
||||
switch (p->tiff_ifd[thm].comp) {
|
||||
@ -5845,10 +5850,16 @@ void DCR_CLASS dcr_parse_riff(DCRAW* p)
|
||||
{ "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
|
||||
struct tm t;
|
||||
|
||||
if (dcr_feof(p->obj_))
|
||||
{
|
||||
fprintf (stderr,_("Unexpected end of file\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
p->order = 0x4949;
|
||||
dcr_fread(p->obj_, tag, 4, 1);
|
||||
size = dcr_get4(p);
|
||||
end = dcr_ftell(p->obj_) + size;
|
||||
end = dcr_ftell(p->obj_) + size;
|
||||
if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
|
||||
dcr_get4(p);
|
||||
while (dcr_ftell(p->obj_)+7 < (long)end)
|
||||
|
||||
@ -205,7 +205,7 @@ TIFFReadDirectory(TIFF* tif)
|
||||
&& fix < tif->tif_nfields) {
|
||||
if (fip->field_type == TIFF_ANY) /* wildcard */
|
||||
break;
|
||||
fip = tif->tif_fieldinfo[++fix];
|
||||
++fix; fip = (fix >= tif->tif_nfields) ? 0 : tif->tif_fieldinfo[fix];
|
||||
if (fix >= tif->tif_nfields ||
|
||||
fip->field_tag != dp->tdir_tag) {
|
||||
TIFFWarningExt(tif->tif_clientdata, module,
|
||||
@ -333,7 +333,7 @@ TIFFReadDirectory(TIFF* tif)
|
||||
&& fix < tif->tif_nfields) {
|
||||
if (fip->field_type == TIFF_ANY) /* wildcard */
|
||||
break;
|
||||
fip = tif->tif_fieldinfo[++fix];
|
||||
++fix; fip = (fix >= tif->tif_nfields) ? 0 : tif->tif_fieldinfo[fix];
|
||||
if (fix >= tif->tif_nfields ||
|
||||
fip->field_tag != dp->tdir_tag) {
|
||||
TIFFWarningExt(tif->tif_clientdata, module,
|
||||
@ -887,7 +887,7 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
|
||||
&& fix < tif->tif_nfields) {
|
||||
if (fip->field_type == TIFF_ANY) /* wildcard */
|
||||
break;
|
||||
fip = tif->tif_fieldinfo[++fix];
|
||||
++fix; fip = (fix >= tif->tif_nfields) ? 0 : tif->tif_fieldinfo[fix];
|
||||
if (fix >= tif->tif_nfields ||
|
||||
fip->field_tag != dp->tdir_tag) {
|
||||
TIFFWarningExt(tif->tif_clientdata, module,
|
||||
|
||||
@ -1920,7 +1920,9 @@ OJPEGReadBufferFill(OJPEGState* sp)
|
||||
sp->in_buffer_file_pos=0;
|
||||
else
|
||||
{
|
||||
sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];
|
||||
sp->in_buffer_file_togo=0;
|
||||
if (sp->tif->tif_dir.td_stripbytecount)
|
||||
sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];
|
||||
if (sp->in_buffer_file_togo==0)
|
||||
sp->in_buffer_file_pos=0;
|
||||
else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
|
||||
|
||||
@ -61,9 +61,9 @@ namespace NSFontConverter
|
||||
CFontFileBase(char *sFile, int nLen, bool bFreeFileData)
|
||||
{
|
||||
m_sFileData = m_sFile = (unsigned char *)sFile;
|
||||
m_nLen = nLen;
|
||||
m_bFreeFileData = bFreeFileData;
|
||||
m_nLen = (nLen > 0) ? 0 : (unsigned int)nLen;
|
||||
m_nPos = 0;
|
||||
m_bFreeFileData = bFreeFileData;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
@ -94,11 +94,11 @@ namespace NSFontConverter
|
||||
// S = signed / U = unsigned
|
||||
// 8/16/32/Var = word length, in bytes
|
||||
// BE = big endian
|
||||
int GetS8 (int nPos, bool *pbSuccess)
|
||||
int GetS8 (const unsigned int& nPos, bool *pbSuccess)
|
||||
{
|
||||
//*pbSuccess = true;
|
||||
|
||||
if ( nPos < 0 || nPos >= m_nLen )
|
||||
if ( nPos >= m_nLen )
|
||||
{
|
||||
*pbSuccess = false;
|
||||
return 0;
|
||||
@ -109,10 +109,10 @@ namespace NSFontConverter
|
||||
return nRes;
|
||||
}
|
||||
|
||||
int GetU8 (int nPos, bool *pbSuccess)
|
||||
int GetU8 (const unsigned int& nPos, bool *pbSuccess)
|
||||
{
|
||||
//*pbSuccess = true;
|
||||
if ( nPos < 0 || nPos >= m_nLen )
|
||||
if ( nPos >= m_nLen )
|
||||
{
|
||||
*pbSuccess = false;
|
||||
return 0;
|
||||
@ -120,11 +120,11 @@ namespace NSFontConverter
|
||||
return m_sFile[ nPos ];
|
||||
}
|
||||
|
||||
int GetS16BE (int nPos, bool *pbSuccess)
|
||||
int GetS16BE (const unsigned int& nPos, bool *pbSuccess)
|
||||
{
|
||||
//*pbSuccess = true;
|
||||
|
||||
if ( nPos < 0 || nPos + 1 >= m_nLen )
|
||||
if ( m_nLen < 2 || nPos > (m_nLen - 2) )
|
||||
{
|
||||
*pbSuccess = false;
|
||||
return 0;
|
||||
@ -136,11 +136,11 @@ namespace NSFontConverter
|
||||
return nRes;
|
||||
}
|
||||
|
||||
int GetU16BE (int nPos, bool *pbSuccess)
|
||||
int GetU16BE (const unsigned int& nPos, bool *pbSuccess)
|
||||
{
|
||||
//*pbSuccess = true;
|
||||
|
||||
if ( nPos < 0 || nPos + 1 >= m_nLen)
|
||||
if ( m_nLen < 2 || nPos > (m_nLen - 2) )
|
||||
{
|
||||
*pbSuccess = false;
|
||||
return 0;
|
||||
@ -150,11 +150,11 @@ namespace NSFontConverter
|
||||
return nRes;
|
||||
}
|
||||
|
||||
int GetS32BE (int nPos, bool *pbSuccess)
|
||||
int GetS32BE (const unsigned int& nPos, bool *pbSuccess)
|
||||
{
|
||||
//*pbSuccess = true;
|
||||
|
||||
if ( nPos < 0 || nPos + 3 >= m_nLen )
|
||||
if ( m_nLen < 4 || nPos > (m_nLen - 4) )
|
||||
{
|
||||
*pbSuccess = false;
|
||||
return 0;
|
||||
@ -169,11 +169,11 @@ namespace NSFontConverter
|
||||
return nRes;
|
||||
}
|
||||
|
||||
unsigned int GetU32BE (int nPos, bool *pbSuccess)
|
||||
unsigned int GetU32BE (const unsigned int& nPos, bool *pbSuccess)
|
||||
{
|
||||
//*pbSuccess = true;
|
||||
|
||||
if ( nPos < 0 || nPos + 3 >= m_nLen )
|
||||
if ( m_nLen < 4 || nPos > (m_nLen - 4) )
|
||||
{
|
||||
*pbSuccess = false;
|
||||
return 0;
|
||||
@ -184,11 +184,11 @@ namespace NSFontConverter
|
||||
nRes = (nRes << 8) + m_sFile[nPos + 3];
|
||||
return nRes;
|
||||
}
|
||||
unsigned int GetU32LE (int nPos, bool *pbSuccess)
|
||||
unsigned int GetU32LE (const unsigned int& nPos, bool *pbSuccess)
|
||||
{
|
||||
//*pbSuccess = true;
|
||||
|
||||
if ( nPos < 0 || nPos + 3 >= m_nLen )
|
||||
if ( m_nLen < 4 || nPos > (m_nLen - 4) )
|
||||
{
|
||||
*pbSuccess = false;
|
||||
return 0;
|
||||
@ -199,11 +199,11 @@ namespace NSFontConverter
|
||||
nRes = (nRes << 8) + m_sFile[nPos + 0];
|
||||
return nRes;
|
||||
}
|
||||
unsigned int GetUVarBE(int nPos, int nSize, bool *pbSuccess)
|
||||
unsigned int GetUVarBE(const unsigned int& nPos, const unsigned int& nSize, bool *pbSuccess)
|
||||
{
|
||||
//*pbSuccess = true;
|
||||
|
||||
if ( nPos < 0 || nPos + nSize > m_nLen )
|
||||
if ( m_nLen < nSize || nPos > (m_nLen - nSize) )
|
||||
{
|
||||
*pbSuccess = false;
|
||||
return 0;
|
||||
@ -215,9 +215,9 @@ namespace NSFontConverter
|
||||
return nRes;
|
||||
}
|
||||
|
||||
bool CheckRegion(int nPos, int nSize)
|
||||
bool CheckRegion(const unsigned int& nPos, const unsigned int& nSize)
|
||||
{
|
||||
return (nPos >= 0 && nPos + nSize >= nPos && nPos + nSize <= m_nLen);
|
||||
return (m_nLen >= nSize && nPos <= (m_nLen - nSize));
|
||||
}
|
||||
int ReadS8 (bool *pbSuccess)
|
||||
{
|
||||
@ -239,10 +239,15 @@ namespace NSFontConverter
|
||||
m_nPos += 4;
|
||||
return unResult;
|
||||
}
|
||||
int Read(void* pDestBuffer, int nSize)
|
||||
int Read(void* pDestBuffer, unsigned int nSize)
|
||||
{
|
||||
if ( m_nPos + nSize >= m_nLen )
|
||||
nSize = m_nLen - m_nPos - 1;
|
||||
if (m_nPos >= m_nLen)
|
||||
nSize = 0;
|
||||
else if (nSize > (m_nLen - m_nPos))
|
||||
nSize = m_nLen - m_nPos;
|
||||
|
||||
if (0 == nSize)
|
||||
return nSize;
|
||||
|
||||
memcpy( pDestBuffer, (m_sFile + m_nPos), nSize );
|
||||
m_nPos += nSize;
|
||||
@ -254,10 +259,9 @@ namespace NSFontConverter
|
||||
|
||||
unsigned char *m_sFileData;
|
||||
unsigned char *m_sFile;
|
||||
int m_nLen;
|
||||
unsigned int m_nLen;
|
||||
unsigned int m_nPos;
|
||||
bool m_bFreeFileData;
|
||||
int m_nPos;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -397,6 +397,7 @@ namespace NSFontConverter
|
||||
char nChar = *pTemp;
|
||||
*pTemp = '\0';
|
||||
nCode = atoi( pCur );
|
||||
if (nCode < 0) nCode = 0;
|
||||
*pTemp = nChar;
|
||||
if ( nCode == 8 && *pTemp == '#')
|
||||
{
|
||||
@ -612,7 +613,7 @@ namespace NSFontConverter
|
||||
sToken.clear();
|
||||
sGlyph.clear();
|
||||
|
||||
while ( ( nChar = sEexec[++nIndex] ) != ' ' )
|
||||
while ( nIndex < nEexecLen && ( nChar = sEexec[++nIndex] ) != ' ' )
|
||||
sGlyph.push_back( (wchar_t)nChar );
|
||||
}
|
||||
}
|
||||
@ -632,13 +633,16 @@ namespace NSFontConverter
|
||||
// (пробел, таб, перенос каретки или перенос строки).
|
||||
unsigned char *sCur = (unsigned char*)(*ppEexecBuffer);
|
||||
while( sCur < (unsigned char*)(*ppEexecBuffer) + nLen && ( ' ' == *sCur || '\t' == *sCur || '\r' == *sCur || '\n' == *sCur ) )
|
||||
{
|
||||
++sCur;
|
||||
--nLen;
|
||||
}
|
||||
|
||||
// Теперь нам надо определить в каком формате у нас данные: ASKII или бинарные данные.
|
||||
// Если первые четыре байта являются шестнадцатиричными символами, значит, кодировка ASCII.
|
||||
bool bASCII = false;
|
||||
|
||||
if ( isxdigit( sCur[0] ) && isxdigit( sCur[1] ) && isxdigit( sCur[2] ) && isxdigit( sCur[3] ) )
|
||||
if ( nLen > 3 && isxdigit( sCur[0] ) && isxdigit( sCur[1] ) && isxdigit( sCur[2] ) && isxdigit( sCur[3] ) )
|
||||
bASCII = true;
|
||||
|
||||
if ( bASCII )
|
||||
@ -656,7 +660,7 @@ namespace NSFontConverter
|
||||
int nChar = 0;
|
||||
|
||||
unsigned char *sBuffer = NULL;
|
||||
int nBufLen = 0;
|
||||
unsigned int nBufLen = 0;
|
||||
|
||||
while ( nBlockType != PFB_DONE )
|
||||
{
|
||||
|
||||
@ -259,6 +259,8 @@ namespace NSFontConverter
|
||||
}
|
||||
|
||||
sBuffer[nBufPos++] = unChar;
|
||||
if (nBufPos >= c_nNumLimit)
|
||||
break;
|
||||
}
|
||||
|
||||
if ( 0 != sBuffer[0] && nCount > 0 )
|
||||
|
||||
@ -2888,15 +2888,21 @@ namespace NSFontConverter
|
||||
if (m_oTopDict.nCharsetOffset == 0)
|
||||
{
|
||||
m_pnCharset = c_arrnFontFileType1CISOAdobeCharset;
|
||||
if (m_nGlyphsCount > 229)
|
||||
m_nGlyphsCount = 229;
|
||||
}
|
||||
else if (m_oTopDict.nCharsetOffset == 1)
|
||||
{
|
||||
m_pnCharset = c_arrnFontFileType1CExpertCharset;
|
||||
}
|
||||
if (m_nGlyphsCount > 166)
|
||||
m_nGlyphsCount = 166;
|
||||
}
|
||||
else if (m_oTopDict.nCharsetOffset == 2)
|
||||
{
|
||||
m_pnCharset = c_arrnFontFileType1CExpertSubsetCharset;
|
||||
}
|
||||
if (m_nGlyphsCount > 87)
|
||||
m_nGlyphsCount = 87;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pnCharset = (unsigned short *)MemUtilsMallocArray( m_nGlyphsCount, sizeof(unsigned short));
|
||||
|
||||
Reference in New Issue
Block a user