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;
148 if (!CompleteHeader()) ReturnWithError(FormatCannotRead);
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;
334 if (m_header.nLevels == 0) {
337 for (
int i=0; i < m_header.channels; i++) {
338 ASSERT(m_wtChannel[i]);
339 m_channel[i] = m_wtChannel[i]->GetSubband(0,
LL)->GetBuffer();
343 int currentLevel = m_header.nLevels;
345 if (ROIisSupported()) {
347 SetROI(
PGFRect(0, 0, m_header.width, m_header.height));
350 while (currentLevel > level) {
351 for (
int i=0; i < m_header.channels; i++) {
352 ASSERT(m_wtChannel[i]);
354 if (currentLevel == m_header.nLevels) {
356 m_wtChannel[i]->GetSubband(currentLevel,
LL)->Dequantize(m_quant);
358 m_wtChannel[i]->GetSubband(currentLevel,
HL)->Dequantize(m_quant);
359 m_wtChannel[i]->GetSubband(currentLevel,
LH)->Dequantize(m_quant);
360 m_wtChannel[i]->GetSubband(currentLevel,
HH)->Dequantize(m_quant);
363 OSError err = m_wtChannel[i]->InverseTransform(currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
364 if (err != NoError) ReturnWithError(err);
365 ASSERT(m_channel[i]);
386 ASSERT((level >= 0 && level < m_header.nLevels) || m_header.nLevels == 0);
389#ifdef __PGFROISUPPORT__
390 if (ROIisSupported() && m_header.nLevels > 0) {
392 PGFRect rect(0, 0, m_header.width, m_header.height);
393 Read(rect, level, cb, data);
398 if (m_header.nLevels == 0) {
403 if ((*cb)(1.0,
true, data)) ReturnWithError(EscapePressed);
407 const int levelDiff = m_currentLevel - level;
408 double percent = (m_progressMode ==
PM_Relative) ? pow(0.25, levelDiff) : m_percent;
411 while (m_currentLevel > level) {
412 for (
int i=0; i < m_header.channels; i++) {
413 ASSERT(m_wtChannel[i]);
415 if (m_currentLevel == m_header.nLevels) {
417 m_wtChannel[i]->GetSubband(m_currentLevel,
LL)->PlaceTile(*m_decoder, m_quant);
419 if (m_preHeader.version &
Version5) {
421 m_wtChannel[i]->GetSubband(m_currentLevel,
HL)->PlaceTile(*m_decoder, m_quant);
422 m_wtChannel[i]->GetSubband(m_currentLevel,
LH)->PlaceTile(*m_decoder, m_quant);
425 m_decoder->DecodeInterleaved(m_wtChannel[i], m_currentLevel, m_quant);
427 m_wtChannel[i]->GetSubband(m_currentLevel,
HH)->PlaceTile(*m_decoder, m_quant);
430 volatile OSError error = NoError;
431#ifdef LIBPGF_USE_OPENMP
432 #pragma omp parallel for default(shared)
434 for (
int i=0; i < m_header.channels; i++) {
436 if (error == NoError) {
437 OSError err = m_wtChannel[i]->InverseTransform(m_currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
438 if (err != NoError) error = err;
440 ASSERT(m_channel[i]);
442 if (error != NoError) ReturnWithError(error);
448 if (m_cb) m_cb(m_cbArg);
453 if (m_progressMode ==
PM_Absolute) m_percent = percent;
454 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
460 if (m_currentLevel == 0) Close();
463#ifdef __PGFROISUPPORT__
474 ASSERT((level >= 0 && level < m_header.nLevels) || m_header.nLevels == 0);
477 if (m_header.nLevels == 0 || !ROIisSupported()) {
478 rect.left = rect.top = 0;
479 rect.right = m_header.width; rect.bottom = m_header.height;
480 Read(level, cb, data);
482 ASSERT(ROIisSupported());
484 ASSERT(rect.left < m_header.width && rect.top < m_header.height);
486 const int levelDiff = m_currentLevel - level;
487 double percent = (m_progressMode ==
PM_Relative) ? pow(0.25, levelDiff) : m_percent;
490 if (levelDiff <= 0) {
492 m_currentLevel = m_header.nLevels;
493 m_decoder->SetStreamPosToData();
497 if (rect.right == 0 || rect.right > m_header.width) rect.right = m_header.width;
498 if (rect.bottom == 0 || rect.bottom > m_header.height) rect.bottom = m_header.height;
503 while (m_currentLevel > level) {
504 for (
int i=0; i < m_header.channels; i++) {
505 ASSERT(m_wtChannel[i]);
508 const UINT32 nTiles = m_wtChannel[i]->GetNofTiles(m_currentLevel);
509 const PGFRect& tileIndices = m_wtChannel[i]->GetTileIndices(m_currentLevel);
512 if (m_currentLevel == m_header.nLevels) {
514 m_decoder->DecodeTileBuffer();
515 m_wtChannel[i]->GetSubband(m_currentLevel,
LL)->PlaceTile(*m_decoder, m_quant);
517 for (UINT32 tileY=0; tileY < nTiles; tileY++) {
518 for (UINT32 tileX=0; tileX < nTiles; tileX++) {
520 if (tileIndices.
IsInside(tileX, tileY)) {
521 m_decoder->DecodeTileBuffer();
522 m_wtChannel[i]->GetSubband(m_currentLevel,
HL)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
523 m_wtChannel[i]->GetSubband(m_currentLevel,
LH)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
524 m_wtChannel[i]->GetSubband(m_currentLevel,
HH)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
527 m_decoder->SkipTileBuffer();
533 volatile OSError error = NoError;
534#ifdef LIBPGF_USE_OPENMP
535 #pragma omp parallel for default(shared)
537 for (
int i=0; i < m_header.channels; i++) {
539 if (error == NoError) {
540 OSError err = m_wtChannel[i]->InverseTransform(m_currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
541 if (err != NoError) error = err;
543 ASSERT(m_channel[i]);
545 if (error != NoError) ReturnWithError(error);
551 if (m_cb) m_cb(m_cbArg);
556 if (m_progressMode ==
PM_Absolute) m_percent = percent;
557 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
563 if (m_currentLevel == 0) Close();
584 else rect.
left -= dx;
585 if (rect.
top < dy) rect.
top = 0;
628 ASSERT(targetLen > 0);
632 m_decoder->SetStreamPosToStart();
635 UINT32 len =
__min(targetLen, GetEncodedHeaderLength());
638 len = m_decoder->ReadEncodedData(target, len);
639 ASSERT(len >= 0 && len <= targetLen);
661 ASSERT(level >= 0 && level < m_header.nLevels);
663 ASSERT(targetLen > 0);
667 m_decoder->SetStreamPosToData();
672 for (
int i=m_header.nLevels - 1; i > level; i--) {
673 offset += m_levelLength[m_header.nLevels - 1 - i];
675 m_decoder->Skip(offset);
678 UINT32 len =
__min(targetLen, GetEncodedLevelLength(level));
681 len = m_decoder->ReadEncodedData(target, len);
682 ASSERT(len >= 0 && len <= targetLen);
695 while(maxValue > 0) {
700 if (pot > bpc) pot = bpc;
701 if (pot > 31) pot = 31;
746 ASSERT(m_channel[0]);
749 RgbToYuv(pitch, buff, bpp, channelMap, cb, data);
753 for (
int i=1; i < m_header.channels; i++) {
767 const int oddW = w%2;
774 for (
int i=0; i < h2; i++) {
775 for (
int j=0; j < w2; j++) {
777 buff[sampledPos] = (buff[loPos] + buff[loPos + 1] + buff[hiPos] + buff[hiPos + 1]) >> 2;
778 loPos += 2; hiPos += 2;
782 buff[sampledPos] = (buff[loPos] + buff[hiPos]) >> 1;
786 loPos += w; hiPos += w;
789 for (
int j=0; j < w2; j++) {
790 buff[sampledPos] = (buff[loPos] + buff[loPos+1]) >> 1;
791 loPos += 2; hiPos += 2;
795 buff[sampledPos] = buff[loPos];
813 while (s > maxThumbnailWidth) {
850#ifdef __PGFROISUPPORT__
851 m_streamReinitialized =
false;
855 memcpy(m_preHeader.magic,
PGFMagic, 3);
877 m_quant = m_header.quality - 1;
879 m_downsample =
false;
880 m_quant = m_header.quality;
888 if (userDataLength && userData) {
889 m_postHeader.userData =
new(std::nothrow) UINT8[userDataLength];
890 if (!m_postHeader.userData) ReturnWithError(InsufficientMemory);
891 m_postHeader.userDataLen = userDataLength;
892 memcpy(m_postHeader.userData, userData, userDataLength);
894 m_preHeader.hSize += userDataLength;
898 for (
int i=0; i < m_header.channels; i++) {
900 m_width[i] = m_header.width;
901 m_height[i] = m_header.height;
904 ASSERT(!m_channel[i]);
905 m_channel[i] =
new(std::nothrow)
DataT[m_header.width*m_header.height];
909 delete[] m_channel[i]; m_channel[i] = 0;
912 ReturnWithError(InsufficientMemory);
925 ASSERT(m_header.nLevels <=
MaxLevel);
928 if (m_header.nLevels > 0) {
929 volatile OSError error = NoError;
931#ifdef LIBPGF_USE_OPENMP
932 #pragma omp parallel for default(shared)
934 for (
int i=0; i < m_header.channels; i++) {
936 if (error == NoError) {
937 if (m_wtChannel[i]) {
938 ASSERT(m_channel[i]);
940 int size = m_height[i]*m_width[i];
941 temp =
new(std::nothrow)
DataT[size];
943 memcpy(temp, m_channel[i], size*
DataTSize);
944 delete m_wtChannel[i];
947 error = InsufficientMemory;
950 if (error == NoError) {
952 ASSERT(!m_channel[i]);
955 m_wtChannel[i] =
new CWaveletTransform(m_width[i], m_height[i], m_header.nLevels, m_channel[i]);
956 if (m_wtChannel[i]) {
957 #ifdef __PGFROISUPPORT__
958 m_wtChannel[i]->SetROI(
PGFRect(0, 0, m_width[i], m_height[i]));
962 for (
int l=0; error == NoError && l < m_header.nLevels; l++) {
963 OSError err = m_wtChannel[i]->ForwardTransform(l, m_quant);
964 if (err != NoError) error = err;
967 delete[] m_channel[i];
968 error = InsufficientMemory;
973 if (error != NoError) {
975 for (
int i=0; i < m_header.channels; i++) {
976 delete m_wtChannel[i];
978 ReturnWithError(error);
981 m_currentLevel = m_header.nLevels;
984 m_encoder =
new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_userDataPos, m_useOMPinEncoder);
985 if (m_favorSpeedOverSize) m_encoder->FavorSpeedOverSize();
987 #ifdef __PGFROISUPPORT__
988 if (ROIisSupported()) {
998 m_encoder =
new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_userDataPos, m_useOMPinEncoder);
1001 INT64 nBytes = m_encoder->ComputeHeaderLength();
1002 return (nBytes > 0) ? (UINT32)nBytes : 0;
1018#ifdef __PGFROISUPPORT__
1025 const UINT32 lastTile = nTiles - 1;
1029 ASSERT(nTiles == 1);
1033 for (UINT32 tileY=0; tileY < nTiles; tileY++) {
1034 for (UINT32 tileX=0; tileX < nTiles; tileX++) {
1038 if (i == lastChannel && tileY == lastTile && tileX == lastTile) {
1095 ASSERT(m_preHeader.hSize);
1097 int levels = m_header.nLevels;
1098 double percent = pow(0.25, levels);
1101 UINT32 nWrittenBytes = UpdatePostHeaderSize();
1105 for (
int c=0; c < m_header.channels; c++) {
1106 const UINT32 size = m_width[c]*m_height[c];
1109 for (UINT32 i=0; i < size; i++) {
1111 stream->Write(&count, &m_channel[c][i]);
1117 if ((*cb)(1,
true, data)) ReturnWithError(EscapePressed);
1126 for (m_currentLevel = levels; m_currentLevel > 0; ) {
1132 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1141 nWrittenBytes += m_encoder->UpdateLevelLength();
1144 delete m_encoder; m_encoder = NULL;
1148 return nWrittenBytes;
1166 ASSERT(m_preHeader.hSize);
1169 UINT32 nBytes = WriteHeader(stream);
1172 nBytes += WriteImage(stream, cb, data);
1175 if (nWrittenBytes) *nWrittenBytes += nBytes;
1178#ifdef __PGFROISUPPORT__
1194 ASSERT(m_header.nLevels > 0);
1195 ASSERT(0 <= level && level < m_header.nLevels);
1197 ASSERT(ROIisSupported());
1199 const int levelDiff = m_currentLevel - level;
1200 double percent = (m_progressMode ==
PM_Relative) ? pow(0.25, levelDiff) : m_percent;
1201 UINT32 nWrittenBytes = 0;
1203 if (m_currentLevel == m_header.nLevels) {
1205 nWrittenBytes = UpdatePostHeaderSize();
1208 if (m_encoder->ComputeBufferLength()) {
1209 m_streamReinitialized =
true;
1214 while (m_currentLevel > level) {
1217 if (m_levelLength) {
1218 nWrittenBytes += m_levelLength[m_header.nLevels - m_currentLevel - 1];
1224 if (m_progressMode ==
PM_Absolute) m_percent = percent;
1225 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1230 if (m_currentLevel == 0) {
1231 if (!m_streamReinitialized) {
1233 m_encoder->UpdateLevelLength();
1236 delete m_encoder; m_encoder = NULL;
1239 return nWrittenBytes;
1294 if (iFirstColor + nColors >
ColorTableLen) ReturnWithError(ColorTableError);
1296 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1297 prgbColors[j] = m_postHeader.clut[i];
1308 if (iFirstColor + nColors >
ColorTableLen) ReturnWithError(ColorTableError);
1310 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1311 m_postHeader.clut[i] = prgbColors[j];
1332void CPGFImage::RgbToYuv(
int pitch, UINT8* buff, BYTE bpp,
int channelMap[], CallbackPtr cb,
void *data ) THROW_ {
1334 int yPos = 0, cnt = 0;
1336 const double dP = 1.0/m_header.height;
1337 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
1339 if (channelMap == NULL) channelMap = defMap;
1341 switch(m_header.mode) {
1344 ASSERT(m_header.channels == 1);
1345 ASSERT(m_header.bpp == 1);
1348 const UINT32 w = m_header.width;
1349 const UINT32 w2 = (m_header.width + 7)/8;
1350 DataT* y = m_channel[0]; ASSERT(y);
1352 for (UINT32 h=0; h < m_header.height; h++) {
1354 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1358 for (UINT32 j=0; j < w2; j++) {
1361 for (UINT32 j=w2; j < w; j++) {
1384 ASSERT(m_header.channels >= 1);
1385 ASSERT(m_header.bpp == m_header.channels*8);
1387 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1389 for (UINT32 h=0; h < m_header.height; h++) {
1391 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1396 for (UINT32 w=0; w < m_header.width; w++) {
1397 for (
int c=0; c < m_header.channels; c++) {
1398 m_channel[c][yPos] = buff[cnt + channelMap[c]] -
YUVoffset8;
1410 ASSERT(m_header.channels >= 1);
1411 ASSERT(m_header.bpp == m_header.channels*16);
1412 ASSERT(bpp%16 == 0);
1414 UINT16 *buff16 = (UINT16 *)buff;
1415 const int pitch16 = pitch/2;
1416 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1417 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1418 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1420 for (UINT32 h=0; h < m_header.height; h++) {
1422 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1427 for (UINT32 w=0; w < m_header.width; w++) {
1428 for (
int c=0; c < m_header.channels; c++) {
1429 m_channel[c][yPos] = (buff16[cnt + channelMap[c]] >> shift) - yuvOffset16;
1440 ASSERT(m_header.channels == 3);
1441 ASSERT(m_header.bpp == m_header.channels*8);
1444 DataT* y = m_channel[0]; ASSERT(y);
1445 DataT* u = m_channel[1]; ASSERT(u);
1446 DataT* v = m_channel[2]; ASSERT(v);
1447 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1450 for (UINT32 h=0; h < m_header.height; h++) {
1452 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1457 for (UINT32 w=0; w < m_header.width; w++) {
1458 b = buff[cnt + channelMap[0]];
1459 g = buff[cnt + channelMap[1]];
1460 r = buff[cnt + channelMap[2]];
1462 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset8;
1474 ASSERT(m_header.channels == 3);
1475 ASSERT(m_header.bpp == m_header.channels*16);
1476 ASSERT(bpp%16 == 0);
1478 UINT16 *buff16 = (UINT16 *)buff;
1479 const int pitch16 = pitch/2;
1480 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1481 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1482 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1484 DataT* y = m_channel[0]; ASSERT(y);
1485 DataT* u = m_channel[1]; ASSERT(u);
1486 DataT* v = m_channel[2]; ASSERT(v);
1489 for (UINT32 h=0; h < m_header.height; h++) {
1491 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1496 for (UINT32 w=0; w < m_header.width; w++) {
1497 b = buff16[cnt + channelMap[0]] >> shift;
1498 g = buff16[cnt + channelMap[1]] >> shift;
1499 r = buff16[cnt + channelMap[2]] >> shift;
1501 y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1514 ASSERT(m_header.channels == 4);
1515 ASSERT(m_header.bpp == m_header.channels*8);
1517 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1519 DataT* y = m_channel[0]; ASSERT(y);
1520 DataT* u = m_channel[1]; ASSERT(u);
1521 DataT* v = m_channel[2]; ASSERT(v);
1522 DataT* a = m_channel[3]; ASSERT(a);
1525 for (UINT32 h=0; h < m_header.height; h++) {
1527 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1532 for (UINT32 w=0; w < m_header.width; w++) {
1533 b = buff[cnt + channelMap[0]];
1534 g = buff[cnt + channelMap[1]];
1535 r = buff[cnt + channelMap[2]];
1537 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset8;
1540 a[yPos++] = buff[cnt + channelMap[3]] -
YUVoffset8;
1549 ASSERT(m_header.channels == 4);
1550 ASSERT(m_header.bpp == m_header.channels*16);
1551 ASSERT(bpp%16 == 0);
1553 UINT16 *buff16 = (UINT16 *)buff;
1554 const int pitch16 = pitch/2;
1555 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1556 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1557 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1559 DataT* y = m_channel[0]; ASSERT(y);
1560 DataT* u = m_channel[1]; ASSERT(u);
1561 DataT* v = m_channel[2]; ASSERT(v);
1562 DataT* a = m_channel[3]; ASSERT(a);
1565 for (UINT32 h=0; h < m_header.height; h++) {
1567 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1572 for (UINT32 w=0; w < m_header.width; w++) {
1573 b = buff16[cnt + channelMap[0]] >> shift;
1574 g = buff16[cnt + channelMap[1]] >> shift;
1575 r = buff16[cnt + channelMap[2]] >> shift;
1577 y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1580 a[yPos++] = (buff16[cnt + channelMap[3]] >> shift) - yuvOffset16;
1587#ifdef __PGF32SUPPORT__
1590 ASSERT(m_header.channels == 1);
1591 ASSERT(m_header.bpp == 32);
1595 DataT* y = m_channel[0]; ASSERT(y);
1597 UINT32 *buff32 = (UINT32 *)buff;
1598 const int pitch32 = pitch/4;
1599 const int shift = 31 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1600 const DataT yuvOffset31 = 1 << (UsedBitsPerChannel() - 1);
1602 for (UINT32 h=0; h < m_header.height; h++) {
1604 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1608 for (UINT32 w=0; w < m_header.width; w++) {
1609 y[yPos++] = (buff32[w] >> shift) - yuvOffset31;
1618 ASSERT(m_header.channels == 3);
1619 ASSERT(m_header.bpp == m_header.channels*4);
1620 ASSERT(bpp == m_header.channels*4);
1622 DataT* y = m_channel[0]; ASSERT(y);
1623 DataT* u = m_channel[1]; ASSERT(u);
1624 DataT* v = m_channel[2]; ASSERT(v);
1626 UINT8 rgb = 0, b, g, r;
1628 for (UINT32 h=0; h < m_header.height; h++) {
1630 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1635 for (UINT32 w=0; w < m_header.width; w++) {
1640 g = (rgb & 0xF0) >> 4;
1646 b = (rgb & 0xF0) >> 4;
1650 r = (rgb & 0xF0) >> 4;
1655 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset4;
1666 ASSERT(m_header.channels == 3);
1667 ASSERT(m_header.bpp == 16);
1670 DataT* y = m_channel[0]; ASSERT(y);
1671 DataT* u = m_channel[1]; ASSERT(u);
1672 DataT* v = m_channel[2]; ASSERT(v);
1674 UINT16 *buff16 = (UINT16 *)buff;
1675 UINT16 rgb, b, g, r;
1676 const int pitch16 = pitch/2;
1678 for (UINT32 h=0; h < m_header.height; h++) {
1680 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1683 for (UINT32 w=0; w < m_header.width; w++) {
1685 r = (rgb & 0xF800) >> 10;
1686 g = (rgb & 0x07E0) >> 5;
1687 b = (rgb & 0x001F) << 1;
1689 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset6;
1721void CPGFImage::GetBitmap(
int pitch, UINT8* buff, BYTE bpp,
int channelMap[] , CallbackPtr cb ,
void *data )
const THROW_ {
1723 UINT32 w = m_width[0];
1724 UINT32 h = m_height[0];
1725 UINT8* targetBuff = 0;
1726 UINT8* buffStart = 0;
1727 int targetPitch = 0;
1729#ifdef __PGFROISUPPORT__
1730 const PGFRect& roi = (ROIisSupported()) ? m_wtChannel[0]->GetROI(m_currentLevel) :
PGFRect(0, 0, w, h);
1731 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));
1736 if (ROIisSupported() && (levelRoi.
Width() < w || levelRoi.
Height() < h)) {
1739 targetPitch = pitch;
1744 buff = buffStart =
new(std::nothrow) UINT8[pitch*h];
1745 if (!buff) ReturnWithError(InsufficientMemory);
1749 const bool wOdd = (1 == w%2);
1751 const double dP = 1.0/h;
1752 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
1753 if (channelMap == NULL) channelMap = defMap;
1754 int sampledPos = 0, yPos = 0;
1759 switch(m_header.mode) {
1762 ASSERT(m_header.channels == 1);
1763 ASSERT(m_header.bpp == 1);
1766 const UINT32 w2 = (w + 7)/8;
1767 DataT* y = m_channel[0]; ASSERT(y);
1769 for (i=0; i < h; i++) {
1771 for (j=0; j < w2; j++) {
1791 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1801 ASSERT(m_header.channels >= 1);
1802 ASSERT(m_header.bpp == m_header.channels*8);
1805 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
1807 for (i=0; i < h; i++) {
1809 for (j=0; j < w; j++) {
1810 for (
int c=0; c < m_header.channels; c++) {
1811 buff[cnt + channelMap[c]] = Clamp8(m_channel[c][yPos] +
YUVoffset8);
1820 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1827 ASSERT(m_header.channels >= 1);
1828 ASSERT(m_header.bpp == m_header.channels*16);
1830 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1834 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1835 UINT16 *buff16 = (UINT16 *)buff;
1836 int pitch16 = pitch/2;
1837 channels = bpp/16; ASSERT(channels >= m_header.channels);
1839 for (i=0; i < h; i++) {
1841 for (j=0; j < w; j++) {
1842 for (
int c=0; c < m_header.channels; c++) {
1843 buff16[cnt + channelMap[c]] = Clamp16((m_channel[c][yPos] + yuvOffset16) << shift);
1852 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1857 const int shift =
__max(0, UsedBitsPerChannel() - 8);
1858 channels = bpp/8; ASSERT(channels >= m_header.channels);
1860 for (i=0; i < h; i++) {
1862 for (j=0; j < w; j++) {
1863 for (
int c=0; c < m_header.channels; c++) {
1864 buff[cnt + channelMap[c]] = Clamp8((m_channel[c][yPos] + yuvOffset16) >> shift);
1873 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1881 ASSERT(m_header.channels == 3);
1882 ASSERT(m_header.bpp == m_header.channels*8);
1884 ASSERT(bpp >= m_header.bpp);
1886 DataT* y = m_channel[0]; ASSERT(y);
1887 DataT* u = m_channel[1]; ASSERT(u);
1888 DataT* v = m_channel[2]; ASSERT(v);
1889 UINT8 *buffg = &buff[channelMap[1]],
1890 *buffr = &buff[channelMap[2]],
1891 *buffb = &buff[channelMap[0]];
1893 int cnt, channels = bpp/8;
1895 for (i=0; i < h; i++) {
1896 if (i%2) sampledPos -= (w + 1)/2;
1898 for (j=0; j < w; j++) {
1900 uAvg = u[sampledPos];
1901 vAvg = v[sampledPos];
1903 buffg[cnt] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
1904 buffr[cnt] = Clamp8(uAvg + g);
1905 buffb[cnt] = Clamp8(vAvg + g);
1908 if (j%2) sampledPos++;
1913 if (wOdd) sampledPos++;
1916 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1920 for (i=0; i < h; i++) {
1922 for (j = 0; j < w; j++) {
1926 buffg[cnt] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
1927 buffr[cnt] = Clamp8(uAvg + g);
1928 buffb[cnt] = Clamp8(vAvg + g);
1938 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1946 ASSERT(m_header.channels == 3);
1947 ASSERT(m_header.bpp == 48);
1949 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1951 DataT* y = m_channel[0]; ASSERT(y);
1952 DataT* u = m_channel[1]; ASSERT(u);
1953 DataT* v = m_channel[2]; ASSERT(v);
1957 if (bpp >= 48 && bpp%16 == 0) {
1958 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1959 UINT16 *buff16 = (UINT16 *)buff;
1960 int pitch16 = pitch/2;
1961 channels = bpp/16; ASSERT(channels >= m_header.channels);
1963 for (i=0; i < h; i++) {
1964 if (i%2) sampledPos -= (w + 1)/2;
1966 for (j=0; j < w; j++) {
1969 uAvg = u[sampledPos];
1970 vAvg = v[sampledPos];
1976 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
1977 buff16[cnt + channelMap[1]] = Clamp16(g << shift);
1978 buff16[cnt + channelMap[2]] = Clamp16((uAvg + g) << shift);
1979 buff16[cnt + channelMap[0]] = Clamp16((vAvg + g) << shift);
1982 if (j%2) sampledPos++;
1985 if (wOdd) sampledPos++;
1989 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1994 const int shift =
__max(0, UsedBitsPerChannel() - 8);
1995 channels = bpp/8; ASSERT(channels >= m_header.channels);
1997 for (i=0; i < h; i++) {
1998 if (i%2) sampledPos -= (w + 1)/2;
2000 for (j=0; j < w; j++) {
2003 uAvg = u[sampledPos];
2004 vAvg = v[sampledPos];
2010 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
2011 buff[cnt + channelMap[1]] = Clamp8(g >> shift);
2012 buff[cnt + channelMap[2]] = Clamp8((uAvg + g) >> shift);
2013 buff[cnt + channelMap[0]] = Clamp8((vAvg + g) >> shift);
2016 if (j%2) sampledPos++;
2019 if (wOdd) sampledPos++;
2023 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2031 ASSERT(m_header.channels == 3);
2032 ASSERT(m_header.bpp == m_header.channels*8);
2035 DataT* l = m_channel[0]; ASSERT(l);
2036 DataT* a = m_channel[1]; ASSERT(a);
2037 DataT* b = m_channel[2]; ASSERT(b);
2038 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
2040 for (i=0; i < h; i++) {
2041 if (i%2) sampledPos -= (w + 1)/2;
2043 for (j=0; j < w; j++) {
2046 uAvg = a[sampledPos];
2047 vAvg = b[sampledPos];
2052 buff[cnt + channelMap[0]] = Clamp8(l[yPos] +
YUVoffset8);
2053 buff[cnt + channelMap[1]] = Clamp8(uAvg +
YUVoffset8);
2054 buff[cnt + channelMap[2]] = Clamp8(vAvg +
YUVoffset8);
2057 if (j%2) sampledPos++;
2060 if (wOdd) sampledPos++;
2064 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2071 ASSERT(m_header.channels == 3);
2072 ASSERT(m_header.bpp == m_header.channels*16);
2074 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2076 DataT* l = m_channel[0]; ASSERT(l);
2077 DataT* a = m_channel[1]; ASSERT(a);
2078 DataT* b = m_channel[2]; ASSERT(b);
2082 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2083 UINT16 *buff16 = (UINT16 *)buff;
2084 int pitch16 = pitch/2;
2085 channels = bpp/16; ASSERT(channels >= m_header.channels);
2087 for (i=0; i < h; i++) {
2088 if (i%2) sampledPos -= (w + 1)/2;
2090 for (j=0; j < w; j++) {
2093 uAvg = a[sampledPos];
2094 vAvg = b[sampledPos];
2099 buff16[cnt + channelMap[0]] = Clamp16((l[yPos] + yuvOffset16) << shift);
2100 buff16[cnt + channelMap[1]] = Clamp16((uAvg + yuvOffset16) << shift);
2101 buff16[cnt + channelMap[2]] = Clamp16((vAvg + yuvOffset16) << shift);
2104 if (j%2) sampledPos++;
2107 if (wOdd) sampledPos++;
2111 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2116 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2117 channels = bpp/8; ASSERT(channels >= m_header.channels);
2119 for (i=0; i < h; i++) {
2120 if (i%2) sampledPos -= (w + 1)/2;
2122 for (j=0; j < w; j++) {
2125 uAvg = a[sampledPos];
2126 vAvg = b[sampledPos];
2131 buff[cnt + channelMap[0]] = Clamp8((l[yPos] + yuvOffset16) >> shift);
2132 buff[cnt + channelMap[1]] = Clamp8((uAvg + yuvOffset16) >> shift);
2133 buff[cnt + channelMap[2]] = Clamp8((vAvg + yuvOffset16) >> shift);
2136 if (j%2) sampledPos++;
2139 if (wOdd) sampledPos++;
2143 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2152 ASSERT(m_header.channels == 4);
2153 ASSERT(m_header.bpp == m_header.channels*8);
2156 DataT* y = m_channel[0]; ASSERT(y);
2157 DataT* u = m_channel[1]; ASSERT(u);
2158 DataT* v = m_channel[2]; ASSERT(v);
2159 DataT* a = m_channel[3]; ASSERT(a);
2161 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
2163 for (i=0; i < h; i++) {
2164 if (i%2) sampledPos -= (w + 1)/2;
2166 for (j=0; j < w; j++) {
2169 uAvg = u[sampledPos];
2170 vAvg = v[sampledPos];
2178 buff[cnt + channelMap[1]] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
2179 buff[cnt + channelMap[2]] = Clamp8(uAvg + g);
2180 buff[cnt + channelMap[0]] = Clamp8(vAvg + g);
2181 buff[cnt + channelMap[3]] = aAvg;
2184 if (j%2) sampledPos++;
2187 if (wOdd) sampledPos++;
2191 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2198 ASSERT(m_header.channels == 4);
2199 ASSERT(m_header.bpp == 64);
2201 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2203 DataT* y = m_channel[0]; ASSERT(y);
2204 DataT* u = m_channel[1]; ASSERT(u);
2205 DataT* v = m_channel[2]; ASSERT(v);
2206 DataT* a = m_channel[3]; ASSERT(a);
2211 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2212 UINT16 *buff16 = (UINT16 *)buff;
2213 int pitch16 = pitch/2;
2214 channels = bpp/16; ASSERT(channels >= m_header.channels);
2216 for (i=0; i < h; i++) {
2217 if (i%2) sampledPos -= (w + 1)/2;
2219 for (j=0; j < w; j++) {
2222 uAvg = u[sampledPos];
2223 vAvg = v[sampledPos];
2224 aAvg = a[sampledPos] + yuvOffset16;
2228 aAvg = a[yPos] + yuvOffset16;
2231 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
2232 buff16[cnt + channelMap[1]] = Clamp16(g << shift);
2233 buff16[cnt + channelMap[2]] = Clamp16((uAvg + g) << shift);
2234 buff16[cnt + channelMap[0]] = Clamp16((vAvg + g) << shift);
2235 buff16[cnt + channelMap[3]] = Clamp16(aAvg << shift);
2238 if (j%2) sampledPos++;
2241 if (wOdd) sampledPos++;
2245 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2250 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2251 channels = bpp/8; ASSERT(channels >= m_header.channels);
2253 for (i=0; i < h; i++) {
2254 if (i%2) sampledPos -= (w + 1)/2;
2256 for (j=0; j < w; j++) {
2259 uAvg = u[sampledPos];
2260 vAvg = v[sampledPos];
2261 aAvg = a[sampledPos] + yuvOffset16;
2265 aAvg = a[yPos] + yuvOffset16;
2268 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
2269 buff[cnt + channelMap[1]] = Clamp8(g >> shift);
2270 buff[cnt + channelMap[2]] = Clamp8((uAvg + g) >> shift);
2271 buff[cnt + channelMap[0]] = Clamp8((vAvg + g) >> shift);
2272 buff[cnt + channelMap[3]] = Clamp8(aAvg >> shift);
2275 if (j%2) sampledPos++;
2278 if (wOdd) sampledPos++;
2282 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2288#ifdef __PGF32SUPPORT__
2291 ASSERT(m_header.channels == 1);
2292 ASSERT(m_header.bpp == 32);
2294 const int yuvOffset31 = 1 << (UsedBitsPerChannel() - 1);
2296 DataT* y = m_channel[0]; ASSERT(y);
2299 const int shift = 31 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2300 UINT32 *buff32 = (UINT32 *)buff;
2301 int pitch32 = pitch/4;
2303 for (i=0; i < h; i++) {
2304 for (j=0; j < w; j++) {
2305 buff32[j] = Clamp31((y[yPos++] + yuvOffset31) << shift);
2311 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2314 }
else if (bpp == 16) {
2315 const int usedBits = UsedBitsPerChannel();
2316 UINT16 *buff16 = (UINT16 *)buff;
2317 int pitch16 = pitch/2;
2319 if (usedBits < 16) {
2320 const int shift = 16 - usedBits;
2321 for (i=0; i < h; i++) {
2322 for (j=0; j < w; j++) {
2323 buff16[j] = Clamp16((y[yPos++] + yuvOffset31) << shift);
2329 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2333 const int shift =
__max(0, usedBits - 16);
2334 for (i=0; i < h; i++) {
2335 for (j=0; j < w; j++) {
2336 buff16[j] = Clamp16((y[yPos++] + yuvOffset31) >> shift);
2342 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2348 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2350 for (i=0; i < h; i++) {
2351 for (j=0; j < w; j++) {
2352 buff[j] = Clamp8((y[yPos++] + yuvOffset31) >> shift);
2358 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2367 ASSERT(m_header.channels == 3);
2368 ASSERT(m_header.bpp == m_header.channels*4);
2369 ASSERT(bpp == m_header.channels*4);
2370 ASSERT(!m_downsample);
2372 DataT* y = m_channel[0]; ASSERT(y);
2373 DataT* u = m_channel[1]; ASSERT(u);
2374 DataT* v = m_channel[2]; ASSERT(v);
2378 for (i=0; i < h; i++) {
2380 for (j=0; j < w; j++) {
2384 yval = Clamp4(y[yPos++] +
YUVoffset4 - ((uAvg + vAvg ) >> 2));
2386 buff[cnt] = UINT8(Clamp4(vAvg + yval) | (yval << 4));
2388 buff[cnt] = Clamp4(uAvg + yval);
2390 buff[cnt] |= Clamp4(vAvg + yval) << 4;
2392 buff[cnt] = UINT8(yval | (Clamp4(uAvg + yval) << 4));
2400 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2407 ASSERT(m_header.channels == 3);
2408 ASSERT(m_header.bpp == 16);
2410 ASSERT(!m_downsample);
2412 DataT* y = m_channel[0]; ASSERT(y);
2413 DataT* u = m_channel[1]; ASSERT(u);
2414 DataT* v = m_channel[2]; ASSERT(v);
2416 UINT16 *buff16 = (UINT16 *)buff;
2417 int pitch16 = pitch/2;
2419 for (i=0; i < h; i++) {
2420 for (j=0; j < w; j++) {
2424 yval = Clamp6(y[yPos++] +
YUVoffset6 - ((uAvg + vAvg ) >> 2));
2425 buff16[j] = (yval << 5) | ((Clamp6(uAvg + yval) >> 1) << 11) | (Clamp6(vAvg + yval) >> 1);
2431 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2440#ifdef __PGFROISUPPORT__
2445 buff = buffStart + (levelRoi.
top - roi.
top)*pitch + (levelRoi.
left - roi.
left)*bypp;
2446 w = levelRoi.
Width()*bypp;
2449 for (i=0; i < h; i++) {
2450 for (j=0; j < w; j++) {
2451 targetBuff[j] = buff[j];
2453 targetBuff += targetPitch;
2460 delete[] buffStart; buffStart = 0;
2481 const UINT32 w = m_width[0];
2482 const UINT32 h = m_height[0];
2483 const bool wOdd = (1 == w%2);
2484 const int dataBits =
DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2487 const double dP = 1.0/h;
2489 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
2490 if (channelMap == NULL) channelMap = defMap;
2491 int sampledPos = 0, yPos = 0;
2496 if (m_header.channels == 3) {
2497 ASSERT(bpp%dataBits == 0);
2499 DataT* y = m_channel[0]; ASSERT(y);
2500 DataT* u = m_channel[1]; ASSERT(u);
2501 DataT* v = m_channel[2]; ASSERT(v);
2502 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2504 for (i=0; i < h; i++) {
2505 if (i%2) sampledPos -= (w + 1)/2;
2507 for (j=0; j < w; j++) {
2510 uAvg = u[sampledPos];
2511 vAvg = v[sampledPos];
2516 buff[cnt + channelMap[0]] = y[yPos];
2517 buff[cnt + channelMap[1]] = uAvg;
2518 buff[cnt + channelMap[2]] = vAvg;
2521 if (j%2) sampledPos++;
2524 if (wOdd) sampledPos++;
2528 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2531 }
else if (m_header.channels == 4) {
2532 ASSERT(m_header.bpp == m_header.channels*8);
2533 ASSERT(bpp%dataBits == 0);
2535 DataT* y = m_channel[0]; ASSERT(y);
2536 DataT* u = m_channel[1]; ASSERT(u);
2537 DataT* v = m_channel[2]; ASSERT(v);
2538 DataT* a = m_channel[3]; ASSERT(a);
2540 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2542 for (i=0; i < h; i++) {
2543 if (i%2) sampledPos -= (w + 1)/2;
2545 for (j=0; j < w; j++) {
2548 uAvg = u[sampledPos];
2549 vAvg = v[sampledPos];
2550 aAvg = Clamp8(a[sampledPos] + yuvOffset);
2554 aAvg = Clamp8(a[yPos] + yuvOffset);
2557 buff[cnt + channelMap[0]] = y[yPos];
2558 buff[cnt + channelMap[1]] = uAvg;
2559 buff[cnt + channelMap[2]] = vAvg;
2560 buff[cnt + channelMap[3]] = aAvg;
2563 if (j%2) sampledPos++;
2566 if (wOdd) sampledPos++;
2570 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2592 const double dP = 1.0/m_header.height;
2593 const int dataBits =
DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2597 int yPos = 0, cnt = 0;
2599 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
2601 if (channelMap == NULL) channelMap = defMap;
2603 if (m_header.channels == 3) {
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 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2611 for (UINT32 h=0; h < m_header.height; h++) {
2613 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2618 for (UINT32 w=0; w < m_header.width; w++) {
2619 y[yPos] = buff[cnt + channelMap[0]];
2620 u[yPos] = buff[cnt + channelMap[1]];
2621 v[yPos] = buff[cnt + channelMap[2]];
2627 }
else if (m_header.channels == 4) {
2628 ASSERT(bpp%dataBits == 0);
2630 DataT* y = m_channel[0]; ASSERT(y);
2631 DataT* u = m_channel[1]; ASSERT(u);
2632 DataT* v = m_channel[2]; ASSERT(v);
2633 DataT* a = m_channel[3]; ASSERT(a);
2634 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2636 for (UINT32 h=0; h < m_header.height; h++) {
2638 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2643 for (UINT32 w=0; w < m_header.width; w++) {
2644 y[yPos] = buff[cnt + channelMap[0]];
2645 u[yPos] = buff[cnt + channelMap[1]];
2646 v[yPos] = buff[cnt + channelMap[2]];
2647 a[yPos] = buff[cnt + channelMap[3]] - yuvOffset;
2657 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