38#define YUVoffset16 32768
46 OSError GetLastPGFError() {
47 OSError tmp = _PGF_Error_;
48 _PGF_Error_ = NoError;
63, m_favorSpeedOverSize(false)
64, m_useOMPinEncoder(true)
65, m_useOMPinDecoder(true)
66, m_skipUserData(false)
68, m_streamReinitialized(false)
135 m_decoder =
new CDecoder(stream, m_preHeader, m_header, m_postHeader, m_levelLength,
136 m_userDataPos, m_useOMPinDecoder, m_skipUserData);
138 if (m_header.nLevels >
MaxLevel) ReturnWithError(FormatCannotRead);
141 m_currentLevel = m_header.nLevels;
144 m_width[0] = m_header.width;
145 m_height[0] = m_header.height;
160 m_quant = m_header.quality - 1;
162 m_downsample =
false;
163 m_quant = m_header.quality;
168 for (
int i=1; i < m_header.channels; i++) {
169 m_width[i] = (m_width[0] + 1)/2;
170 m_height[i] = (m_height[0] + 1)/2;
173 for (
int i=1; i < m_header.channels; i++) {
174 m_width[i] = m_width[0];
175 m_height[i] = m_height[0];
179 if (m_header.nLevels > 0) {
181 for (
int i=0; i < m_header.channels; i++) {
182 m_wtChannel[i] =
new CWaveletTransform(m_width[i], m_height[i], m_header.nLevels);
186 m_percent = pow(0.25, m_header.nLevels);
192 for (
int c=0; c < m_header.channels; c++) {
193 const UINT32 size = m_width[c]*m_height[c];
194 m_channel[c] =
new(std::nothrow)
DataT[size];
195 if (!m_channel[c]) ReturnWithError(InsufficientMemory);
198 for (UINT32 i=0; i < size; i++) {
200 stream->Read(&count, &m_channel[c][i]);
201 if (count !=
DataTSize) ReturnWithError(MissingData);
310 if (bpc > 31) bpc = 31;
332 if (m_header.nLevels == 0) {
335 for (
int i=0; i < m_header.channels; i++) {
336 ASSERT(m_wtChannel[i]);
337 m_channel[i] = m_wtChannel[i]->GetSubband(0,
LL)->GetBuffer();
341 int currentLevel = m_header.nLevels;
343 if (ROIisSupported()) {
345 SetROI(
PGFRect(0, 0, m_header.width, m_header.height));
348 while (currentLevel > level) {
349 for (
int i=0; i < m_header.channels; i++) {
350 ASSERT(m_wtChannel[i]);
352 if (currentLevel == m_header.nLevels) {
354 m_wtChannel[i]->GetSubband(currentLevel,
LL)->Dequantize(m_quant);
356 m_wtChannel[i]->GetSubband(currentLevel,
HL)->Dequantize(m_quant);
357 m_wtChannel[i]->GetSubband(currentLevel,
LH)->Dequantize(m_quant);
358 m_wtChannel[i]->GetSubband(currentLevel,
HH)->Dequantize(m_quant);
361 OSError err = m_wtChannel[i]->InverseTransform(currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
362 if (err != NoError) ReturnWithError(err);
363 ASSERT(m_channel[i]);
384 ASSERT((level >= 0 && level < m_header.nLevels) || m_header.nLevels == 0);
387#ifdef __PGFROISUPPORT__
388 if (ROIisSupported() && m_header.nLevels > 0) {
390 PGFRect rect(0, 0, m_header.width, m_header.height);
391 Read(rect, level, cb, data);
396 if (m_header.nLevels == 0) {
401 if ((*cb)(1.0,
true, data)) ReturnWithError(EscapePressed);
405 const int levelDiff = m_currentLevel - level;
406 double percent = (m_progressMode ==
PM_Relative) ? pow(0.25, levelDiff) : m_percent;
409 while (m_currentLevel > level) {
410 for (
int i=0; i < m_header.channels; i++) {
411 ASSERT(m_wtChannel[i]);
413 if (m_currentLevel == m_header.nLevels) {
415 m_wtChannel[i]->GetSubband(m_currentLevel,
LL)->PlaceTile(*m_decoder, m_quant);
417 if (m_preHeader.version &
Version5) {
419 m_wtChannel[i]->GetSubband(m_currentLevel,
HL)->PlaceTile(*m_decoder, m_quant);
420 m_wtChannel[i]->GetSubband(m_currentLevel,
LH)->PlaceTile(*m_decoder, m_quant);
423 m_decoder->DecodeInterleaved(m_wtChannel[i], m_currentLevel, m_quant);
425 m_wtChannel[i]->GetSubband(m_currentLevel,
HH)->PlaceTile(*m_decoder, m_quant);
428 volatile OSError error = NoError;
429#ifdef LIBPGF_USE_OPENMP
430 #pragma omp parallel for default(shared)
432 for (
int i=0; i < m_header.channels; i++) {
434 if (error == NoError) {
435 OSError err = m_wtChannel[i]->InverseTransform(m_currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
436 if (err != NoError) error = err;
438 ASSERT(m_channel[i]);
440 if (error != NoError) ReturnWithError(error);
446 if (m_cb) m_cb(m_cbArg);
451 if (m_progressMode ==
PM_Absolute) m_percent = percent;
452 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
458 if (m_currentLevel == 0) Close();
461#ifdef __PGFROISUPPORT__
472 ASSERT((level >= 0 && level < m_header.nLevels) || m_header.nLevels == 0);
475 if (m_header.nLevels == 0 || !ROIisSupported()) {
476 rect.left = rect.top = 0;
477 rect.right = m_header.width; rect.bottom = m_header.height;
478 Read(level, cb, data);
480 ASSERT(ROIisSupported());
482 ASSERT(rect.left < m_header.width && rect.top < m_header.height);
484 const int levelDiff = m_currentLevel - level;
485 double percent = (m_progressMode ==
PM_Relative) ? pow(0.25, levelDiff) : m_percent;
488 if (levelDiff <= 0) {
490 m_currentLevel = m_header.nLevels;
491 m_decoder->SetStreamPosToData();
495 if (rect.right == 0 || rect.right > m_header.width) rect.right = m_header.width;
496 if (rect.bottom == 0 || rect.bottom > m_header.height) rect.bottom = m_header.height;
501 while (m_currentLevel > level) {
502 for (
int i=0; i < m_header.channels; i++) {
503 ASSERT(m_wtChannel[i]);
506 const UINT32 nTiles = m_wtChannel[i]->GetNofTiles(m_currentLevel);
507 const PGFRect& tileIndices = m_wtChannel[i]->GetTileIndices(m_currentLevel);
510 if (m_currentLevel == m_header.nLevels) {
512 m_decoder->DecodeTileBuffer();
513 m_wtChannel[i]->GetSubband(m_currentLevel,
LL)->PlaceTile(*m_decoder, m_quant);
515 for (UINT32 tileY=0; tileY < nTiles; tileY++) {
516 for (UINT32 tileX=0; tileX < nTiles; tileX++) {
518 if (tileIndices.
IsInside(tileX, tileY)) {
519 m_decoder->DecodeTileBuffer();
520 m_wtChannel[i]->GetSubband(m_currentLevel,
HL)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
521 m_wtChannel[i]->GetSubband(m_currentLevel,
LH)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
522 m_wtChannel[i]->GetSubband(m_currentLevel,
HH)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
525 m_decoder->SkipTileBuffer();
531 volatile OSError error = NoError;
532#ifdef LIBPGF_USE_OPENMP
533 #pragma omp parallel for default(shared)
535 for (
int i=0; i < m_header.channels; i++) {
537 if (error == NoError) {
538 OSError err = m_wtChannel[i]->InverseTransform(m_currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
539 if (err != NoError) error = err;
541 ASSERT(m_channel[i]);
543 if (error != NoError) ReturnWithError(error);
549 if (m_cb) m_cb(m_cbArg);
554 if (m_progressMode ==
PM_Absolute) m_percent = percent;
555 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
561 if (m_currentLevel == 0) Close();
582 else rect.
left -= dx;
583 if (rect.
top < dy) rect.
top = 0;
626 ASSERT(targetLen > 0);
630 m_decoder->SetStreamPosToStart();
633 UINT32 len =
__min(targetLen, GetEncodedHeaderLength());
636 len = m_decoder->ReadEncodedData(target, len);
637 ASSERT(len >= 0 && len <= targetLen);
659 ASSERT(level >= 0 && level < m_header.nLevels);
661 ASSERT(targetLen > 0);
665 m_decoder->SetStreamPosToData();
670 for (
int i=m_header.nLevels - 1; i > level; i--) {
671 offset += m_levelLength[m_header.nLevels - 1 - i];
673 m_decoder->Skip(offset);
676 UINT32 len =
__min(targetLen, GetEncodedLevelLength(level));
679 len = m_decoder->ReadEncodedData(target, len);
680 ASSERT(len >= 0 && len <= targetLen);
693 while(maxValue > 0) {
698 if (pot > bpc) pot = bpc;
699 if (pot > 31) pot = 31;
744 ASSERT(m_channel[0]);
747 RgbToYuv(pitch, buff, bpp, channelMap, cb, data);
751 for (
int i=1; i < m_header.channels; i++) {
765 const int oddW = w%2;
772 for (
int i=0; i < h2; i++) {
773 for (
int j=0; j < w2; j++) {
775 buff[sampledPos] = (buff[loPos] + buff[loPos + 1] + buff[hiPos] + buff[hiPos + 1]) >> 2;
776 loPos += 2; hiPos += 2;
780 buff[sampledPos] = (buff[loPos] + buff[hiPos]) >> 1;
784 loPos += w; hiPos += w;
787 for (
int j=0; j < w2; j++) {
788 buff[sampledPos] = (buff[loPos] + buff[loPos+1]) >> 1;
789 loPos += 2; hiPos += 2;
793 buff[sampledPos] = buff[loPos];
811 while (s > maxThumbnailWidth) {
848#ifdef __PGFROISUPPORT__
849 m_streamReinitialized =
false;
853 memcpy(m_preHeader.magic,
PGFMagic, 3);
875 m_quant = m_header.quality - 1;
877 m_downsample =
false;
878 m_quant = m_header.quality;
886 if (userDataLength && userData) {
887 m_postHeader.userData =
new(std::nothrow) UINT8[userDataLength];
888 if (!m_postHeader.userData) ReturnWithError(InsufficientMemory);
889 m_postHeader.userDataLen = userDataLength;
890 memcpy(m_postHeader.userData, userData, userDataLength);
892 m_preHeader.hSize += userDataLength;
896 for (
int i=0; i < m_header.channels; i++) {
898 m_width[i] = m_header.width;
899 m_height[i] = m_header.height;
902 ASSERT(!m_channel[i]);
903 m_channel[i] =
new(std::nothrow)
DataT[m_header.width*m_header.height];
907 delete[] m_channel[i]; m_channel[i] = 0;
910 ReturnWithError(InsufficientMemory);
923 ASSERT(m_header.nLevels <=
MaxLevel);
926 if (m_header.nLevels > 0) {
927 volatile OSError error = NoError;
929#ifdef LIBPGF_USE_OPENMP
930 #pragma omp parallel for default(shared)
932 for (
int i=0; i < m_header.channels; i++) {
934 if (error == NoError) {
935 if (m_wtChannel[i]) {
936 ASSERT(m_channel[i]);
938 int size = m_height[i]*m_width[i];
939 temp =
new(std::nothrow)
DataT[size];
941 memcpy(temp, m_channel[i], size*
DataTSize);
942 delete m_wtChannel[i];
945 error = InsufficientMemory;
948 if (error == NoError) {
950 ASSERT(!m_channel[i]);
953 m_wtChannel[i] =
new CWaveletTransform(m_width[i], m_height[i], m_header.nLevels, m_channel[i]);
954 if (m_wtChannel[i]) {
955 #ifdef __PGFROISUPPORT__
956 m_wtChannel[i]->SetROI(
PGFRect(0, 0, m_width[i], m_height[i]));
960 for (
int l=0; error == NoError && l < m_header.nLevels; l++) {
961 OSError err = m_wtChannel[i]->ForwardTransform(l, m_quant);
962 if (err != NoError) error = err;
965 delete[] m_channel[i];
966 error = InsufficientMemory;
971 if (error != NoError) {
973 for (
int i=0; i < m_header.channels; i++) {
974 delete m_wtChannel[i];
976 ReturnWithError(error);
979 m_currentLevel = m_header.nLevels;
982 m_encoder =
new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_userDataPos, m_useOMPinEncoder);
983 if (m_favorSpeedOverSize) m_encoder->FavorSpeedOverSize();
985 #ifdef __PGFROISUPPORT__
986 if (ROIisSupported()) {
996 m_encoder =
new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_userDataPos, m_useOMPinEncoder);
999 INT64 nBytes = m_encoder->ComputeHeaderLength();
1000 return (nBytes > 0) ? (UINT32)nBytes : 0;
1016#ifdef __PGFROISUPPORT__
1023 const UINT32 lastTile = nTiles - 1;
1027 ASSERT(nTiles == 1);
1031 for (UINT32 tileY=0; tileY < nTiles; tileY++) {
1032 for (UINT32 tileX=0; tileX < nTiles; tileX++) {
1036 if (i == lastChannel && tileY == lastTile && tileX == lastTile) {
1093 ASSERT(m_preHeader.hSize);
1095 int levels = m_header.nLevels;
1096 double percent = pow(0.25, levels);
1099 UINT32 nWrittenBytes = UpdatePostHeaderSize();
1103 for (
int c=0; c < m_header.channels; c++) {
1104 const UINT32 size = m_width[c]*m_height[c];
1107 for (UINT32 i=0; i < size; i++) {
1109 stream->Write(&count, &m_channel[c][i]);
1115 if ((*cb)(1,
true, data)) ReturnWithError(EscapePressed);
1124 for (m_currentLevel = levels; m_currentLevel > 0; ) {
1130 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1139 nWrittenBytes += m_encoder->UpdateLevelLength();
1142 delete m_encoder; m_encoder = NULL;
1146 return nWrittenBytes;
1164 ASSERT(m_preHeader.hSize);
1167 UINT32 nBytes = WriteHeader(stream);
1170 nBytes += WriteImage(stream, cb, data);
1173 if (nWrittenBytes) *nWrittenBytes += nBytes;
1176#ifdef __PGFROISUPPORT__
1192 ASSERT(m_header.nLevels > 0);
1193 ASSERT(0 <= level && level < m_header.nLevels);
1195 ASSERT(ROIisSupported());
1197 const int levelDiff = m_currentLevel - level;
1198 double percent = (m_progressMode ==
PM_Relative) ? pow(0.25, levelDiff) : m_percent;
1199 UINT32 nWrittenBytes = 0;
1201 if (m_currentLevel == m_header.nLevels) {
1203 nWrittenBytes = UpdatePostHeaderSize();
1206 if (m_encoder->ComputeBufferLength()) {
1207 m_streamReinitialized =
true;
1212 while (m_currentLevel > level) {
1215 if (m_levelLength) {
1216 nWrittenBytes += m_levelLength[m_header.nLevels - m_currentLevel - 1];
1222 if (m_progressMode ==
PM_Absolute) m_percent = percent;
1223 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1228 if (m_currentLevel == 0) {
1229 if (!m_streamReinitialized) {
1231 m_encoder->UpdateLevelLength();
1234 delete m_encoder; m_encoder = NULL;
1237 return nWrittenBytes;
1292 if (iFirstColor + nColors >
ColorTableLen) ReturnWithError(ColorTableError);
1294 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1295 prgbColors[j] = m_postHeader.clut[i];
1306 if (iFirstColor + nColors >
ColorTableLen) ReturnWithError(ColorTableError);
1308 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1309 m_postHeader.clut[i] = prgbColors[j];
1330void CPGFImage::RgbToYuv(
int pitch, UINT8* buff, BYTE bpp,
int channelMap[], CallbackPtr cb,
void *data ) THROW_ {
1332 int yPos = 0, cnt = 0;
1334 const double dP = 1.0/m_header.height;
1335 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
1337 if (channelMap == NULL) channelMap = defMap;
1339 switch(m_header.mode) {
1342 ASSERT(m_header.channels == 1);
1343 ASSERT(m_header.bpp == 1);
1346 const UINT32 w = m_header.width;
1347 const UINT32 w2 = (m_header.width + 7)/8;
1348 DataT* y = m_channel[0]; ASSERT(y);
1350 for (UINT32 h=0; h < m_header.height; h++) {
1352 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1356 for (UINT32 j=0; j < w2; j++) {
1359 for (UINT32 j=w2; j < w; j++) {
1382 ASSERT(m_header.channels >= 1);
1383 ASSERT(m_header.bpp == m_header.channels*8);
1385 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1387 for (UINT32 h=0; h < m_header.height; h++) {
1389 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1394 for (UINT32 w=0; w < m_header.width; w++) {
1395 for (
int c=0; c < m_header.channels; c++) {
1396 m_channel[c][yPos] = buff[cnt + channelMap[c]] -
YUVoffset8;
1408 ASSERT(m_header.channels >= 1);
1409 ASSERT(m_header.bpp == m_header.channels*16);
1410 ASSERT(bpp%16 == 0);
1412 UINT16 *buff16 = (UINT16 *)buff;
1413 const int pitch16 = pitch/2;
1414 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1415 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1416 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1418 for (UINT32 h=0; h < m_header.height; h++) {
1420 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1425 for (UINT32 w=0; w < m_header.width; w++) {
1426 for (
int c=0; c < m_header.channels; c++) {
1427 m_channel[c][yPos] = (buff16[cnt + channelMap[c]] >> shift) - yuvOffset16;
1438 ASSERT(m_header.channels == 3);
1439 ASSERT(m_header.bpp == m_header.channels*8);
1442 DataT* y = m_channel[0]; ASSERT(y);
1443 DataT* u = m_channel[1]; ASSERT(u);
1444 DataT* v = m_channel[2]; ASSERT(v);
1445 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1448 for (UINT32 h=0; h < m_header.height; h++) {
1450 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1455 for (UINT32 w=0; w < m_header.width; w++) {
1456 b = buff[cnt + channelMap[0]];
1457 g = buff[cnt + channelMap[1]];
1458 r = buff[cnt + channelMap[2]];
1460 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset8;
1472 ASSERT(m_header.channels == 3);
1473 ASSERT(m_header.bpp == m_header.channels*16);
1474 ASSERT(bpp%16 == 0);
1476 UINT16 *buff16 = (UINT16 *)buff;
1477 const int pitch16 = pitch/2;
1478 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1479 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1480 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1482 DataT* y = m_channel[0]; ASSERT(y);
1483 DataT* u = m_channel[1]; ASSERT(u);
1484 DataT* v = m_channel[2]; ASSERT(v);
1487 for (UINT32 h=0; h < m_header.height; h++) {
1489 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1494 for (UINT32 w=0; w < m_header.width; w++) {
1495 b = buff16[cnt + channelMap[0]] >> shift;
1496 g = buff16[cnt + channelMap[1]] >> shift;
1497 r = buff16[cnt + channelMap[2]] >> shift;
1499 y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1512 ASSERT(m_header.channels == 4);
1513 ASSERT(m_header.bpp == m_header.channels*8);
1515 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1517 DataT* y = m_channel[0]; ASSERT(y);
1518 DataT* u = m_channel[1]; ASSERT(u);
1519 DataT* v = m_channel[2]; ASSERT(v);
1520 DataT* a = m_channel[3]; ASSERT(a);
1523 for (UINT32 h=0; h < m_header.height; h++) {
1525 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1530 for (UINT32 w=0; w < m_header.width; w++) {
1531 b = buff[cnt + channelMap[0]];
1532 g = buff[cnt + channelMap[1]];
1533 r = buff[cnt + channelMap[2]];
1535 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset8;
1538 a[yPos++] = buff[cnt + channelMap[3]] -
YUVoffset8;
1547 ASSERT(m_header.channels == 4);
1548 ASSERT(m_header.bpp == m_header.channels*16);
1549 ASSERT(bpp%16 == 0);
1551 UINT16 *buff16 = (UINT16 *)buff;
1552 const int pitch16 = pitch/2;
1553 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1554 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1555 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1557 DataT* y = m_channel[0]; ASSERT(y);
1558 DataT* u = m_channel[1]; ASSERT(u);
1559 DataT* v = m_channel[2]; ASSERT(v);
1560 DataT* a = m_channel[3]; ASSERT(a);
1563 for (UINT32 h=0; h < m_header.height; h++) {
1565 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1570 for (UINT32 w=0; w < m_header.width; w++) {
1571 b = buff16[cnt + channelMap[0]] >> shift;
1572 g = buff16[cnt + channelMap[1]] >> shift;
1573 r = buff16[cnt + channelMap[2]] >> shift;
1575 y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1578 a[yPos++] = (buff16[cnt + channelMap[3]] >> shift) - yuvOffset16;
1585#ifdef __PGF32SUPPORT__
1588 ASSERT(m_header.channels == 1);
1589 ASSERT(m_header.bpp == 32);
1593 DataT* y = m_channel[0]; ASSERT(y);
1595 UINT32 *buff32 = (UINT32 *)buff;
1596 const int pitch32 = pitch/4;
1597 const int shift = 31 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1598 const DataT yuvOffset31 = 1 << (UsedBitsPerChannel() - 1);
1600 for (UINT32 h=0; h < m_header.height; h++) {
1602 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1606 for (UINT32 w=0; w < m_header.width; w++) {
1607 y[yPos++] = (buff32[w] >> shift) - yuvOffset31;
1616 ASSERT(m_header.channels == 3);
1617 ASSERT(m_header.bpp == m_header.channels*4);
1618 ASSERT(bpp == m_header.channels*4);
1620 DataT* y = m_channel[0]; ASSERT(y);
1621 DataT* u = m_channel[1]; ASSERT(u);
1622 DataT* v = m_channel[2]; ASSERT(v);
1624 UINT8 rgb = 0, b, g, r;
1626 for (UINT32 h=0; h < m_header.height; h++) {
1628 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1633 for (UINT32 w=0; w < m_header.width; w++) {
1638 g = (rgb & 0xF0) >> 4;
1644 b = (rgb & 0xF0) >> 4;
1648 r = (rgb & 0xF0) >> 4;
1653 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset4;
1664 ASSERT(m_header.channels == 3);
1665 ASSERT(m_header.bpp == 16);
1668 DataT* y = m_channel[0]; ASSERT(y);
1669 DataT* u = m_channel[1]; ASSERT(u);
1670 DataT* v = m_channel[2]; ASSERT(v);
1672 UINT16 *buff16 = (UINT16 *)buff;
1673 UINT16 rgb, b, g, r;
1674 const int pitch16 = pitch/2;
1676 for (UINT32 h=0; h < m_header.height; h++) {
1678 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1681 for (UINT32 w=0; w < m_header.width; w++) {
1683 r = (rgb & 0xF800) >> 10;
1684 g = (rgb & 0x07E0) >> 5;
1685 b = (rgb & 0x001F) << 1;
1687 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset6;
1719void CPGFImage::GetBitmap(
int pitch, UINT8* buff, BYTE bpp,
int channelMap[] , CallbackPtr cb ,
void *data )
const THROW_ {
1721 UINT32 w = m_width[0];
1722 UINT32 h = m_height[0];
1723 UINT8* targetBuff = 0;
1724 UINT8* buffStart = 0;
1725 int targetPitch = 0;
1727#ifdef __PGFROISUPPORT__
1728 const PGFRect& roi = (ROIisSupported()) ? m_wtChannel[0]->GetROI(m_currentLevel) :
PGFRect(0, 0, w, h);
1729 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));
1734 if (ROIisSupported() && (levelRoi.
Width() < w || levelRoi.
Height() < h)) {
1737 targetPitch = pitch;
1742 buff = buffStart =
new(std::nothrow) UINT8[pitch*h];
1743 if (!buff) ReturnWithError(InsufficientMemory);
1747 const bool wOdd = (1 == w%2);
1749 const double dP = 1.0/h;
1750 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
1751 if (channelMap == NULL) channelMap = defMap;
1752 int sampledPos = 0, yPos = 0;
1757 switch(m_header.mode) {
1760 ASSERT(m_header.channels == 1);
1761 ASSERT(m_header.bpp == 1);
1764 const UINT32 w2 = (w + 7)/8;
1765 DataT* y = m_channel[0]; ASSERT(y);
1767 for (i=0; i < h; i++) {
1769 for (j=0; j < w2; j++) {
1789 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1799 ASSERT(m_header.channels >= 1);
1800 ASSERT(m_header.bpp == m_header.channels*8);
1803 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
1805 for (i=0; i < h; i++) {
1807 for (j=0; j < w; j++) {
1808 for (
int c=0; c < m_header.channels; c++) {
1809 buff[cnt + channelMap[c]] = Clamp8(m_channel[c][yPos] +
YUVoffset8);
1818 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1825 ASSERT(m_header.channels >= 1);
1826 ASSERT(m_header.bpp == m_header.channels*16);
1828 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1832 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1833 UINT16 *buff16 = (UINT16 *)buff;
1834 int pitch16 = pitch/2;
1835 channels = bpp/16; ASSERT(channels >= m_header.channels);
1837 for (i=0; i < h; i++) {
1839 for (j=0; j < w; j++) {
1840 for (
int c=0; c < m_header.channels; c++) {
1841 buff16[cnt + channelMap[c]] = Clamp16((m_channel[c][yPos] + yuvOffset16) << shift);
1850 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1855 const int shift =
__max(0, UsedBitsPerChannel() - 8);
1856 channels = bpp/8; ASSERT(channels >= m_header.channels);
1858 for (i=0; i < h; i++) {
1860 for (j=0; j < w; j++) {
1861 for (
int c=0; c < m_header.channels; c++) {
1862 buff[cnt + channelMap[c]] = Clamp8((m_channel[c][yPos] + yuvOffset16) >> shift);
1871 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1879 ASSERT(m_header.channels == 3);
1880 ASSERT(m_header.bpp == m_header.channels*8);
1882 ASSERT(bpp >= m_header.bpp);
1884 DataT* y = m_channel[0]; ASSERT(y);
1885 DataT* u = m_channel[1]; ASSERT(u);
1886 DataT* v = m_channel[2]; ASSERT(v);
1887 UINT8 *buffg = &buff[channelMap[1]],
1888 *buffr = &buff[channelMap[2]],
1889 *buffb = &buff[channelMap[0]];
1891 int cnt, channels = bpp/8;
1893 for (i=0; i < h; i++) {
1894 if (i%2) sampledPos -= (w + 1)/2;
1896 for (j=0; j < w; j++) {
1898 uAvg = u[sampledPos];
1899 vAvg = v[sampledPos];
1901 buffg[cnt] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
1902 buffr[cnt] = Clamp8(uAvg + g);
1903 buffb[cnt] = Clamp8(vAvg + g);
1906 if (j%2) sampledPos++;
1911 if (wOdd) sampledPos++;
1914 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1918 for (i=0; i < h; i++) {
1920 for (j = 0; j < w; j++) {
1924 buffg[cnt] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
1925 buffr[cnt] = Clamp8(uAvg + g);
1926 buffb[cnt] = Clamp8(vAvg + g);
1936 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1944 ASSERT(m_header.channels == 3);
1945 ASSERT(m_header.bpp == 48);
1947 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1949 DataT* y = m_channel[0]; ASSERT(y);
1950 DataT* u = m_channel[1]; ASSERT(u);
1951 DataT* v = m_channel[2]; ASSERT(v);
1955 if (bpp >= 48 && bpp%16 == 0) {
1956 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1957 UINT16 *buff16 = (UINT16 *)buff;
1958 int pitch16 = pitch/2;
1959 channels = bpp/16; ASSERT(channels >= m_header.channels);
1961 for (i=0; i < h; i++) {
1962 if (i%2) sampledPos -= (w + 1)/2;
1964 for (j=0; j < w; j++) {
1967 uAvg = u[sampledPos];
1968 vAvg = v[sampledPos];
1974 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
1975 buff16[cnt + channelMap[1]] = Clamp16(g << shift);
1976 buff16[cnt + channelMap[2]] = Clamp16((uAvg + g) << shift);
1977 buff16[cnt + channelMap[0]] = Clamp16((vAvg + g) << shift);
1980 if (j%2) sampledPos++;
1983 if (wOdd) sampledPos++;
1987 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1992 const int shift =
__max(0, UsedBitsPerChannel() - 8);
1993 channels = bpp/8; ASSERT(channels >= m_header.channels);
1995 for (i=0; i < h; i++) {
1996 if (i%2) sampledPos -= (w + 1)/2;
1998 for (j=0; j < w; j++) {
2001 uAvg = u[sampledPos];
2002 vAvg = v[sampledPos];
2008 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
2009 buff[cnt + channelMap[1]] = Clamp8(g >> shift);
2010 buff[cnt + channelMap[2]] = Clamp8((uAvg + g) >> shift);
2011 buff[cnt + channelMap[0]] = Clamp8((vAvg + g) >> shift);
2014 if (j%2) sampledPos++;
2017 if (wOdd) sampledPos++;
2021 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2029 ASSERT(m_header.channels == 3);
2030 ASSERT(m_header.bpp == m_header.channels*8);
2033 DataT* l = m_channel[0]; ASSERT(l);
2034 DataT* a = m_channel[1]; ASSERT(a);
2035 DataT* b = m_channel[2]; ASSERT(b);
2036 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
2038 for (i=0; i < h; i++) {
2039 if (i%2) sampledPos -= (w + 1)/2;
2041 for (j=0; j < w; j++) {
2044 uAvg = a[sampledPos];
2045 vAvg = b[sampledPos];
2050 buff[cnt + channelMap[0]] = Clamp8(l[yPos] +
YUVoffset8);
2051 buff[cnt + channelMap[1]] = Clamp8(uAvg +
YUVoffset8);
2052 buff[cnt + channelMap[2]] = Clamp8(vAvg +
YUVoffset8);
2055 if (j%2) sampledPos++;
2058 if (wOdd) sampledPos++;
2062 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2069 ASSERT(m_header.channels == 3);
2070 ASSERT(m_header.bpp == m_header.channels*16);
2072 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2074 DataT* l = m_channel[0]; ASSERT(l);
2075 DataT* a = m_channel[1]; ASSERT(a);
2076 DataT* b = m_channel[2]; ASSERT(b);
2080 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2081 UINT16 *buff16 = (UINT16 *)buff;
2082 int pitch16 = pitch/2;
2083 channels = bpp/16; ASSERT(channels >= m_header.channels);
2085 for (i=0; i < h; i++) {
2086 if (i%2) sampledPos -= (w + 1)/2;
2088 for (j=0; j < w; j++) {
2091 uAvg = a[sampledPos];
2092 vAvg = b[sampledPos];
2097 buff16[cnt + channelMap[0]] = Clamp16((l[yPos] + yuvOffset16) << shift);
2098 buff16[cnt + channelMap[1]] = Clamp16((uAvg + yuvOffset16) << shift);
2099 buff16[cnt + channelMap[2]] = Clamp16((vAvg + yuvOffset16) << shift);
2102 if (j%2) sampledPos++;
2105 if (wOdd) sampledPos++;
2109 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2114 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2115 channels = bpp/8; ASSERT(channels >= m_header.channels);
2117 for (i=0; i < h; i++) {
2118 if (i%2) sampledPos -= (w + 1)/2;
2120 for (j=0; j < w; j++) {
2123 uAvg = a[sampledPos];
2124 vAvg = b[sampledPos];
2129 buff[cnt + channelMap[0]] = Clamp8((l[yPos] + yuvOffset16) >> shift);
2130 buff[cnt + channelMap[1]] = Clamp8((uAvg + yuvOffset16) >> shift);
2131 buff[cnt + channelMap[2]] = Clamp8((vAvg + yuvOffset16) >> shift);
2134 if (j%2) sampledPos++;
2137 if (wOdd) sampledPos++;
2141 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2150 ASSERT(m_header.channels == 4);
2151 ASSERT(m_header.bpp == m_header.channels*8);
2154 DataT* y = m_channel[0]; ASSERT(y);
2155 DataT* u = m_channel[1]; ASSERT(u);
2156 DataT* v = m_channel[2]; ASSERT(v);
2157 DataT* a = m_channel[3]; ASSERT(a);
2159 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
2161 for (i=0; i < h; i++) {
2162 if (i%2) sampledPos -= (w + 1)/2;
2164 for (j=0; j < w; j++) {
2167 uAvg = u[sampledPos];
2168 vAvg = v[sampledPos];
2176 buff[cnt + channelMap[1]] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
2177 buff[cnt + channelMap[2]] = Clamp8(uAvg + g);
2178 buff[cnt + channelMap[0]] = Clamp8(vAvg + g);
2179 buff[cnt + channelMap[3]] = aAvg;
2182 if (j%2) sampledPos++;
2185 if (wOdd) sampledPos++;
2189 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2196 ASSERT(m_header.channels == 4);
2197 ASSERT(m_header.bpp == 64);
2199 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2201 DataT* y = m_channel[0]; ASSERT(y);
2202 DataT* u = m_channel[1]; ASSERT(u);
2203 DataT* v = m_channel[2]; ASSERT(v);
2204 DataT* a = m_channel[3]; ASSERT(a);
2209 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2210 UINT16 *buff16 = (UINT16 *)buff;
2211 int pitch16 = pitch/2;
2212 channels = bpp/16; ASSERT(channels >= m_header.channels);
2214 for (i=0; i < h; i++) {
2215 if (i%2) sampledPos -= (w + 1)/2;
2217 for (j=0; j < w; j++) {
2220 uAvg = u[sampledPos];
2221 vAvg = v[sampledPos];
2222 aAvg = a[sampledPos] + yuvOffset16;
2226 aAvg = a[yPos] + yuvOffset16;
2229 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
2230 buff16[cnt + channelMap[1]] = Clamp16(g << shift);
2231 buff16[cnt + channelMap[2]] = Clamp16((uAvg + g) << shift);
2232 buff16[cnt + channelMap[0]] = Clamp16((vAvg + g) << shift);
2233 buff16[cnt + channelMap[3]] = Clamp16(aAvg << shift);
2236 if (j%2) sampledPos++;
2239 if (wOdd) sampledPos++;
2243 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2248 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2249 channels = bpp/8; ASSERT(channels >= m_header.channels);
2251 for (i=0; i < h; i++) {
2252 if (i%2) sampledPos -= (w + 1)/2;
2254 for (j=0; j < w; j++) {
2257 uAvg = u[sampledPos];
2258 vAvg = v[sampledPos];
2259 aAvg = a[sampledPos] + yuvOffset16;
2263 aAvg = a[yPos] + yuvOffset16;
2266 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
2267 buff[cnt + channelMap[1]] = Clamp8(g >> shift);
2268 buff[cnt + channelMap[2]] = Clamp8((uAvg + g) >> shift);
2269 buff[cnt + channelMap[0]] = Clamp8((vAvg + g) >> shift);
2270 buff[cnt + channelMap[3]] = Clamp8(aAvg >> shift);
2273 if (j%2) sampledPos++;
2276 if (wOdd) sampledPos++;
2280 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2286#ifdef __PGF32SUPPORT__
2289 ASSERT(m_header.channels == 1);
2290 ASSERT(m_header.bpp == 32);
2292 const int yuvOffset31 = 1 << (UsedBitsPerChannel() - 1);
2294 DataT* y = m_channel[0]; ASSERT(y);
2297 const int shift = 31 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2298 UINT32 *buff32 = (UINT32 *)buff;
2299 int pitch32 = pitch/4;
2301 for (i=0; i < h; i++) {
2302 for (j=0; j < w; j++) {
2303 buff32[j] = Clamp31((y[yPos++] + yuvOffset31) << shift);
2309 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2312 }
else if (bpp == 16) {
2313 const int usedBits = UsedBitsPerChannel();
2314 UINT16 *buff16 = (UINT16 *)buff;
2315 int pitch16 = pitch/2;
2317 if (usedBits < 16) {
2318 const int shift = 16 - usedBits;
2319 for (i=0; i < h; i++) {
2320 for (j=0; j < w; j++) {
2321 buff16[j] = Clamp16((y[yPos++] + yuvOffset31) << shift);
2327 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2331 const int shift =
__max(0, usedBits - 16);
2332 for (i=0; i < h; i++) {
2333 for (j=0; j < w; j++) {
2334 buff16[j] = Clamp16((y[yPos++] + yuvOffset31) >> shift);
2340 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2346 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2348 for (i=0; i < h; i++) {
2349 for (j=0; j < w; j++) {
2350 buff[j] = Clamp8((y[yPos++] + yuvOffset31) >> shift);
2356 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2365 ASSERT(m_header.channels == 3);
2366 ASSERT(m_header.bpp == m_header.channels*4);
2367 ASSERT(bpp == m_header.channels*4);
2368 ASSERT(!m_downsample);
2370 DataT* y = m_channel[0]; ASSERT(y);
2371 DataT* u = m_channel[1]; ASSERT(u);
2372 DataT* v = m_channel[2]; ASSERT(v);
2376 for (i=0; i < h; i++) {
2378 for (j=0; j < w; j++) {
2382 yval = Clamp4(y[yPos++] +
YUVoffset4 - ((uAvg + vAvg ) >> 2));
2384 buff[cnt] = UINT8(Clamp4(vAvg + yval) | (yval << 4));
2386 buff[cnt] = Clamp4(uAvg + yval);
2388 buff[cnt] |= Clamp4(vAvg + yval) << 4;
2390 buff[cnt] = UINT8(yval | (Clamp4(uAvg + yval) << 4));
2398 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2405 ASSERT(m_header.channels == 3);
2406 ASSERT(m_header.bpp == 16);
2408 ASSERT(!m_downsample);
2410 DataT* y = m_channel[0]; ASSERT(y);
2411 DataT* u = m_channel[1]; ASSERT(u);
2412 DataT* v = m_channel[2]; ASSERT(v);
2414 UINT16 *buff16 = (UINT16 *)buff;
2415 int pitch16 = pitch/2;
2417 for (i=0; i < h; i++) {
2418 for (j=0; j < w; j++) {
2422 yval = Clamp6(y[yPos++] +
YUVoffset6 - ((uAvg + vAvg ) >> 2));
2423 buff16[j] = (yval << 5) | ((Clamp6(uAvg + yval) >> 1) << 11) | (Clamp6(vAvg + yval) >> 1);
2429 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2438#ifdef __PGFROISUPPORT__
2443 buff = buffStart + (levelRoi.
top - roi.
top)*pitch + (levelRoi.
left - roi.
left)*bypp;
2444 w = levelRoi.
Width()*bypp;
2447 for (i=0; i < h; i++) {
2448 for (j=0; j < w; j++) {
2449 targetBuff[j] = buff[j];
2451 targetBuff += targetPitch;
2458 delete[] buffStart; buffStart = 0;
2479 const UINT32 w = m_width[0];
2480 const UINT32 h = m_height[0];
2481 const bool wOdd = (1 == w%2);
2482 const int dataBits =
DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2485 const double dP = 1.0/h;
2487 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
2488 if (channelMap == NULL) channelMap = defMap;
2489 int sampledPos = 0, yPos = 0;
2494 if (m_header.channels == 3) {
2495 ASSERT(bpp%dataBits == 0);
2497 DataT* y = m_channel[0]; ASSERT(y);
2498 DataT* u = m_channel[1]; ASSERT(u);
2499 DataT* v = m_channel[2]; ASSERT(v);
2500 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2502 for (i=0; i < h; i++) {
2503 if (i%2) sampledPos -= (w + 1)/2;
2505 for (j=0; j < w; j++) {
2508 uAvg = u[sampledPos];
2509 vAvg = v[sampledPos];
2514 buff[cnt + channelMap[0]] = y[yPos];
2515 buff[cnt + channelMap[1]] = uAvg;
2516 buff[cnt + channelMap[2]] = vAvg;
2519 if (j%2) sampledPos++;
2522 if (wOdd) sampledPos++;
2526 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2529 }
else if (m_header.channels == 4) {
2530 ASSERT(m_header.bpp == m_header.channels*8);
2531 ASSERT(bpp%dataBits == 0);
2533 DataT* y = m_channel[0]; ASSERT(y);
2534 DataT* u = m_channel[1]; ASSERT(u);
2535 DataT* v = m_channel[2]; ASSERT(v);
2536 DataT* a = m_channel[3]; ASSERT(a);
2538 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2540 for (i=0; i < h; i++) {
2541 if (i%2) sampledPos -= (w + 1)/2;
2543 for (j=0; j < w; j++) {
2546 uAvg = u[sampledPos];
2547 vAvg = v[sampledPos];
2548 aAvg = Clamp8(a[sampledPos] + yuvOffset);
2552 aAvg = Clamp8(a[yPos] + yuvOffset);
2555 buff[cnt + channelMap[0]] = y[yPos];
2556 buff[cnt + channelMap[1]] = uAvg;
2557 buff[cnt + channelMap[2]] = vAvg;
2558 buff[cnt + channelMap[3]] = aAvg;
2561 if (j%2) sampledPos++;
2564 if (wOdd) sampledPos++;
2568 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2590 const double dP = 1.0/m_header.height;
2591 const int dataBits =
DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2595 int yPos = 0, cnt = 0;
2597 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
2599 if (channelMap == NULL) channelMap = defMap;
2601 if (m_header.channels == 3) {
2602 ASSERT(bpp%dataBits == 0);
2604 DataT* y = m_channel[0]; ASSERT(y);
2605 DataT* u = m_channel[1]; ASSERT(u);
2606 DataT* v = m_channel[2]; ASSERT(v);
2607 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2609 for (UINT32 h=0; h < m_header.height; h++) {
2611 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2616 for (UINT32 w=0; w < m_header.width; w++) {
2617 y[yPos] = buff[cnt + channelMap[0]];
2618 u[yPos] = buff[cnt + channelMap[1]];
2619 v[yPos] = buff[cnt + channelMap[2]];
2625 }
else if (m_header.channels == 4) {
2626 ASSERT(bpp%dataBits == 0);
2628 DataT* y = m_channel[0]; ASSERT(y);
2629 DataT* u = m_channel[1]; ASSERT(u);
2630 DataT* v = m_channel[2]; ASSERT(v);
2631 DataT* a = m_channel[3]; ASSERT(a);
2632 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2634 for (UINT32 h=0; h < m_header.height; h++) {
2636 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2641 for (UINT32 w=0; w < m_header.width; w++) {
2642 y[yPos] = buff[cnt + channelMap[0]];
2643 u[yPos] = buff[cnt + channelMap[1]];
2644 v[yPos] = buff[cnt + channelMap[2]];
2645 a[yPos] = buff[cnt + channelMap[3]] - yuvOffset;
2655 for (
int i=1; i < m_header.channels; i++) {
UINT32 AlignWordPos(UINT32 pos)
#define MaxLevel
maximum number of transform levels
#define PGFMagic
PGF identification.
#define MaxQuality
maximum quality
#define MaxChannels
maximum number of (color) channels
#define Version5
new coding scheme since major version 5
#define ColorTableLen
size of color lookup table (clut)
#define Version2
data structure PGFHeader of major version 2
#define Version6
new HeaderSize: 32 bits instead of 16 bits
#define PGFVersion
current standard version
#define DownsampleThreshold
if quality is larger than this threshold than downsampling is used
void SetStreamPosToStart() THROW_
Reset stream position to beginning of PGF pre-header.
UINT32 GetEncodedHeaderLength() const
INT64 ComputeOffset() const
UINT32 WriteLevelLength(UINT32 *&levelLength) THROW_
void SetEncodedLevel(int currentLevel)
void UpdatePostHeaderSize(PGFPreHeader preHeader) THROW_
void SetColorTable(UINT32 iFirstColor, UINT32 nColors, const RGBQUAD *prgbColors) THROW_
UINT32 WriteImage(CPGFStream *stream, CallbackPtr cb=NULL, void *data=NULL) THROW_
CDecoder * m_decoder
PGF decoder.
void RgbToYuv(int pitch, UINT8 *rgbBuff, BYTE bpp, int channelMap[], CallbackPtr cb, void *data) THROW_
void SetHeader(const PGFHeader &header, BYTE flags=0, UINT8 *userData=0, UINT32 userDataLength=0) THROW_
UINT32 * m_levelLength
length of each level in bytes; first level starts immediately after this array
UINT32 m_height[MaxChannels]
height of each channel at current level
PGFHeader m_header
PGF file header.
virtual ~CPGFImage()
Destructor: Destroy internal data structures.
void Downsample(int nChannel)
UINT32 UpdatePostHeaderSize() THROW_
int m_currentLevel
transform level of current image
UINT32 ReadEncodedHeader(UINT8 *target, UINT32 targetLen) const THROW_
DataT * m_channel[MaxChannels]
untransformed channels in YUV format
void Write(CPGFStream *stream, UINT32 *nWrittenBytes=NULL, CallbackPtr cb=NULL, void *data=NULL) THROW_
static BYTE CurrentVersion(BYTE version=PGFVersion)
Return version.
UINT32 WriteHeader(CPGFStream *stream) THROW_
const UINT8 * GetUserData(UINT32 &size) const
static bool ImportIsSupported(BYTE mode)
void SetMaxValue(UINT32 maxValue)
BYTE UsedBitsPerChannel() const
CEncoder * m_encoder
PGF encoder.
PGFRect m_roi
region of interest
void SetROI(PGFRect rect)
void Read(int level=0, CallbackPtr cb=NULL, void *data=NULL) THROW_
bool m_downsample
chrominance channels are downsampled
bool ROIisSupported() const
void ResetStreamPos() THROW_
Reset stream position to start of PGF pre-header.
void Open(CPGFStream *stream) THROW_
void Reconstruct(int level=0) THROW_
UINT32 m_width[MaxChannels]
width of each channel at current level
PGFPostHeader m_postHeader
PGF post-header.
void GetYUV(int pitch, DataT *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) const THROW_
const RGBQUAD * GetColorTable() const
UINT64 m_userDataPos
stream position of user data
UINT32 GetEncodedHeaderLength() const
PGFPreHeader m_preHeader
PGF pre-header.
double m_percent
progress [0..1]
void ImportYUV(int pitch, DataT *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) THROW_
CWaveletTransform * m_wtChannel[MaxChannels]
wavelet transformed color channels
CPGFImage()
Standard constructor: It is used to create a PGF instance for opening and reading.
void ImportBitmap(int pitch, UINT8 *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) THROW_
UINT32 ReadEncodedData(int level, UINT8 *target, UINT32 targetLen) const THROW_
void GetBitmap(int pitch, UINT8 *buff, BYTE bpp, int channelMap[]=NULL, CallbackPtr cb=NULL, void *data=NULL) const THROW_
Abstract stream base class.
void ExtractTile(CEncoder &encoder, bool tile=false, UINT32 tileX=0, UINT32 tileY=0) THROW_
char magic[3]
PGF identification = "PGF".
UINT8 version
PGF version.
bool IsInside(UINT32 x, UINT32 y) const