35 #define YUVoffset4 8 // 2^3
36 #define YUVoffset6 32 // 2^5
37 #define YUVoffset8 128 // 2^7
38 #define YUVoffset16 32768 // 2^15
46 OSError GetLastPGFError() {
47 OSError tmp = _PGF_Error_;
48 _PGF_Error_ = NoError;
62 , m_favorSpeedOverSize(false)
63 , m_useOMPinEncoder(true)
64 , m_useOMPinDecoder(true)
65 , m_skipUserData(false)
67 , m_streamReinitialized(false)
134 m_decoder =
new CDecoder(stream, m_preHeader, m_header, m_postHeader, m_levelLength,
135 m_userDataPos, m_useOMPinDecoder, m_skipUserData);
137 if (m_header.nLevels >
MaxLevel) ReturnWithError(FormatCannotRead);
140 m_currentLevel = m_header.nLevels;
143 m_width[0] = m_header.width;
144 m_height[0] = m_header.height;
159 m_quant = m_header.quality - 1;
161 m_downsample =
false;
162 m_quant = m_header.quality;
167 for (
int i=1; i < m_header.channels; i++) {
168 m_width[i] = (m_width[0] + 1)/2;
169 m_height[i] = (m_height[0] + 1)/2;
172 for (
int i=1; i < m_header.channels; i++) {
173 m_width[i] = m_width[0];
174 m_height[i] = m_height[0];
178 if (m_header.nLevels > 0) {
180 for (
int i=0; i < m_header.channels; i++) {
181 m_wtChannel[i] =
new CWaveletTransform(m_width[i], m_height[i], m_header.nLevels);
185 m_percent = pow(0.25, m_header.nLevels);
191 for (
int c=0; c < m_header.channels; c++) {
192 const UINT32 size = m_width[c]*m_height[c];
193 m_channel[c] =
new(std::nothrow)
DataT[size];
194 if (!m_channel[c]) ReturnWithError(InsufficientMemory);
197 for (UINT32 i=0; i < size; i++) {
199 stream->Read(&count, &m_channel[c][i]);
200 if (count !=
DataTSize) ReturnWithError(MissingData);
309 if (bpc > 31) bpc = 31;
331 if (m_header.nLevels == 0) {
334 for (
int i=0; i < m_header.channels; i++) {
335 ASSERT(m_wtChannel[i]);
336 m_channel[i] = m_wtChannel[i]->GetSubband(0,
LL)->GetBuffer();
340 int currentLevel = m_header.nLevels;
342 if (ROIisSupported()) {
344 SetROI(
PGFRect(0, 0, m_header.width, m_header.height));
347 while (currentLevel > level) {
348 for (
int i=0; i < m_header.channels; i++) {
349 ASSERT(m_wtChannel[i]);
351 if (currentLevel == m_header.nLevels) {
353 m_wtChannel[i]->GetSubband(currentLevel,
LL)->Dequantize(m_quant);
355 m_wtChannel[i]->GetSubband(currentLevel,
HL)->Dequantize(m_quant);
356 m_wtChannel[i]->GetSubband(currentLevel,
LH)->Dequantize(m_quant);
357 m_wtChannel[i]->GetSubband(currentLevel,
HH)->Dequantize(m_quant);
360 OSError err = m_wtChannel[i]->InverseTransform(currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
361 if (err != NoError) ReturnWithError(err);
362 ASSERT(m_channel[i]);
383 ASSERT((level >= 0 && level < m_header.nLevels) || m_header.nLevels == 0);
386 #ifdef __PGFROISUPPORT__
387 if (ROIisSupported() && m_header.nLevels > 0) {
389 PGFRect rect(0, 0, m_header.width, m_header.height);
390 Read(rect, level, cb, data);
395 if (m_header.nLevels == 0) {
400 if ((*cb)(1.0,
true, data)) ReturnWithError(EscapePressed);
404 const int levelDiff = m_currentLevel - level;
405 double percent = (m_progressMode ==
PM_Relative) ? pow(0.25, levelDiff) : m_percent;
408 while (m_currentLevel > level) {
409 for (
int i=0; i < m_header.channels; i++) {
410 ASSERT(m_wtChannel[i]);
412 if (m_currentLevel == m_header.nLevels) {
414 m_wtChannel[i]->GetSubband(m_currentLevel,
LL)->PlaceTile(*m_decoder, m_quant);
416 if (m_preHeader.version &
Version5) {
418 m_wtChannel[i]->GetSubband(m_currentLevel,
HL)->PlaceTile(*m_decoder, m_quant);
419 m_wtChannel[i]->GetSubband(m_currentLevel,
LH)->PlaceTile(*m_decoder, m_quant);
422 m_decoder->DecodeInterleaved(m_wtChannel[i], m_currentLevel, m_quant);
424 m_wtChannel[i]->GetSubband(m_currentLevel,
HH)->PlaceTile(*m_decoder, m_quant);
427 volatile OSError error = NoError;
428 #pragma omp parallel for default(shared)
429 for (
int i=0; i < m_header.channels; i++) {
431 if (error == NoError) {
432 OSError err = m_wtChannel[i]->InverseTransform(m_currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
433 if (err != NoError) error = err;
435 ASSERT(m_channel[i]);
437 if (error != NoError) ReturnWithError(error);
443 if (m_cb) m_cb(m_cbArg);
448 if (m_progressMode ==
PM_Absolute) m_percent = percent;
449 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
455 if (m_currentLevel == 0) Close();
458 #ifdef __PGFROISUPPORT__
469 ASSERT((level >= 0 && level < m_header.nLevels) || m_header.nLevels == 0);
472 if (m_header.nLevels == 0 || !ROIisSupported()) {
473 rect.left = rect.top = 0;
474 rect.right = m_header.width; rect.bottom = m_header.height;
475 Read(level, cb, data);
477 ASSERT(ROIisSupported());
479 ASSERT(rect.left < m_header.width && rect.top < m_header.height);
481 const int levelDiff = m_currentLevel - level;
482 double percent = (m_progressMode ==
PM_Relative) ? pow(0.25, levelDiff) : m_percent;
485 if (levelDiff <= 0) {
487 m_currentLevel = m_header.nLevels;
488 m_decoder->SetStreamPosToData();
492 if (rect.right == 0 || rect.right > m_header.width) rect.right = m_header.width;
493 if (rect.bottom == 0 || rect.bottom > m_header.height) rect.bottom = m_header.height;
498 while (m_currentLevel > level) {
499 for (
int i=0; i < m_header.channels; i++) {
500 ASSERT(m_wtChannel[i]);
503 const UINT32 nTiles = m_wtChannel[i]->GetNofTiles(m_currentLevel);
504 const PGFRect& tileIndices = m_wtChannel[i]->GetTileIndices(m_currentLevel);
507 if (m_currentLevel == m_header.nLevels) {
509 m_decoder->DecodeTileBuffer();
510 m_wtChannel[i]->GetSubband(m_currentLevel,
LL)->PlaceTile(*m_decoder, m_quant);
512 for (UINT32 tileY=0; tileY < nTiles; tileY++) {
513 for (UINT32 tileX=0; tileX < nTiles; tileX++) {
515 if (tileIndices.
IsInside(tileX, tileY)) {
516 m_decoder->DecodeTileBuffer();
517 m_wtChannel[i]->GetSubband(m_currentLevel,
HL)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
518 m_wtChannel[i]->GetSubband(m_currentLevel,
LH)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
519 m_wtChannel[i]->GetSubband(m_currentLevel,
HH)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
522 m_decoder->SkipTileBuffer();
528 volatile OSError error = NoError;
529 #pragma omp parallel for default(shared)
530 for (
int i=0; i < m_header.channels; i++) {
532 if (error == NoError) {
533 OSError err = m_wtChannel[i]->InverseTransform(m_currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
534 if (err != NoError) error = err;
536 ASSERT(m_channel[i]);
538 if (error != NoError) ReturnWithError(error);
544 if (m_cb) m_cb(m_cbArg);
549 if (m_progressMode ==
PM_Absolute) m_percent = percent;
550 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
556 if (m_currentLevel == 0) Close();
577 else rect.
left -= dx;
578 if (rect.
top < dy) rect.
top = 0;
601 #endif // __PGFROISUPPORT__
621 ASSERT(targetLen > 0);
625 m_decoder->SetStreamPosToStart();
628 UINT32 len =
__min(targetLen, GetEncodedHeaderLength());
631 len = m_decoder->ReadEncodedData(target, len);
632 ASSERT(len >= 0 && len <= targetLen);
654 ASSERT(level >= 0 && level < m_header.nLevels);
656 ASSERT(targetLen > 0);
660 m_decoder->SetStreamPosToData();
665 for (
int i=m_header.nLevels - 1; i > level; i--) {
666 offset += m_levelLength[m_header.nLevels - 1 - i];
668 m_decoder->Skip(offset);
671 UINT32 len =
__min(targetLen, GetEncodedLevelLength(level));
674 len = m_decoder->ReadEncodedData(target, len);
675 ASSERT(len >= 0 && len <= targetLen);
688 while(maxValue > 0) {
693 if (pot > bpc) pot = bpc;
694 if (pot > 31) pot = 31;
739 ASSERT(m_channel[0]);
742 RgbToYuv(pitch, buff, bpp, channelMap, cb, data);
746 for (
int i=1; i < m_header.channels; i++) {
760 const int oddW = w%2;
767 for (
int i=0; i < h2; i++) {
768 for (
int j=0; j < w2; j++) {
770 buff[sampledPos] = (buff[loPos] + buff[loPos + 1] + buff[hiPos] + buff[hiPos + 1]) >> 2;
771 loPos += 2; hiPos += 2;
775 buff[sampledPos] = (buff[loPos] + buff[hiPos]) >> 1;
779 loPos += w; hiPos += w;
782 for (
int j=0; j < w2; j++) {
783 buff[sampledPos] = (buff[loPos] + buff[loPos+1]) >> 1;
784 loPos += 2; hiPos += 2;
788 buff[sampledPos] = buff[loPos];
806 while (s > maxThumbnailWidth) {
843 #ifdef __PGFROISUPPORT__
844 m_streamReinitialized =
false;
848 memcpy(m_preHeader.magic,
Magic, 3);
870 m_quant = m_header.quality - 1;
872 m_downsample =
false;
873 m_quant = m_header.quality;
881 if (userDataLength && userData) {
882 m_postHeader.userData =
new(std::nothrow) UINT8[userDataLength];
883 if (!m_postHeader.userData) ReturnWithError(InsufficientMemory);
884 m_postHeader.userDataLen = userDataLength;
885 memcpy(m_postHeader.userData, userData, userDataLength);
887 m_preHeader.hSize += userDataLength;
891 for (
int i=0; i < m_header.channels; i++) {
893 m_width[i] = m_header.width;
894 m_height[i] = m_header.height;
897 ASSERT(!m_channel[i]);
898 m_channel[i] =
new(std::nothrow)
DataT[m_header.width*m_header.height];
902 delete[] m_channel[i]; m_channel[i] = 0;
905 ReturnWithError(InsufficientMemory);
918 ASSERT(m_header.nLevels <=
MaxLevel);
921 if (m_header.nLevels > 0) {
922 volatile OSError error = NoError;
924 #pragma omp parallel for default(shared)
925 for (
int i=0; i < m_header.channels; i++) {
927 if (error == NoError) {
928 if (m_wtChannel[i]) {
929 ASSERT(m_channel[i]);
931 int size = m_height[i]*m_width[i];
932 temp =
new(std::nothrow)
DataT[size];
934 memcpy(temp, m_channel[i], size*
DataTSize);
935 delete m_wtChannel[i];
937 error = InsufficientMemory;
940 if (error == NoError) {
941 if (temp) m_channel[i] = temp;
942 m_wtChannel[i] =
new CWaveletTransform(m_width[i], m_height[i], m_header.nLevels, m_channel[i]);
943 #ifdef __PGFROISUPPORT__
944 m_wtChannel[i]->SetROI(
PGFRect(0, 0, m_header.width, m_header.height));
948 for (
int l=0; error == NoError && l < m_header.nLevels; l++) {
949 OSError err = m_wtChannel[i]->ForwardTransform(l, m_quant);
950 if (err != NoError) error = err;
955 if (error != NoError) ReturnWithError(error);
957 m_currentLevel = m_header.nLevels;
960 m_encoder =
new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_userDataPos, m_useOMPinEncoder);
961 if (m_favorSpeedOverSize) m_encoder->FavorSpeedOverSize();
963 #ifdef __PGFROISUPPORT__
964 if (ROIisSupported()) {
974 m_encoder =
new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_userDataPos, m_useOMPinEncoder);
977 INT64 nBytes = m_encoder->ComputeHeaderLength();
978 return (nBytes > 0) ? (UINT32)nBytes : 0;
994 #ifdef __PGFROISUPPORT__
1001 const UINT32 lastTile = nTiles - 1;
1005 ASSERT(nTiles == 1);
1009 for (UINT32 tileY=0; tileY < nTiles; tileY++) {
1010 for (UINT32 tileX=0; tileX < nTiles; tileX++) {
1014 if (i == lastChannel && tileY == lastTile && tileX == lastTile) {
1071 ASSERT(m_preHeader.hSize);
1073 int levels = m_header.nLevels;
1074 double percent = pow(0.25, levels);
1077 UINT32 nWrittenBytes = UpdatePostHeaderSize();
1081 for (
int c=0; c < m_header.channels; c++) {
1082 const UINT32 size = m_width[c]*m_height[c];
1085 for (UINT32 i=0; i < size; i++) {
1087 stream->Write(&count, &m_channel[c][i]);
1093 if ((*cb)(1,
true, data)) ReturnWithError(EscapePressed);
1102 for (m_currentLevel = levels; m_currentLevel > 0; ) {
1108 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1117 nWrittenBytes = m_encoder->UpdateLevelLength();
1120 delete m_encoder; m_encoder = NULL;
1124 return nWrittenBytes;
1142 ASSERT(m_preHeader.hSize);
1145 UINT32 nBytes = WriteHeader(stream);
1148 nBytes += WriteImage(stream, cb, data);
1151 if (nWrittenBytes) *nWrittenBytes += nBytes;
1154 #ifdef __PGFROISUPPORT__
1170 ASSERT(m_header.nLevels > 0);
1171 ASSERT(0 <= level && level < m_header.nLevels);
1173 ASSERT(ROIisSupported());
1175 const int levelDiff = m_currentLevel - level;
1176 double percent = (m_progressMode ==
PM_Relative) ? pow(0.25, levelDiff) : m_percent;
1177 UINT32 nWrittenBytes = 0;
1179 if (m_currentLevel == m_header.nLevels) {
1181 nWrittenBytes = UpdatePostHeaderSize();
1184 if (m_encoder->ComputeBufferLength()) {
1185 m_streamReinitialized =
true;
1190 while (m_currentLevel > level) {
1193 if (m_levelLength) {
1194 nWrittenBytes += m_levelLength[m_header.nLevels - m_currentLevel - 1];
1200 if (m_progressMode ==
PM_Absolute) m_percent = percent;
1201 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1206 if (m_currentLevel == 0) {
1207 if (!m_streamReinitialized) {
1209 m_encoder->UpdateLevelLength();
1212 delete m_encoder; m_encoder = NULL;
1215 return nWrittenBytes;
1217 #endif // __PGFROISUPPORT__
1270 if (iFirstColor + nColors >
ColorTableLen) ReturnWithError(ColorTableError);
1272 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1273 prgbColors[j] = m_postHeader.clut[i];
1284 if (iFirstColor + nColors >
ColorTableLen) ReturnWithError(ColorTableError);
1286 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1287 m_postHeader.clut[i] = prgbColors[j];
1308 void CPGFImage::RgbToYuv(
int pitch, UINT8* buff, BYTE bpp,
int channelMap[], CallbackPtr cb,
void *data ) THROW_ {
1310 int yPos = 0, cnt = 0;
1312 const double dP = 1.0/m_header.height;
1313 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
1315 if (channelMap == NULL) channelMap = defMap;
1317 switch(m_header.mode) {
1320 ASSERT(m_header.channels == 1);
1321 ASSERT(m_header.bpp == 1);
1324 const UINT32 w = m_header.width;
1325 const UINT32 w2 = (m_header.width + 7)/8;
1326 DataT* y = m_channel[0]; ASSERT(y);
1328 for (UINT32 h=0; h < m_header.height; h++) {
1330 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1334 for (UINT32 j=0; j < w2; j++) {
1337 for (UINT32 j=w2; j < w; j++) {
1360 ASSERT(m_header.channels >= 1);
1361 ASSERT(m_header.bpp == m_header.channels*8);
1363 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1365 for (UINT32 h=0; h < m_header.height; h++) {
1367 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1372 for (UINT32 w=0; w < m_header.width; w++) {
1373 for (
int c=0; c < m_header.channels; c++) {
1374 m_channel[c][yPos] = buff[cnt + channelMap[c]] -
YUVoffset8;
1386 ASSERT(m_header.channels >= 1);
1387 ASSERT(m_header.bpp == m_header.channels*16);
1388 ASSERT(bpp%16 == 0);
1390 UINT16 *buff16 = (UINT16 *)buff;
1391 const int pitch16 = pitch/2;
1392 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1393 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1394 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1396 for (UINT32 h=0; h < m_header.height; h++) {
1398 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1403 for (UINT32 w=0; w < m_header.width; w++) {
1404 for (
int c=0; c < m_header.channels; c++) {
1405 m_channel[c][yPos] = (buff16[cnt + channelMap[c]] >> shift) - yuvOffset16;
1416 ASSERT(m_header.channels == 3);
1417 ASSERT(m_header.bpp == m_header.channels*8);
1420 DataT* y = m_channel[0]; ASSERT(y);
1421 DataT* u = m_channel[1]; ASSERT(u);
1422 DataT* v = m_channel[2]; ASSERT(v);
1423 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1426 for (UINT32 h=0; h < m_header.height; h++) {
1428 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1433 for (UINT32 w=0; w < m_header.width; w++) {
1434 b = buff[cnt + channelMap[0]];
1435 g = buff[cnt + channelMap[1]];
1436 r = buff[cnt + channelMap[2]];
1438 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset8;
1450 ASSERT(m_header.channels == 3);
1451 ASSERT(m_header.bpp == m_header.channels*16);
1452 ASSERT(bpp%16 == 0);
1454 UINT16 *buff16 = (UINT16 *)buff;
1455 const int pitch16 = pitch/2;
1456 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1457 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1458 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1460 DataT* y = m_channel[0]; ASSERT(y);
1461 DataT* u = m_channel[1]; ASSERT(u);
1462 DataT* v = m_channel[2]; ASSERT(v);
1465 for (UINT32 h=0; h < m_header.height; h++) {
1467 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1472 for (UINT32 w=0; w < m_header.width; w++) {
1473 b = buff16[cnt + channelMap[0]] >> shift;
1474 g = buff16[cnt + channelMap[1]] >> shift;
1475 r = buff16[cnt + channelMap[2]] >> shift;
1477 y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1490 ASSERT(m_header.channels == 4);
1491 ASSERT(m_header.bpp == m_header.channels*8);
1493 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1495 DataT* y = m_channel[0]; ASSERT(y);
1496 DataT* u = m_channel[1]; ASSERT(u);
1497 DataT* v = m_channel[2]; ASSERT(v);
1498 DataT* a = m_channel[3]; ASSERT(a);
1501 for (UINT32 h=0; h < m_header.height; h++) {
1503 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1508 for (UINT32 w=0; w < m_header.width; w++) {
1509 b = buff[cnt + channelMap[0]];
1510 g = buff[cnt + channelMap[1]];
1511 r = buff[cnt + channelMap[2]];
1513 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset8;
1516 a[yPos++] = buff[cnt + channelMap[3]] -
YUVoffset8;
1525 ASSERT(m_header.channels == 4);
1526 ASSERT(m_header.bpp == m_header.channels*16);
1527 ASSERT(bpp%16 == 0);
1529 UINT16 *buff16 = (UINT16 *)buff;
1530 const int pitch16 = pitch/2;
1531 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1532 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1533 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1535 DataT* y = m_channel[0]; ASSERT(y);
1536 DataT* u = m_channel[1]; ASSERT(u);
1537 DataT* v = m_channel[2]; ASSERT(v);
1538 DataT* a = m_channel[3]; ASSERT(a);
1541 for (UINT32 h=0; h < m_header.height; h++) {
1543 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1548 for (UINT32 w=0; w < m_header.width; w++) {
1549 b = buff16[cnt + channelMap[0]] >> shift;
1550 g = buff16[cnt + channelMap[1]] >> shift;
1551 r = buff16[cnt + channelMap[2]] >> shift;
1553 y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1556 a[yPos++] = (buff16[cnt + channelMap[3]] >> shift) - yuvOffset16;
1563 #ifdef __PGF32SUPPORT__
1566 ASSERT(m_header.channels == 1);
1567 ASSERT(m_header.bpp == 32);
1571 DataT* y = m_channel[0]; ASSERT(y);
1573 UINT32 *buff32 = (UINT32 *)buff;
1574 const int pitch32 = pitch/4;
1575 const int shift = 31 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1576 const DataT yuvOffset31 = 1 << (UsedBitsPerChannel() - 1);
1578 for (UINT32 h=0; h < m_header.height; h++) {
1580 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1584 for (UINT32 w=0; w < m_header.width; w++) {
1585 y[yPos++] = (buff32[w] >> shift) - yuvOffset31;
1594 ASSERT(m_header.channels == 3);
1595 ASSERT(m_header.bpp == m_header.channels*4);
1596 ASSERT(bpp == m_header.channels*4);
1598 DataT* y = m_channel[0]; ASSERT(y);
1599 DataT* u = m_channel[1]; ASSERT(u);
1600 DataT* v = m_channel[2]; ASSERT(v);
1602 UINT8 rgb = 0, b, g, r;
1604 for (UINT32 h=0; h < m_header.height; h++) {
1606 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1611 for (UINT32 w=0; w < m_header.width; w++) {
1616 g = (rgb & 0xF0) >> 4;
1622 b = (rgb & 0xF0) >> 4;
1626 r = (rgb & 0xF0) >> 4;
1631 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset4;
1642 ASSERT(m_header.channels == 3);
1643 ASSERT(m_header.bpp == 16);
1646 DataT* y = m_channel[0]; ASSERT(y);
1647 DataT* u = m_channel[1]; ASSERT(u);
1648 DataT* v = m_channel[2]; ASSERT(v);
1650 UINT16 *buff16 = (UINT16 *)buff;
1651 UINT16 rgb, b, g, r;
1652 const int pitch16 = pitch/2;
1654 for (UINT32 h=0; h < m_header.height; h++) {
1656 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1659 for (UINT32 w=0; w < m_header.width; w++) {
1661 r = (rgb & 0xF800) >> 10;
1662 g = (rgb & 0x07E0) >> 5;
1663 b = (rgb & 0x001F) << 1;
1665 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset6;
1697 void CPGFImage::GetBitmap(
int pitch, UINT8* buff, BYTE bpp,
int channelMap[] , CallbackPtr cb ,
void *data )
const THROW_ {
1699 UINT32 w = m_width[0];
1700 UINT32 h = m_height[0];
1701 UINT8* targetBuff = 0;
1702 UINT8* buffStart = 0;
1703 int targetPitch = 0;
1705 #ifdef __PGFROISUPPORT__
1706 const PGFRect& roi = (ROIisSupported()) ? m_wtChannel[0]->GetROI(m_currentLevel) :
PGFRect(0, 0, w, h);
1707 const PGFRect levelRoi(LevelWidth(m_roi.left, m_currentLevel), LevelHeight(m_roi.top, m_currentLevel), LevelWidth(m_roi.Width(), m_currentLevel), LevelHeight(m_roi.Height(), m_currentLevel));
1712 if (ROIisSupported() && (levelRoi.
Width() < w || levelRoi.
Height() < h)) {
1715 targetPitch = pitch;
1720 buff = buffStart =
new(std::nothrow) UINT8[pitch*h];
1721 if (!buff) ReturnWithError(InsufficientMemory);
1725 const bool wOdd = (1 == w%2);
1727 const double dP = 1.0/h;
1728 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
1729 if (channelMap == NULL) channelMap = defMap;
1730 int sampledPos = 0, yPos = 0;
1735 switch(m_header.mode) {
1738 ASSERT(m_header.channels == 1);
1739 ASSERT(m_header.bpp == 1);
1742 const UINT32 w2 = (w + 7)/8;
1743 DataT* y = m_channel[0]; ASSERT(y);
1745 for (i=0; i < h; i++) {
1747 for (j=0; j < w2; j++) {
1767 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1777 ASSERT(m_header.channels >= 1);
1778 ASSERT(m_header.bpp == m_header.channels*8);
1781 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
1783 for (i=0; i < h; i++) {
1785 for (j=0; j < w; j++) {
1786 for (
int c=0; c < m_header.channels; c++) {
1787 buff[cnt + channelMap[c]] = Clamp8(m_channel[c][yPos] +
YUVoffset8);
1796 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1803 ASSERT(m_header.channels >= 1);
1804 ASSERT(m_header.bpp == m_header.channels*16);
1806 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1810 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1811 UINT16 *buff16 = (UINT16 *)buff;
1812 int pitch16 = pitch/2;
1813 channels = bpp/16; ASSERT(channels >= m_header.channels);
1815 for (i=0; i < h; i++) {
1817 for (j=0; j < w; j++) {
1818 for (
int c=0; c < m_header.channels; c++) {
1819 buff16[cnt + channelMap[c]] = Clamp16((m_channel[c][yPos] + yuvOffset16) << shift);
1828 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1833 const int shift =
__max(0, UsedBitsPerChannel() - 8);
1834 channels = bpp/8; ASSERT(channels >= m_header.channels);
1836 for (i=0; i < h; i++) {
1838 for (j=0; j < w; j++) {
1839 for (
int c=0; c < m_header.channels; c++) {
1840 buff[cnt + channelMap[c]] = Clamp8((m_channel[c][yPos] + yuvOffset16) >> shift);
1849 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1857 ASSERT(m_header.channels == 3);
1858 ASSERT(m_header.bpp == m_header.channels*8);
1860 ASSERT(bpp >= m_header.bpp);
1862 DataT* y = m_channel[0]; ASSERT(y);
1863 DataT* u = m_channel[1]; ASSERT(u);
1864 DataT* v = m_channel[2]; ASSERT(v);
1865 UINT8 *buffg = &buff[channelMap[1]],
1866 *buffr = &buff[channelMap[2]],
1867 *buffb = &buff[channelMap[0]];
1869 int cnt, channels = bpp/8;
1871 for (i=0; i < h; i++) {
1872 if (i%2) sampledPos -= (w + 1)/2;
1874 for (j=0; j < w; j++) {
1876 uAvg = u[sampledPos];
1877 vAvg = v[sampledPos];
1879 buffg[cnt] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
1880 buffr[cnt] = Clamp8(uAvg + g);
1881 buffb[cnt] = Clamp8(vAvg + g);
1884 if (j%2) sampledPos++;
1889 if (wOdd) sampledPos++;
1892 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1896 for (i=0; i < h; i++) {
1898 for (j = 0; j < w; j++) {
1902 buffg[cnt] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
1903 buffr[cnt] = Clamp8(uAvg + g);
1904 buffb[cnt] = Clamp8(vAvg + g);
1914 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1922 ASSERT(m_header.channels == 3);
1923 ASSERT(m_header.bpp == 48);
1925 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1927 DataT* y = m_channel[0]; ASSERT(y);
1928 DataT* u = m_channel[1]; ASSERT(u);
1929 DataT* v = m_channel[2]; ASSERT(v);
1933 if (bpp >= 48 && bpp%16 == 0) {
1934 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1935 UINT16 *buff16 = (UINT16 *)buff;
1936 int pitch16 = pitch/2;
1937 channels = bpp/16; ASSERT(channels >= m_header.channels);
1939 for (i=0; i < h; i++) {
1940 if (i%2) sampledPos -= (w + 1)/2;
1942 for (j=0; j < w; j++) {
1945 uAvg = u[sampledPos];
1946 vAvg = v[sampledPos];
1952 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
1953 buff16[cnt + channelMap[1]] = Clamp16(g << shift);
1954 buff16[cnt + channelMap[2]] = Clamp16((uAvg + g) << shift);
1955 buff16[cnt + channelMap[0]] = Clamp16((vAvg + g) << shift);
1958 if (j%2) sampledPos++;
1961 if (wOdd) sampledPos++;
1965 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1970 const int shift =
__max(0, UsedBitsPerChannel() - 8);
1971 channels = bpp/8; ASSERT(channels >= m_header.channels);
1973 for (i=0; i < h; i++) {
1974 if (i%2) sampledPos -= (w + 1)/2;
1976 for (j=0; j < w; j++) {
1979 uAvg = u[sampledPos];
1980 vAvg = v[sampledPos];
1986 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
1987 buff[cnt + channelMap[1]] = Clamp8(g >> shift);
1988 buff[cnt + channelMap[2]] = Clamp8((uAvg + g) >> shift);
1989 buff[cnt + channelMap[0]] = Clamp8((vAvg + g) >> shift);
1992 if (j%2) sampledPos++;
1995 if (wOdd) sampledPos++;
1999 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2007 ASSERT(m_header.channels == 3);
2008 ASSERT(m_header.bpp == m_header.channels*8);
2011 DataT* l = m_channel[0]; ASSERT(l);
2012 DataT* a = m_channel[1]; ASSERT(a);
2013 DataT* b = m_channel[2]; ASSERT(b);
2014 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
2016 for (i=0; i < h; i++) {
2017 if (i%2) sampledPos -= (w + 1)/2;
2019 for (j=0; j < w; j++) {
2022 uAvg = a[sampledPos];
2023 vAvg = b[sampledPos];
2028 buff[cnt + channelMap[0]] = Clamp8(l[yPos] +
YUVoffset8);
2029 buff[cnt + channelMap[1]] = Clamp8(uAvg +
YUVoffset8);
2030 buff[cnt + channelMap[2]] = Clamp8(vAvg +
YUVoffset8);
2033 if (j%2) sampledPos++;
2036 if (wOdd) sampledPos++;
2040 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2047 ASSERT(m_header.channels == 3);
2048 ASSERT(m_header.bpp == m_header.channels*16);
2050 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2052 DataT* l = m_channel[0]; ASSERT(l);
2053 DataT* a = m_channel[1]; ASSERT(a);
2054 DataT* b = m_channel[2]; ASSERT(b);
2058 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2059 UINT16 *buff16 = (UINT16 *)buff;
2060 int pitch16 = pitch/2;
2061 channels = bpp/16; ASSERT(channels >= m_header.channels);
2063 for (i=0; i < h; i++) {
2064 if (i%2) sampledPos -= (w + 1)/2;
2066 for (j=0; j < w; j++) {
2069 uAvg = a[sampledPos];
2070 vAvg = b[sampledPos];
2075 buff16[cnt + channelMap[0]] = Clamp16((l[yPos] + yuvOffset16) << shift);
2076 buff16[cnt + channelMap[1]] = Clamp16((uAvg + yuvOffset16) << shift);
2077 buff16[cnt + channelMap[2]] = Clamp16((vAvg + yuvOffset16) << shift);
2080 if (j%2) sampledPos++;
2083 if (wOdd) sampledPos++;
2087 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2092 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2093 channels = bpp/8; ASSERT(channels >= m_header.channels);
2095 for (i=0; i < h; i++) {
2096 if (i%2) sampledPos -= (w + 1)/2;
2098 for (j=0; j < w; j++) {
2101 uAvg = a[sampledPos];
2102 vAvg = b[sampledPos];
2107 buff[cnt + channelMap[0]] = Clamp8((l[yPos] + yuvOffset16) >> shift);
2108 buff[cnt + channelMap[1]] = Clamp8((uAvg + yuvOffset16) >> shift);
2109 buff[cnt + channelMap[2]] = Clamp8((vAvg + yuvOffset16) >> shift);
2112 if (j%2) sampledPos++;
2115 if (wOdd) sampledPos++;
2119 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2128 ASSERT(m_header.channels == 4);
2129 ASSERT(m_header.bpp == m_header.channels*8);
2132 DataT* y = m_channel[0]; ASSERT(y);
2133 DataT* u = m_channel[1]; ASSERT(u);
2134 DataT* v = m_channel[2]; ASSERT(v);
2135 DataT* a = m_channel[3]; ASSERT(a);
2137 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
2139 for (i=0; i < h; i++) {
2140 if (i%2) sampledPos -= (w + 1)/2;
2142 for (j=0; j < w; j++) {
2145 uAvg = u[sampledPos];
2146 vAvg = v[sampledPos];
2154 buff[cnt + channelMap[1]] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
2155 buff[cnt + channelMap[2]] = Clamp8(uAvg + g);
2156 buff[cnt + channelMap[0]] = Clamp8(vAvg + g);
2157 buff[cnt + channelMap[3]] = aAvg;
2160 if (j%2) sampledPos++;
2163 if (wOdd) sampledPos++;
2167 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2174 ASSERT(m_header.channels == 4);
2175 ASSERT(m_header.bpp == 64);
2177 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2179 DataT* y = m_channel[0]; ASSERT(y);
2180 DataT* u = m_channel[1]; ASSERT(u);
2181 DataT* v = m_channel[2]; ASSERT(v);
2182 DataT* a = m_channel[3]; ASSERT(a);
2187 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2188 UINT16 *buff16 = (UINT16 *)buff;
2189 int pitch16 = pitch/2;
2190 channels = bpp/16; ASSERT(channels >= m_header.channels);
2192 for (i=0; i < h; i++) {
2193 if (i%2) sampledPos -= (w + 1)/2;
2195 for (j=0; j < w; j++) {
2198 uAvg = u[sampledPos];
2199 vAvg = v[sampledPos];
2200 aAvg = a[sampledPos] + yuvOffset16;
2204 aAvg = a[yPos] + yuvOffset16;
2207 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
2208 buff16[cnt + channelMap[1]] = Clamp16(g << shift);
2209 buff16[cnt + channelMap[2]] = Clamp16((uAvg + g) << shift);
2210 buff16[cnt + channelMap[0]] = Clamp16((vAvg + g) << shift);
2211 buff16[cnt + channelMap[3]] = Clamp16(aAvg << shift);
2214 if (j%2) sampledPos++;
2217 if (wOdd) sampledPos++;
2221 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2226 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2227 channels = bpp/8; ASSERT(channels >= m_header.channels);
2229 for (i=0; i < h; i++) {
2230 if (i%2) sampledPos -= (w + 1)/2;
2232 for (j=0; j < w; j++) {
2235 uAvg = u[sampledPos];
2236 vAvg = v[sampledPos];
2237 aAvg = a[sampledPos] + yuvOffset16;
2241 aAvg = a[yPos] + yuvOffset16;
2244 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
2245 buff[cnt + channelMap[1]] = Clamp8(g >> shift);
2246 buff[cnt + channelMap[2]] = Clamp8((uAvg + g) >> shift);
2247 buff[cnt + channelMap[0]] = Clamp8((vAvg + g) >> shift);
2248 buff[cnt + channelMap[3]] = Clamp8(aAvg >> shift);
2251 if (j%2) sampledPos++;
2254 if (wOdd) sampledPos++;
2258 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2264 #ifdef __PGF32SUPPORT__
2267 ASSERT(m_header.channels == 1);
2268 ASSERT(m_header.bpp == 32);
2270 const int yuvOffset31 = 1 << (UsedBitsPerChannel() - 1);
2272 DataT* y = m_channel[0]; ASSERT(y);
2275 const int shift = 31 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2276 UINT32 *buff32 = (UINT32 *)buff;
2277 int pitch32 = pitch/4;
2279 for (i=0; i < h; i++) {
2280 for (j=0; j < w; j++) {
2281 buff32[j] = Clamp31((y[yPos++] + yuvOffset31) << shift);
2287 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2290 }
else if (bpp == 16) {
2291 const int usedBits = UsedBitsPerChannel();
2292 UINT16 *buff16 = (UINT16 *)buff;
2293 int pitch16 = pitch/2;
2295 if (usedBits < 16) {
2296 const int shift = 16 - usedBits;
2297 for (i=0; i < h; i++) {
2298 for (j=0; j < w; j++) {
2299 buff16[j] = Clamp16((y[yPos++] + yuvOffset31) << shift);
2305 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2309 const int shift =
__max(0, usedBits - 16);
2310 for (i=0; i < h; i++) {
2311 for (j=0; j < w; j++) {
2312 buff16[j] = Clamp16((y[yPos++] + yuvOffset31) >> shift);
2318 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2324 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2326 for (i=0; i < h; i++) {
2327 for (j=0; j < w; j++) {
2328 buff[j] = Clamp8((y[yPos++] + yuvOffset31) >> shift);
2334 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2343 ASSERT(m_header.channels == 3);
2344 ASSERT(m_header.bpp == m_header.channels*4);
2345 ASSERT(bpp == m_header.channels*4);
2346 ASSERT(!m_downsample);
2348 DataT* y = m_channel[0]; ASSERT(y);
2349 DataT* u = m_channel[1]; ASSERT(u);
2350 DataT* v = m_channel[2]; ASSERT(v);
2354 for (i=0; i < h; i++) {
2356 for (j=0; j < w; j++) {
2360 yval = Clamp4(y[yPos++] +
YUVoffset4 - ((uAvg + vAvg ) >> 2));
2362 buff[cnt] = UINT8(Clamp4(vAvg + yval) | (yval << 4));
2364 buff[cnt] = Clamp4(uAvg + yval);
2366 buff[cnt] |= Clamp4(vAvg + yval) << 4;
2368 buff[cnt] = UINT8(yval | (Clamp4(uAvg + yval) << 4));
2376 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2383 ASSERT(m_header.channels == 3);
2384 ASSERT(m_header.bpp == 16);
2386 ASSERT(!m_downsample);
2388 DataT* y = m_channel[0]; ASSERT(y);
2389 DataT* u = m_channel[1]; ASSERT(u);
2390 DataT* v = m_channel[2]; ASSERT(v);
2392 UINT16 *buff16 = (UINT16 *)buff;
2393 int pitch16 = pitch/2;
2395 for (i=0; i < h; i++) {
2396 for (j=0; j < w; j++) {
2400 yval = Clamp6(y[yPos++] +
YUVoffset6 - ((uAvg + vAvg ) >> 2));
2401 buff16[j] = (yval << 5) | ((Clamp6(uAvg + yval) >> 1) << 11) | (Clamp6(vAvg + yval) >> 1);
2407 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2416 #ifdef __PGFROISUPPORT__
2421 buff = buffStart + (levelRoi.
top - roi.
top)*pitch + (levelRoi.
left - roi.
left)*bypp;
2422 w = levelRoi.
Width()*bypp;
2425 for (i=0; i < h; i++) {
2426 for (j=0; j < w; j++) {
2427 targetBuff[j] = buff[j];
2429 targetBuff += targetPitch;
2457 const UINT32 w = m_width[0];
2458 const UINT32 h = m_height[0];
2459 const bool wOdd = (1 == w%2);
2460 const int dataBits =
DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2463 const double dP = 1.0/h;
2465 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
2466 if (channelMap == NULL) channelMap = defMap;
2467 int sampledPos = 0, yPos = 0;
2472 if (m_header.channels == 3) {
2473 ASSERT(bpp%dataBits == 0);
2475 DataT* y = m_channel[0]; ASSERT(y);
2476 DataT* u = m_channel[1]; ASSERT(u);
2477 DataT* v = m_channel[2]; ASSERT(v);
2478 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2480 for (i=0; i < h; i++) {
2481 if (i%2) sampledPos -= (w + 1)/2;
2483 for (j=0; j < w; j++) {
2486 uAvg = u[sampledPos];
2487 vAvg = v[sampledPos];
2492 buff[cnt + channelMap[0]] = y[yPos];
2493 buff[cnt + channelMap[1]] = uAvg;
2494 buff[cnt + channelMap[2]] = vAvg;
2497 if (j%2) sampledPos++;
2500 if (wOdd) sampledPos++;
2504 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2507 }
else if (m_header.channels == 4) {
2508 ASSERT(m_header.bpp == m_header.channels*8);
2509 ASSERT(bpp%dataBits == 0);
2511 DataT* y = m_channel[0]; ASSERT(y);
2512 DataT* u = m_channel[1]; ASSERT(u);
2513 DataT* v = m_channel[2]; ASSERT(v);
2514 DataT* a = m_channel[3]; ASSERT(a);
2516 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2518 for (i=0; i < h; i++) {
2519 if (i%2) sampledPos -= (w + 1)/2;
2521 for (j=0; j < w; j++) {
2524 uAvg = u[sampledPos];
2525 vAvg = v[sampledPos];
2526 aAvg = Clamp8(a[sampledPos] + yuvOffset);
2530 aAvg = Clamp8(a[yPos] + yuvOffset);
2533 buff[cnt + channelMap[0]] = y[yPos];
2534 buff[cnt + channelMap[1]] = uAvg;
2535 buff[cnt + channelMap[2]] = vAvg;
2536 buff[cnt + channelMap[3]] = aAvg;
2539 if (j%2) sampledPos++;
2542 if (wOdd) sampledPos++;
2546 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2568 const double dP = 1.0/m_header.height;
2569 const int dataBits =
DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2573 int yPos = 0, cnt = 0;
2575 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
2577 if (channelMap == NULL) channelMap = defMap;
2579 if (m_header.channels == 3) {
2580 ASSERT(bpp%dataBits == 0);
2582 DataT* y = m_channel[0]; ASSERT(y);
2583 DataT* u = m_channel[1]; ASSERT(u);
2584 DataT* v = m_channel[2]; ASSERT(v);
2585 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2587 for (UINT32 h=0; h < m_header.height; h++) {
2589 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2594 for (UINT32 w=0; w < m_header.width; w++) {
2595 y[yPos] = buff[cnt + channelMap[0]];
2596 u[yPos] = buff[cnt + channelMap[1]];
2597 v[yPos] = buff[cnt + channelMap[2]];
2603 }
else if (m_header.channels == 4) {
2604 ASSERT(bpp%dataBits == 0);
2606 DataT* y = m_channel[0]; ASSERT(y);
2607 DataT* u = m_channel[1]; ASSERT(u);
2608 DataT* v = m_channel[2]; ASSERT(v);
2609 DataT* a = m_channel[3]; ASSERT(a);
2610 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2612 for (UINT32 h=0; h < m_header.height; h++) {
2614 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2619 for (UINT32 w=0; w < m_header.width; w++) {
2620 y[yPos] = buff[cnt + channelMap[0]];
2621 u[yPos] = buff[cnt + channelMap[1]];
2622 v[yPos] = buff[cnt + channelMap[2]];
2623 a[yPos] = buff[cnt + channelMap[3]] - yuvOffset;
2633 for (
int i=1; i < m_header.channels; i++) {
const RGBQUAD * GetColorTable() const
UINT64 m_userDataPos
stream position of user data
UINT8 version
PGF version.
BYTE UsedBitsPerChannel() const
#define PGFVersion
current standard version
UINT32 AlignWordPos(UINT32 pos)
#define MaxChannels
maximum number of (color) channels
static BYTE CurrentVersion(BYTE version=PGFVersion)
Return version.
Abstract stream base class.
UINT32 ReadEncodedData(int level, UINT8 *target, UINT32 targetLen) const THROW_
void ImportYUV(int pitch, DataT *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) THROW_
void ExtractTile(CEncoder &encoder, bool tile=false, UINT32 tileX=0, UINT32 tileY=0) THROW_
void RgbToYuv(int pitch, UINT8 *rgbBuff, BYTE bpp, int channelMap[], CallbackPtr cb, void *data) THROW_
void Write(CPGFStream *stream, UINT32 *nWrittenBytes=NULL, CallbackPtr cb=NULL, void *data=NULL) THROW_
CDecoder * m_decoder
PGF decoder.
void Open(CPGFStream *stream) THROW_
PGFHeader m_header
PGF file header.
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
PGFPreHeader m_preHeader
PGF pre-header.
UINT32 WriteLevelLength(UINT32 *&levelLength) THROW_
const UINT8 * GetUserData(UINT32 &size) const
void GetBitmap(int pitch, UINT8 *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) const THROW_
void SetROI(PGFRect rect)
void GetYUV(int pitch, DataT *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) const THROW_
#define Version6
new HeaderSize: 32 bits instead of 16 bits
#define ColorTableLen
size of color lookup table (clut)
#define MaxLevel
maximum number of transform levels
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
void Read(int level=0, CallbackPtr cb=NULL, void *data=NULL) THROW_
char magic[3]
PGF identification = "PGF".
PGFPostHeader m_postHeader
PGF post-header.
UINT32 ReadEncodedHeader(UINT8 *target, UINT32 targetLen) const THROW_
bool m_downsample
chrominance channels are downsampled
#define DownsampleThreshold
if quality is larger than this threshold than downsampling is used
UINT32 UpdatePostHeaderSize() THROW_
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
UINT32 m_width[MaxChannels]
width of each channel at current level
#define Version2
data structure PGFHeader of major version 2
CPGFImage()
Standard constructor: It is used to create a PGF instance for opening and reading.
void SetColorTable(UINT32 iFirstColor, UINT32 nColors, const RGBQUAD *prgbColors) THROW_
void ImportBitmap(int pitch, UINT8 *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) THROW_
bool IsInside(UINT32 x, UINT32 y) const
#define MaxQuality
maximum quality
void Reconstruct(int level=0) THROW_
virtual ~CPGFImage()
Destructor: Destroy internal data structures.
UINT32 GetEncodedHeaderLength() const
bool ROIisSupported() const
double m_percent
progress [0..1]
void SetMaxValue(UINT32 maxValue)
UINT32 WriteHeader(CPGFStream *stream) THROW_
static bool ImportIsSupported(BYTE mode)
UINT32 GetEncodedHeaderLength() const
CEncoder * m_encoder
PGF encoder.
#define Magic
PGF identification.
void ResetStreamPos() THROW_
Reset stream position to start of PGF pre-header.
INT64 ComputeOffset() const
void Downsample(int nChannel)
UINT32 WriteImage(CPGFStream *stream, CallbackPtr cb=NULL, void *data=NULL) THROW_
int m_currentLevel
transform level of current image
#define Version5
new coding scheme since major version 5
void SetHeader(const PGFHeader &header, BYTE flags=0, UINT8 *userData=0, UINT32 userDataLength=0) THROW_
UINT32 m_height[MaxChannels]
height of each channel at current level
void SetStreamPosToStart() THROW_
Reset stream position to beginning of PGF pre-header.
PGFRect m_roi
region of interest
void UpdatePostHeaderSize(PGFPreHeader preHeader) THROW_
void SetEncodedLevel(int currentLevel)