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;
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);
309 if (bpc > 31) bpc = 31;
333 if (m_header.nLevels == 0) {
336 for (
int i=0; i < m_header.channels; i++) {
337 ASSERT(m_wtChannel[i]);
338 m_channel[i] = m_wtChannel[i]->GetSubband(0,
LL)->GetBuffer();
342 int currentLevel = m_header.nLevels;
344 if (ROIisSupported()) {
346 SetROI(
PGFRect(0, 0, m_header.width, m_header.height));
349 while (currentLevel > level) {
350 for (
int i=0; i < m_header.channels; i++) {
351 ASSERT(m_wtChannel[i]);
353 if (currentLevel == m_header.nLevels) {
355 m_wtChannel[i]->GetSubband(currentLevel,
LL)->Dequantize(m_quant);
357 m_wtChannel[i]->GetSubband(currentLevel,
HL)->Dequantize(m_quant);
358 m_wtChannel[i]->GetSubband(currentLevel,
LH)->Dequantize(m_quant);
359 m_wtChannel[i]->GetSubband(currentLevel,
HH)->Dequantize(m_quant);
362 OSError err = m_wtChannel[i]->InverseTransform(currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
363 if (err != NoError) ReturnWithError(err);
364 ASSERT(m_channel[i]);
385 ASSERT((level >= 0 && level < m_header.nLevels) || m_header.nLevels == 0);
388 #ifdef __PGFROISUPPORT__
389 if (ROIisSupported() && m_header.nLevels > 0) {
391 PGFRect rect(0, 0, m_header.width, m_header.height);
392 Read(rect, level, cb, data);
397 if (m_header.nLevels == 0) {
402 if ((*cb)(1.0,
true, data)) ReturnWithError(EscapePressed);
406 const int levelDiff = m_currentLevel - level;
407 double percent = (m_progressMode ==
PM_Relative) ? pow(0.25, levelDiff) : m_percent;
410 while (m_currentLevel > level) {
411 for (
int i=0; i < m_header.channels; i++) {
412 ASSERT(m_wtChannel[i]);
414 if (m_currentLevel == m_header.nLevels) {
416 m_wtChannel[i]->GetSubband(m_currentLevel,
LL)->PlaceTile(*m_decoder, m_quant);
418 if (m_preHeader.version &
Version5) {
420 m_wtChannel[i]->GetSubband(m_currentLevel,
HL)->PlaceTile(*m_decoder, m_quant);
421 m_wtChannel[i]->GetSubband(m_currentLevel,
LH)->PlaceTile(*m_decoder, m_quant);
424 m_decoder->DecodeInterleaved(m_wtChannel[i], m_currentLevel, m_quant);
426 m_wtChannel[i]->GetSubband(m_currentLevel,
HH)->PlaceTile(*m_decoder, m_quant);
429 volatile OSError error = NoError;
430 #ifdef LIBPGF_USE_OPENMP
431 #pragma omp parallel for default(shared)
433 for (
int i=0; i < m_header.channels; i++) {
435 if (error == NoError) {
436 OSError err = m_wtChannel[i]->InverseTransform(m_currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
437 if (err != NoError) error = err;
439 ASSERT(m_channel[i]);
441 if (error != NoError) ReturnWithError(error);
447 if (m_cb) m_cb(m_cbArg);
452 if (m_progressMode ==
PM_Absolute) m_percent = percent;
453 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
459 if (m_currentLevel == 0) Close();
462 #ifdef __PGFROISUPPORT__
473 ASSERT((level >= 0 && level < m_header.nLevels) || m_header.nLevels == 0);
476 if (m_header.nLevels == 0 || !ROIisSupported()) {
477 rect.left = rect.top = 0;
478 rect.right = m_header.width; rect.bottom = m_header.height;
479 Read(level, cb, data);
481 ASSERT(ROIisSupported());
483 ASSERT(rect.left < m_header.width && rect.top < m_header.height);
485 const int levelDiff = m_currentLevel - level;
486 double percent = (m_progressMode ==
PM_Relative) ? pow(0.25, levelDiff) : m_percent;
489 if (levelDiff <= 0) {
491 m_currentLevel = m_header.nLevels;
492 m_decoder->SetStreamPosToData();
496 if (rect.right == 0 || rect.right > m_header.width) rect.right = m_header.width;
497 if (rect.bottom == 0 || rect.bottom > m_header.height) rect.bottom = m_header.height;
502 while (m_currentLevel > level) {
503 for (
int i=0; i < m_header.channels; i++) {
504 ASSERT(m_wtChannel[i]);
507 const UINT32 nTiles = m_wtChannel[i]->GetNofTiles(m_currentLevel);
508 const PGFRect& tileIndices = m_wtChannel[i]->GetTileIndices(m_currentLevel);
511 if (m_currentLevel == m_header.nLevels) {
513 m_decoder->DecodeTileBuffer();
514 m_wtChannel[i]->GetSubband(m_currentLevel,
LL)->PlaceTile(*m_decoder, m_quant);
516 for (UINT32 tileY=0; tileY < nTiles; tileY++) {
517 for (UINT32 tileX=0; tileX < nTiles; tileX++) {
519 if (tileIndices.
IsInside(tileX, tileY)) {
520 m_decoder->DecodeTileBuffer();
521 m_wtChannel[i]->GetSubband(m_currentLevel,
HL)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
522 m_wtChannel[i]->GetSubband(m_currentLevel,
LH)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
523 m_wtChannel[i]->GetSubband(m_currentLevel,
HH)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
526 m_decoder->SkipTileBuffer();
532 volatile OSError error = NoError;
533 #ifdef LIBPGF_USE_OPENMP
534 #pragma omp parallel for default(shared)
536 for (
int i=0; i < m_header.channels; i++) {
538 if (error == NoError) {
539 OSError err = m_wtChannel[i]->InverseTransform(m_currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
540 if (err != NoError) error = err;
542 ASSERT(m_channel[i]);
544 if (error != NoError) ReturnWithError(error);
550 if (m_cb) m_cb(m_cbArg);
555 if (m_progressMode ==
PM_Absolute) m_percent = percent;
556 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
562 if (m_currentLevel == 0) Close();
583 else rect.
left -= dx;
584 if (rect.
top < dy) rect.
top = 0;
607 #endif // __PGFROISUPPORT__
627 ASSERT(targetLen > 0);
631 m_decoder->SetStreamPosToStart();
634 UINT32 len =
__min(targetLen, GetEncodedHeaderLength());
637 len = m_decoder->ReadEncodedData(target, len);
638 ASSERT(len >= 0 && len <= targetLen);
660 ASSERT(level >= 0 && level < m_header.nLevels);
662 ASSERT(targetLen > 0);
666 m_decoder->SetStreamPosToData();
671 for (
int i=m_header.nLevels - 1; i > level; i--) {
672 offset += m_levelLength[m_header.nLevels - 1 - i];
674 m_decoder->Skip(offset);
677 UINT32 len =
__min(targetLen, GetEncodedLevelLength(level));
680 len = m_decoder->ReadEncodedData(target, len);
681 ASSERT(len >= 0 && len <= targetLen);
694 while(maxValue > 0) {
699 if (pot > bpc) pot = bpc;
700 if (pot > 31) pot = 31;
745 ASSERT(m_channel[0]);
748 RgbToYuv(pitch, buff, bpp, channelMap, cb, data);
752 for (
int i=1; i < m_header.channels; i++) {
766 const int oddW = w%2;
773 for (
int i=0; i < h2; i++) {
774 for (
int j=0; j < w2; j++) {
776 buff[sampledPos] = (buff[loPos] + buff[loPos + 1] + buff[hiPos] + buff[hiPos + 1]) >> 2;
777 loPos += 2; hiPos += 2;
781 buff[sampledPos] = (buff[loPos] + buff[hiPos]) >> 1;
785 loPos += w; hiPos += w;
788 for (
int j=0; j < w2; j++) {
789 buff[sampledPos] = (buff[loPos] + buff[loPos+1]) >> 1;
790 loPos += 2; hiPos += 2;
794 buff[sampledPos] = buff[loPos];
812 while (s > maxThumbnailWidth) {
849 #ifdef __PGFROISUPPORT__
850 m_streamReinitialized =
false;
854 memcpy(m_preHeader.magic,
PGFMagic, 3);
876 m_quant = m_header.quality - 1;
878 m_downsample =
false;
879 m_quant = m_header.quality;
887 if (userDataLength && userData) {
888 m_postHeader.userData =
new(std::nothrow) UINT8[userDataLength];
889 if (!m_postHeader.userData) ReturnWithError(InsufficientMemory);
890 m_postHeader.userDataLen = userDataLength;
891 memcpy(m_postHeader.userData, userData, userDataLength);
893 m_preHeader.hSize += userDataLength;
897 for (
int i=0; i < m_header.channels; i++) {
899 m_width[i] = m_header.width;
900 m_height[i] = m_header.height;
903 ASSERT(!m_channel[i]);
904 m_channel[i] =
new(std::nothrow)
DataT[m_header.width*m_header.height];
908 delete[] m_channel[i]; m_channel[i] = 0;
911 ReturnWithError(InsufficientMemory);
924 ASSERT(m_header.nLevels <=
MaxLevel);
927 if (m_header.nLevels > 0) {
928 volatile OSError error = NoError;
930 #ifdef LIBPGF_USE_OPENMP
931 #pragma omp parallel for default(shared)
933 for (
int i=0; i < m_header.channels; i++) {
935 if (error == NoError) {
936 if (m_wtChannel[i]) {
937 ASSERT(m_channel[i]);
939 int size = m_height[i]*m_width[i];
940 temp =
new(std::nothrow)
DataT[size];
942 memcpy(temp, m_channel[i], size*
DataTSize);
943 delete m_wtChannel[i];
946 error = InsufficientMemory;
949 if (error == NoError) {
951 ASSERT(!m_channel[i]);
954 m_wtChannel[i] =
new CWaveletTransform(m_width[i], m_height[i], m_header.nLevels, m_channel[i]);
955 if (m_wtChannel[i]) {
956 #ifdef __PGFROISUPPORT__
957 m_wtChannel[i]->SetROI(
PGFRect(0, 0, m_width[i], m_height[i]));
961 for (
int l=0; error == NoError && l < m_header.nLevels; l++) {
962 OSError err = m_wtChannel[i]->ForwardTransform(l, m_quant);
963 if (err != NoError) error = err;
966 delete[] m_channel[i];
967 error = InsufficientMemory;
972 if (error != NoError) {
974 for (
int i=0; i < m_header.channels; i++) {
975 delete m_wtChannel[i];
977 ReturnWithError(error);
980 m_currentLevel = m_header.nLevels;
983 m_encoder =
new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_userDataPos, m_useOMPinEncoder);
984 if (m_favorSpeedOverSize) m_encoder->FavorSpeedOverSize();
986 #ifdef __PGFROISUPPORT__
987 if (ROIisSupported()) {
997 m_encoder =
new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_userDataPos, m_useOMPinEncoder);
1000 INT64 nBytes = m_encoder->ComputeHeaderLength();
1001 return (nBytes > 0) ? (UINT32)nBytes : 0;
1017 #ifdef __PGFROISUPPORT__
1024 const UINT32 lastTile = nTiles - 1;
1028 ASSERT(nTiles == 1);
1032 for (UINT32 tileY=0; tileY < nTiles; tileY++) {
1033 for (UINT32 tileX=0; tileX < nTiles; tileX++) {
1037 if (i == lastChannel && tileY == lastTile && tileX == lastTile) {
1094 ASSERT(m_preHeader.hSize);
1096 int levels = m_header.nLevels;
1097 double percent = pow(0.25, levels);
1100 UINT32 nWrittenBytes = UpdatePostHeaderSize();
1104 for (
int c=0; c < m_header.channels; c++) {
1105 const UINT32 size = m_width[c]*m_height[c];
1108 for (UINT32 i=0; i < size; i++) {
1110 stream->Write(&count, &m_channel[c][i]);
1116 if ((*cb)(1,
true, data)) ReturnWithError(EscapePressed);
1125 for (m_currentLevel = levels; m_currentLevel > 0; ) {
1131 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1140 nWrittenBytes += m_encoder->UpdateLevelLength();
1143 delete m_encoder; m_encoder = NULL;
1147 return nWrittenBytes;
1165 ASSERT(m_preHeader.hSize);
1168 UINT32 nBytes = WriteHeader(stream);
1171 nBytes += WriteImage(stream, cb, data);
1174 if (nWrittenBytes) *nWrittenBytes += nBytes;
1177 #ifdef __PGFROISUPPORT__
1193 ASSERT(m_header.nLevels > 0);
1194 ASSERT(0 <= level && level < m_header.nLevels);
1196 ASSERT(ROIisSupported());
1198 const int levelDiff = m_currentLevel - level;
1199 double percent = (m_progressMode ==
PM_Relative) ? pow(0.25, levelDiff) : m_percent;
1200 UINT32 nWrittenBytes = 0;
1202 if (m_currentLevel == m_header.nLevels) {
1204 nWrittenBytes = UpdatePostHeaderSize();
1207 if (m_encoder->ComputeBufferLength()) {
1208 m_streamReinitialized =
true;
1213 while (m_currentLevel > level) {
1216 if (m_levelLength) {
1217 nWrittenBytes += m_levelLength[m_header.nLevels - m_currentLevel - 1];
1223 if (m_progressMode ==
PM_Absolute) m_percent = percent;
1224 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1229 if (m_currentLevel == 0) {
1230 if (!m_streamReinitialized) {
1232 m_encoder->UpdateLevelLength();
1235 delete m_encoder; m_encoder = NULL;
1238 return nWrittenBytes;
1240 #endif // __PGFROISUPPORT__
1293 if (iFirstColor + nColors >
ColorTableLen) ReturnWithError(ColorTableError);
1295 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1296 prgbColors[j] = m_postHeader.clut[i];
1307 if (iFirstColor + nColors >
ColorTableLen) ReturnWithError(ColorTableError);
1309 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1310 m_postHeader.clut[i] = prgbColors[j];
1331 void CPGFImage::RgbToYuv(
int pitch, UINT8* buff, BYTE bpp,
int channelMap[], CallbackPtr cb,
void *data ) THROW_ {
1333 int yPos = 0, cnt = 0;
1335 const double dP = 1.0/m_header.height;
1336 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
1338 if (channelMap == NULL) channelMap = defMap;
1340 switch(m_header.mode) {
1343 ASSERT(m_header.channels == 1);
1344 ASSERT(m_header.bpp == 1);
1347 const UINT32 w = m_header.width;
1348 const UINT32 w2 = (m_header.width + 7)/8;
1349 DataT* y = m_channel[0]; ASSERT(y);
1351 for (UINT32 h=0; h < m_header.height; h++) {
1353 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1357 for (UINT32 j=0; j < w2; j++) {
1360 for (UINT32 j=w2; j < w; j++) {
1383 ASSERT(m_header.channels >= 1);
1384 ASSERT(m_header.bpp == m_header.channels*8);
1386 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1388 for (UINT32 h=0; h < m_header.height; h++) {
1390 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1395 for (UINT32 w=0; w < m_header.width; w++) {
1396 for (
int c=0; c < m_header.channels; c++) {
1397 m_channel[c][yPos] = buff[cnt + channelMap[c]] -
YUVoffset8;
1409 ASSERT(m_header.channels >= 1);
1410 ASSERT(m_header.bpp == m_header.channels*16);
1411 ASSERT(bpp%16 == 0);
1413 UINT16 *buff16 = (UINT16 *)buff;
1414 const int pitch16 = pitch/2;
1415 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1416 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1417 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1419 for (UINT32 h=0; h < m_header.height; h++) {
1421 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1426 for (UINT32 w=0; w < m_header.width; w++) {
1427 for (
int c=0; c < m_header.channels; c++) {
1428 m_channel[c][yPos] = (buff16[cnt + channelMap[c]] >> shift) - yuvOffset16;
1439 ASSERT(m_header.channels == 3);
1440 ASSERT(m_header.bpp == m_header.channels*8);
1443 DataT* y = m_channel[0]; ASSERT(y);
1444 DataT* u = m_channel[1]; ASSERT(u);
1445 DataT* v = m_channel[2]; ASSERT(v);
1446 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1449 for (UINT32 h=0; h < m_header.height; h++) {
1451 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1456 for (UINT32 w=0; w < m_header.width; w++) {
1457 b = buff[cnt + channelMap[0]];
1458 g = buff[cnt + channelMap[1]];
1459 r = buff[cnt + channelMap[2]];
1461 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset8;
1473 ASSERT(m_header.channels == 3);
1474 ASSERT(m_header.bpp == m_header.channels*16);
1475 ASSERT(bpp%16 == 0);
1477 UINT16 *buff16 = (UINT16 *)buff;
1478 const int pitch16 = pitch/2;
1479 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1480 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1481 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1483 DataT* y = m_channel[0]; ASSERT(y);
1484 DataT* u = m_channel[1]; ASSERT(u);
1485 DataT* v = m_channel[2]; ASSERT(v);
1488 for (UINT32 h=0; h < m_header.height; h++) {
1490 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1495 for (UINT32 w=0; w < m_header.width; w++) {
1496 b = buff16[cnt + channelMap[0]] >> shift;
1497 g = buff16[cnt + channelMap[1]] >> shift;
1498 r = buff16[cnt + channelMap[2]] >> shift;
1500 y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1513 ASSERT(m_header.channels == 4);
1514 ASSERT(m_header.bpp == m_header.channels*8);
1516 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1518 DataT* y = m_channel[0]; ASSERT(y);
1519 DataT* u = m_channel[1]; ASSERT(u);
1520 DataT* v = m_channel[2]; ASSERT(v);
1521 DataT* a = m_channel[3]; ASSERT(a);
1524 for (UINT32 h=0; h < m_header.height; h++) {
1526 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1531 for (UINT32 w=0; w < m_header.width; w++) {
1532 b = buff[cnt + channelMap[0]];
1533 g = buff[cnt + channelMap[1]];
1534 r = buff[cnt + channelMap[2]];
1536 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset8;
1539 a[yPos++] = buff[cnt + channelMap[3]] -
YUVoffset8;
1548 ASSERT(m_header.channels == 4);
1549 ASSERT(m_header.bpp == m_header.channels*16);
1550 ASSERT(bpp%16 == 0);
1552 UINT16 *buff16 = (UINT16 *)buff;
1553 const int pitch16 = pitch/2;
1554 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1555 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1556 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1558 DataT* y = m_channel[0]; ASSERT(y);
1559 DataT* u = m_channel[1]; ASSERT(u);
1560 DataT* v = m_channel[2]; ASSERT(v);
1561 DataT* a = m_channel[3]; ASSERT(a);
1564 for (UINT32 h=0; h < m_header.height; h++) {
1566 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1571 for (UINT32 w=0; w < m_header.width; w++) {
1572 b = buff16[cnt + channelMap[0]] >> shift;
1573 g = buff16[cnt + channelMap[1]] >> shift;
1574 r = buff16[cnt + channelMap[2]] >> shift;
1576 y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1579 a[yPos++] = (buff16[cnt + channelMap[3]] >> shift) - yuvOffset16;
1586 #ifdef __PGF32SUPPORT__
1589 ASSERT(m_header.channels == 1);
1590 ASSERT(m_header.bpp == 32);
1594 DataT* y = m_channel[0]; ASSERT(y);
1596 UINT32 *buff32 = (UINT32 *)buff;
1597 const int pitch32 = pitch/4;
1598 const int shift = 31 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1599 const DataT yuvOffset31 = 1 << (UsedBitsPerChannel() - 1);
1601 for (UINT32 h=0; h < m_header.height; h++) {
1603 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1607 for (UINT32 w=0; w < m_header.width; w++) {
1608 y[yPos++] = (buff32[w] >> shift) - yuvOffset31;
1617 ASSERT(m_header.channels == 3);
1618 ASSERT(m_header.bpp == m_header.channels*4);
1619 ASSERT(bpp == m_header.channels*4);
1621 DataT* y = m_channel[0]; ASSERT(y);
1622 DataT* u = m_channel[1]; ASSERT(u);
1623 DataT* v = m_channel[2]; ASSERT(v);
1625 UINT8 rgb = 0, b, g, r;
1627 for (UINT32 h=0; h < m_header.height; h++) {
1629 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1634 for (UINT32 w=0; w < m_header.width; w++) {
1639 g = (rgb & 0xF0) >> 4;
1645 b = (rgb & 0xF0) >> 4;
1649 r = (rgb & 0xF0) >> 4;
1654 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset4;
1665 ASSERT(m_header.channels == 3);
1666 ASSERT(m_header.bpp == 16);
1669 DataT* y = m_channel[0]; ASSERT(y);
1670 DataT* u = m_channel[1]; ASSERT(u);
1671 DataT* v = m_channel[2]; ASSERT(v);
1673 UINT16 *buff16 = (UINT16 *)buff;
1674 UINT16 rgb, b, g, r;
1675 const int pitch16 = pitch/2;
1677 for (UINT32 h=0; h < m_header.height; h++) {
1679 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1682 for (UINT32 w=0; w < m_header.width; w++) {
1684 r = (rgb & 0xF800) >> 10;
1685 g = (rgb & 0x07E0) >> 5;
1686 b = (rgb & 0x001F) << 1;
1688 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset6;
1720 void CPGFImage::GetBitmap(
int pitch, UINT8* buff, BYTE bpp,
int channelMap[] , CallbackPtr cb ,
void *data )
const THROW_ {
1722 UINT32 w = m_width[0];
1723 UINT32 h = m_height[0];
1724 UINT8* targetBuff = 0;
1725 UINT8* buffStart = 0;
1726 int targetPitch = 0;
1728 #ifdef __PGFROISUPPORT__
1729 const PGFRect& roi = (ROIisSupported()) ? m_wtChannel[0]->GetROI(m_currentLevel) :
PGFRect(0, 0, w, h);
1730 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));
1735 if (ROIisSupported() && (levelRoi.
Width() < w || levelRoi.
Height() < h)) {
1738 targetPitch = pitch;
1743 buff = buffStart =
new(std::nothrow) UINT8[pitch*h];
1744 if (!buff) ReturnWithError(InsufficientMemory);
1748 const bool wOdd = (1 == w%2);
1750 const double dP = 1.0/h;
1751 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
1752 if (channelMap == NULL) channelMap = defMap;
1753 int sampledPos = 0, yPos = 0;
1758 switch(m_header.mode) {
1761 ASSERT(m_header.channels == 1);
1762 ASSERT(m_header.bpp == 1);
1765 const UINT32 w2 = (w + 7)/8;
1766 DataT* y = m_channel[0]; ASSERT(y);
1768 for (i=0; i < h; i++) {
1770 for (j=0; j < w2; j++) {
1790 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1800 ASSERT(m_header.channels >= 1);
1801 ASSERT(m_header.bpp == m_header.channels*8);
1804 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
1806 for (i=0; i < h; i++) {
1808 for (j=0; j < w; j++) {
1809 for (
int c=0; c < m_header.channels; c++) {
1810 buff[cnt + channelMap[c]] = Clamp8(m_channel[c][yPos] +
YUVoffset8);
1819 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1826 ASSERT(m_header.channels >= 1);
1827 ASSERT(m_header.bpp == m_header.channels*16);
1829 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1833 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1834 UINT16 *buff16 = (UINT16 *)buff;
1835 int pitch16 = pitch/2;
1836 channels = bpp/16; ASSERT(channels >= m_header.channels);
1838 for (i=0; i < h; i++) {
1840 for (j=0; j < w; j++) {
1841 for (
int c=0; c < m_header.channels; c++) {
1842 buff16[cnt + channelMap[c]] = Clamp16((m_channel[c][yPos] + yuvOffset16) << shift);
1851 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1856 const int shift =
__max(0, UsedBitsPerChannel() - 8);
1857 channels = bpp/8; ASSERT(channels >= m_header.channels);
1859 for (i=0; i < h; i++) {
1861 for (j=0; j < w; j++) {
1862 for (
int c=0; c < m_header.channels; c++) {
1863 buff[cnt + channelMap[c]] = Clamp8((m_channel[c][yPos] + yuvOffset16) >> shift);
1872 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1880 ASSERT(m_header.channels == 3);
1881 ASSERT(m_header.bpp == m_header.channels*8);
1883 ASSERT(bpp >= m_header.bpp);
1885 DataT* y = m_channel[0]; ASSERT(y);
1886 DataT* u = m_channel[1]; ASSERT(u);
1887 DataT* v = m_channel[2]; ASSERT(v);
1888 UINT8 *buffg = &buff[channelMap[1]],
1889 *buffr = &buff[channelMap[2]],
1890 *buffb = &buff[channelMap[0]];
1892 int cnt, channels = bpp/8;
1894 for (i=0; i < h; i++) {
1895 if (i%2) sampledPos -= (w + 1)/2;
1897 for (j=0; j < w; j++) {
1899 uAvg = u[sampledPos];
1900 vAvg = v[sampledPos];
1902 buffg[cnt] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
1903 buffr[cnt] = Clamp8(uAvg + g);
1904 buffb[cnt] = Clamp8(vAvg + g);
1907 if (j%2) sampledPos++;
1912 if (wOdd) sampledPos++;
1915 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1919 for (i=0; i < h; i++) {
1921 for (j = 0; j < w; j++) {
1925 buffg[cnt] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
1926 buffr[cnt] = Clamp8(uAvg + g);
1927 buffb[cnt] = Clamp8(vAvg + g);
1937 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1945 ASSERT(m_header.channels == 3);
1946 ASSERT(m_header.bpp == 48);
1948 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1950 DataT* y = m_channel[0]; ASSERT(y);
1951 DataT* u = m_channel[1]; ASSERT(u);
1952 DataT* v = m_channel[2]; ASSERT(v);
1956 if (bpp >= 48 && bpp%16 == 0) {
1957 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1958 UINT16 *buff16 = (UINT16 *)buff;
1959 int pitch16 = pitch/2;
1960 channels = bpp/16; ASSERT(channels >= m_header.channels);
1962 for (i=0; i < h; i++) {
1963 if (i%2) sampledPos -= (w + 1)/2;
1965 for (j=0; j < w; j++) {
1968 uAvg = u[sampledPos];
1969 vAvg = v[sampledPos];
1975 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
1976 buff16[cnt + channelMap[1]] = Clamp16(g << shift);
1977 buff16[cnt + channelMap[2]] = Clamp16((uAvg + g) << shift);
1978 buff16[cnt + channelMap[0]] = Clamp16((vAvg + g) << shift);
1981 if (j%2) sampledPos++;
1984 if (wOdd) sampledPos++;
1988 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1993 const int shift =
__max(0, UsedBitsPerChannel() - 8);
1994 channels = bpp/8; ASSERT(channels >= m_header.channels);
1996 for (i=0; i < h; i++) {
1997 if (i%2) sampledPos -= (w + 1)/2;
1999 for (j=0; j < w; j++) {
2002 uAvg = u[sampledPos];
2003 vAvg = v[sampledPos];
2009 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
2010 buff[cnt + channelMap[1]] = Clamp8(g >> shift);
2011 buff[cnt + channelMap[2]] = Clamp8((uAvg + g) >> shift);
2012 buff[cnt + channelMap[0]] = Clamp8((vAvg + g) >> shift);
2015 if (j%2) sampledPos++;
2018 if (wOdd) sampledPos++;
2022 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2030 ASSERT(m_header.channels == 3);
2031 ASSERT(m_header.bpp == m_header.channels*8);
2034 DataT* l = m_channel[0]; ASSERT(l);
2035 DataT* a = m_channel[1]; ASSERT(a);
2036 DataT* b = m_channel[2]; ASSERT(b);
2037 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
2039 for (i=0; i < h; i++) {
2040 if (i%2) sampledPos -= (w + 1)/2;
2042 for (j=0; j < w; j++) {
2045 uAvg = a[sampledPos];
2046 vAvg = b[sampledPos];
2051 buff[cnt + channelMap[0]] = Clamp8(l[yPos] +
YUVoffset8);
2052 buff[cnt + channelMap[1]] = Clamp8(uAvg +
YUVoffset8);
2053 buff[cnt + channelMap[2]] = Clamp8(vAvg +
YUVoffset8);
2056 if (j%2) sampledPos++;
2059 if (wOdd) sampledPos++;
2063 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2070 ASSERT(m_header.channels == 3);
2071 ASSERT(m_header.bpp == m_header.channels*16);
2073 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2075 DataT* l = m_channel[0]; ASSERT(l);
2076 DataT* a = m_channel[1]; ASSERT(a);
2077 DataT* b = m_channel[2]; ASSERT(b);
2081 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2082 UINT16 *buff16 = (UINT16 *)buff;
2083 int pitch16 = pitch/2;
2084 channels = bpp/16; ASSERT(channels >= m_header.channels);
2086 for (i=0; i < h; i++) {
2087 if (i%2) sampledPos -= (w + 1)/2;
2089 for (j=0; j < w; j++) {
2092 uAvg = a[sampledPos];
2093 vAvg = b[sampledPos];
2098 buff16[cnt + channelMap[0]] = Clamp16((l[yPos] + yuvOffset16) << shift);
2099 buff16[cnt + channelMap[1]] = Clamp16((uAvg + yuvOffset16) << shift);
2100 buff16[cnt + channelMap[2]] = Clamp16((vAvg + yuvOffset16) << shift);
2103 if (j%2) sampledPos++;
2106 if (wOdd) sampledPos++;
2110 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2115 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2116 channels = bpp/8; ASSERT(channels >= m_header.channels);
2118 for (i=0; i < h; i++) {
2119 if (i%2) sampledPos -= (w + 1)/2;
2121 for (j=0; j < w; j++) {
2124 uAvg = a[sampledPos];
2125 vAvg = b[sampledPos];
2130 buff[cnt + channelMap[0]] = Clamp8((l[yPos] + yuvOffset16) >> shift);
2131 buff[cnt + channelMap[1]] = Clamp8((uAvg + yuvOffset16) >> shift);
2132 buff[cnt + channelMap[2]] = Clamp8((vAvg + yuvOffset16) >> shift);
2135 if (j%2) sampledPos++;
2138 if (wOdd) sampledPos++;
2142 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2151 ASSERT(m_header.channels == 4);
2152 ASSERT(m_header.bpp == m_header.channels*8);
2155 DataT* y = m_channel[0]; ASSERT(y);
2156 DataT* u = m_channel[1]; ASSERT(u);
2157 DataT* v = m_channel[2]; ASSERT(v);
2158 DataT* a = m_channel[3]; ASSERT(a);
2160 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
2162 for (i=0; i < h; i++) {
2163 if (i%2) sampledPos -= (w + 1)/2;
2165 for (j=0; j < w; j++) {
2168 uAvg = u[sampledPos];
2169 vAvg = v[sampledPos];
2177 buff[cnt + channelMap[1]] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
2178 buff[cnt + channelMap[2]] = Clamp8(uAvg + g);
2179 buff[cnt + channelMap[0]] = Clamp8(vAvg + g);
2180 buff[cnt + channelMap[3]] = aAvg;
2183 if (j%2) sampledPos++;
2186 if (wOdd) sampledPos++;
2190 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2197 ASSERT(m_header.channels == 4);
2198 ASSERT(m_header.bpp == 64);
2200 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2202 DataT* y = m_channel[0]; ASSERT(y);
2203 DataT* u = m_channel[1]; ASSERT(u);
2204 DataT* v = m_channel[2]; ASSERT(v);
2205 DataT* a = m_channel[3]; ASSERT(a);
2210 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2211 UINT16 *buff16 = (UINT16 *)buff;
2212 int pitch16 = pitch/2;
2213 channels = bpp/16; ASSERT(channels >= m_header.channels);
2215 for (i=0; i < h; i++) {
2216 if (i%2) sampledPos -= (w + 1)/2;
2218 for (j=0; j < w; j++) {
2221 uAvg = u[sampledPos];
2222 vAvg = v[sampledPos];
2223 aAvg = a[sampledPos] + yuvOffset16;
2227 aAvg = a[yPos] + yuvOffset16;
2230 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
2231 buff16[cnt + channelMap[1]] = Clamp16(g << shift);
2232 buff16[cnt + channelMap[2]] = Clamp16((uAvg + g) << shift);
2233 buff16[cnt + channelMap[0]] = Clamp16((vAvg + g) << shift);
2234 buff16[cnt + channelMap[3]] = Clamp16(aAvg << shift);
2237 if (j%2) sampledPos++;
2240 if (wOdd) sampledPos++;
2244 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2249 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2250 channels = bpp/8; ASSERT(channels >= m_header.channels);
2252 for (i=0; i < h; i++) {
2253 if (i%2) sampledPos -= (w + 1)/2;
2255 for (j=0; j < w; j++) {
2258 uAvg = u[sampledPos];
2259 vAvg = v[sampledPos];
2260 aAvg = a[sampledPos] + yuvOffset16;
2264 aAvg = a[yPos] + yuvOffset16;
2267 g = y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2);
2268 buff[cnt + channelMap[1]] = Clamp8(g >> shift);
2269 buff[cnt + channelMap[2]] = Clamp8((uAvg + g) >> shift);
2270 buff[cnt + channelMap[0]] = Clamp8((vAvg + g) >> shift);
2271 buff[cnt + channelMap[3]] = Clamp8(aAvg >> shift);
2274 if (j%2) sampledPos++;
2277 if (wOdd) sampledPos++;
2281 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2287 #ifdef __PGF32SUPPORT__
2290 ASSERT(m_header.channels == 1);
2291 ASSERT(m_header.bpp == 32);
2293 const int yuvOffset31 = 1 << (UsedBitsPerChannel() - 1);
2295 DataT* y = m_channel[0]; ASSERT(y);
2298 const int shift = 31 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2299 UINT32 *buff32 = (UINT32 *)buff;
2300 int pitch32 = pitch/4;
2302 for (i=0; i < h; i++) {
2303 for (j=0; j < w; j++) {
2304 buff32[j] = Clamp31((y[yPos++] + yuvOffset31) << shift);
2310 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2313 }
else if (bpp == 16) {
2314 const int usedBits = UsedBitsPerChannel();
2315 UINT16 *buff16 = (UINT16 *)buff;
2316 int pitch16 = pitch/2;
2318 if (usedBits < 16) {
2319 const int shift = 16 - usedBits;
2320 for (i=0; i < h; i++) {
2321 for (j=0; j < w; j++) {
2322 buff16[j] = Clamp16((y[yPos++] + yuvOffset31) << shift);
2328 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2332 const int shift =
__max(0, usedBits - 16);
2333 for (i=0; i < h; i++) {
2334 for (j=0; j < w; j++) {
2335 buff16[j] = Clamp16((y[yPos++] + yuvOffset31) >> shift);
2341 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2347 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2349 for (i=0; i < h; i++) {
2350 for (j=0; j < w; j++) {
2351 buff[j] = Clamp8((y[yPos++] + yuvOffset31) >> shift);
2357 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2366 ASSERT(m_header.channels == 3);
2367 ASSERT(m_header.bpp == m_header.channels*4);
2368 ASSERT(bpp == m_header.channels*4);
2369 ASSERT(!m_downsample);
2371 DataT* y = m_channel[0]; ASSERT(y);
2372 DataT* u = m_channel[1]; ASSERT(u);
2373 DataT* v = m_channel[2]; ASSERT(v);
2377 for (i=0; i < h; i++) {
2379 for (j=0; j < w; j++) {
2383 yval = Clamp4(y[yPos++] +
YUVoffset4 - ((uAvg + vAvg ) >> 2));
2385 buff[cnt] = UINT8(Clamp4(vAvg + yval) | (yval << 4));
2387 buff[cnt] = Clamp4(uAvg + yval);
2389 buff[cnt] |= Clamp4(vAvg + yval) << 4;
2391 buff[cnt] = UINT8(yval | (Clamp4(uAvg + yval) << 4));
2399 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2406 ASSERT(m_header.channels == 3);
2407 ASSERT(m_header.bpp == 16);
2409 ASSERT(!m_downsample);
2411 DataT* y = m_channel[0]; ASSERT(y);
2412 DataT* u = m_channel[1]; ASSERT(u);
2413 DataT* v = m_channel[2]; ASSERT(v);
2415 UINT16 *buff16 = (UINT16 *)buff;
2416 int pitch16 = pitch/2;
2418 for (i=0; i < h; i++) {
2419 for (j=0; j < w; j++) {
2423 yval = Clamp6(y[yPos++] +
YUVoffset6 - ((uAvg + vAvg ) >> 2));
2424 buff16[j] = (yval << 5) | ((Clamp6(uAvg + yval) >> 1) << 11) | (Clamp6(vAvg + yval) >> 1);
2430 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2439 #ifdef __PGFROISUPPORT__
2444 buff = buffStart + (levelRoi.
top - roi.
top)*pitch + (levelRoi.
left - roi.
left)*bypp;
2445 w = levelRoi.
Width()*bypp;
2448 for (i=0; i < h; i++) {
2449 for (j=0; j < w; j++) {
2450 targetBuff[j] = buff[j];
2452 targetBuff += targetPitch;
2459 delete[] buffStart; buffStart = 0;
2480 const UINT32 w = m_width[0];
2481 const UINT32 h = m_height[0];
2482 const bool wOdd = (1 == w%2);
2483 const int dataBits =
DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2486 const double dP = 1.0/h;
2488 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
2489 if (channelMap == NULL) channelMap = defMap;
2490 int sampledPos = 0, yPos = 0;
2495 if (m_header.channels == 3) {
2496 ASSERT(bpp%dataBits == 0);
2498 DataT* y = m_channel[0]; ASSERT(y);
2499 DataT* u = m_channel[1]; ASSERT(u);
2500 DataT* v = m_channel[2]; ASSERT(v);
2501 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2503 for (i=0; i < h; i++) {
2504 if (i%2) sampledPos -= (w + 1)/2;
2506 for (j=0; j < w; j++) {
2509 uAvg = u[sampledPos];
2510 vAvg = v[sampledPos];
2515 buff[cnt + channelMap[0]] = y[yPos];
2516 buff[cnt + channelMap[1]] = uAvg;
2517 buff[cnt + channelMap[2]] = vAvg;
2520 if (j%2) sampledPos++;
2523 if (wOdd) sampledPos++;
2527 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2530 }
else if (m_header.channels == 4) {
2531 ASSERT(m_header.bpp == m_header.channels*8);
2532 ASSERT(bpp%dataBits == 0);
2534 DataT* y = m_channel[0]; ASSERT(y);
2535 DataT* u = m_channel[1]; ASSERT(u);
2536 DataT* v = m_channel[2]; ASSERT(v);
2537 DataT* a = m_channel[3]; ASSERT(a);
2539 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2541 for (i=0; i < h; i++) {
2542 if (i%2) sampledPos -= (w + 1)/2;
2544 for (j=0; j < w; j++) {
2547 uAvg = u[sampledPos];
2548 vAvg = v[sampledPos];
2549 aAvg = Clamp8(a[sampledPos] + yuvOffset);
2553 aAvg = Clamp8(a[yPos] + yuvOffset);
2556 buff[cnt + channelMap[0]] = y[yPos];
2557 buff[cnt + channelMap[1]] = uAvg;
2558 buff[cnt + channelMap[2]] = vAvg;
2559 buff[cnt + channelMap[3]] = aAvg;
2562 if (j%2) sampledPos++;
2565 if (wOdd) sampledPos++;
2569 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2591 const double dP = 1.0/m_header.height;
2592 const int dataBits =
DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2596 int yPos = 0, cnt = 0;
2598 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
2600 if (channelMap == NULL) channelMap = defMap;
2602 if (m_header.channels == 3) {
2603 ASSERT(bpp%dataBits == 0);
2605 DataT* y = m_channel[0]; ASSERT(y);
2606 DataT* u = m_channel[1]; ASSERT(u);
2607 DataT* v = m_channel[2]; ASSERT(v);
2608 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2610 for (UINT32 h=0; h < m_header.height; h++) {
2612 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2617 for (UINT32 w=0; w < m_header.width; w++) {
2618 y[yPos] = buff[cnt + channelMap[0]];
2619 u[yPos] = buff[cnt + channelMap[1]];
2620 v[yPos] = buff[cnt + channelMap[2]];
2626 }
else if (m_header.channels == 4) {
2627 ASSERT(bpp%dataBits == 0);
2629 DataT* y = m_channel[0]; ASSERT(y);
2630 DataT* u = m_channel[1]; ASSERT(u);
2631 DataT* v = m_channel[2]; ASSERT(v);
2632 DataT* a = m_channel[3]; ASSERT(a);
2633 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2635 for (UINT32 h=0; h < m_header.height; h++) {
2637 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2642 for (UINT32 w=0; w < m_header.width; w++) {
2643 y[yPos] = buff[cnt + channelMap[0]];
2644 u[yPos] = buff[cnt + channelMap[1]];
2645 v[yPos] = buff[cnt + channelMap[2]];
2646 a[yPos] = buff[cnt + channelMap[3]] - yuvOffset;
2656 for (
int i=1; i < m_header.channels; i++) {