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;
61 , m_favorSpeedOverSize(false)
62 , m_useOMPinEncoder(true)
63 , m_useOMPinDecoder(true)
66 , m_streamReinitialized(false)
128 m_decoder =
new CDecoder(stream, m_preHeader, m_header, m_postHeader, m_levelLength, m_useOMPinDecoder);
130 if (m_header.nLevels >
MaxLevel) ReturnWithError(FormatCannotRead);
133 m_currentLevel = m_header.nLevels;
136 m_width[0] = m_header.width;
137 m_height[0] = m_header.height;
152 m_quant = m_header.quality - 1;
154 m_downsample =
false;
155 m_quant = m_header.quality;
160 for (
int i=1; i < m_header.channels; i++) {
161 m_width[i] = (m_width[0] + 1)/2;
162 m_height[i] = (m_height[0] + 1)/2;
165 for (
int i=1; i < m_header.channels; i++) {
166 m_width[i] = m_width[0];
167 m_height[i] = m_height[0];
171 if (m_header.nLevels > 0) {
173 for (
int i=0; i < m_header.channels; i++) {
174 m_wtChannel[i] =
new CWaveletTransform(m_width[i], m_height[i], m_header.nLevels);
180 for (
int c=0; c < m_header.channels; c++) {
181 const UINT32 size = m_width[c]*m_height[c];
182 m_channel[c] =
new DataT[size];
185 for (UINT32 i=0; i < size; i++) {
187 stream->Read(&count, &m_channel[c][i]);
188 if (count !=
DataTSize) ReturnWithError(MissingData);
232 #ifdef __PGF32SUPPORT__
273 #ifdef __PGF32SUPPORT__
299 if (bpc > 31) bpc = 31;
320 if (m_header.nLevels == 0) {
323 for (
int i=0; i < m_header.channels; i++) {
324 ASSERT(m_wtChannel[i]);
325 m_channel[i] = m_wtChannel[i]->GetSubband(0,
LL)->GetBuffer();
329 int currentLevel = m_header.nLevels;
331 if (ROIisSupported()) {
333 SetROI(
PGFRect(0, 0, m_header.width, m_header.height));
336 while (currentLevel > level) {
337 for (
int i=0; i < m_header.channels; i++) {
338 ASSERT(m_wtChannel[i]);
340 if (currentLevel == m_header.nLevels) {
342 m_wtChannel[i]->GetSubband(currentLevel,
LL)->Dequantize(m_quant);
344 m_wtChannel[i]->GetSubband(currentLevel,
HL)->Dequantize(m_quant);
345 m_wtChannel[i]->GetSubband(currentLevel,
LH)->Dequantize(m_quant);
346 m_wtChannel[i]->GetSubband(currentLevel,
HH)->Dequantize(m_quant);
349 if (!m_wtChannel[i]->InverseTransform(currentLevel, &m_width[i], &m_height[i], &m_channel[i])) ReturnWithError(InsufficientMemory);
350 ASSERT(m_channel[i]);
371 ASSERT((level >= 0 && level < m_header.nLevels) || m_header.nLevels == 0);
374 #ifdef __PGFROISUPPORT__
375 if (ROIisSupported() && m_header.nLevels > 0) {
377 PGFRect rect(0, 0, m_header.width, m_header.height);
378 Read(rect, level, cb, data);
383 if (m_header.nLevels == 0) {
388 if ((*cb)(1.0,
true, data)) ReturnWithError(EscapePressed);
392 const int levelDiff = m_currentLevel - level;
393 double percent = pow(0.25, levelDiff);
396 while (m_currentLevel > level) {
397 for (
int i=0; i < m_header.channels; i++) {
398 ASSERT(m_wtChannel[i]);
400 if (m_currentLevel == m_header.nLevels) {
402 m_wtChannel[i]->GetSubband(m_currentLevel,
LL)->PlaceTile(*m_decoder, m_quant);
404 if (m_preHeader.version &
Version5) {
406 m_wtChannel[i]->GetSubband(m_currentLevel,
HL)->PlaceTile(*m_decoder, m_quant);
407 m_wtChannel[i]->GetSubband(m_currentLevel,
LH)->PlaceTile(*m_decoder, m_quant);
410 m_decoder->DecodeInterleaved(m_wtChannel[i], m_currentLevel, m_quant);
412 m_wtChannel[i]->GetSubband(m_currentLevel,
HH)->PlaceTile(*m_decoder, m_quant);
415 volatile OSError error = NoError;
416 #pragma omp parallel for default(shared)
417 for (
int i=0; i < m_header.channels; i++) {
419 if (error == NoError) {
420 OSError err = m_wtChannel[i]->InverseTransform(m_currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
421 if (err != NoError) error = err;
423 ASSERT(m_channel[i]);
425 if (error != NoError) ReturnWithError(error);
431 if (m_cb) m_cb(m_cbArg);
435 percent += 3*percent;
436 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
442 if (m_currentLevel == 0) Close();
445 #ifdef __PGFROISUPPORT__
456 ASSERT((level >= 0 && level < m_header.nLevels) || m_header.nLevels == 0);
459 if (m_header.nLevels == 0 || !ROIisSupported()) {
460 rect.left = rect.top = 0;
461 rect.right = m_header.width; rect.bottom = m_header.height;
462 Read(level, cb, data);
464 ASSERT(ROIisSupported());
466 ASSERT(rect.left < m_header.width && rect.top < m_header.height);
467 const int levelDiff = m_currentLevel - level;
468 double percent = pow(0.25, levelDiff);
471 if (levelDiff <= 0) {
473 m_currentLevel = m_header.nLevels;
474 m_decoder->SetStreamPosToData();
478 if (rect.right == 0 || rect.right > m_header.width) rect.right = m_header.width;
479 if (rect.bottom == 0 || rect.bottom > m_header.height) rect.bottom = m_header.height;
484 while (m_currentLevel > level) {
485 for (
int i=0; i < m_header.channels; i++) {
486 ASSERT(m_wtChannel[i]);
489 const UINT32 nTiles = m_wtChannel[i]->GetNofTiles(m_currentLevel);
490 const PGFRect& tileIndices = m_wtChannel[i]->GetTileIndices(m_currentLevel);
493 if (m_currentLevel == m_header.nLevels) {
495 m_decoder->DecodeTileBuffer();
496 m_wtChannel[i]->GetSubband(m_currentLevel,
LL)->PlaceTile(*m_decoder, m_quant);
498 for (UINT32 tileY=0; tileY < nTiles; tileY++) {
499 for (UINT32 tileX=0; tileX < nTiles; tileX++) {
501 if (tileIndices.
IsInside(tileX, tileY)) {
502 m_decoder->DecodeTileBuffer();
503 m_wtChannel[i]->GetSubband(m_currentLevel,
HL)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
504 m_wtChannel[i]->GetSubband(m_currentLevel,
LH)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
505 m_wtChannel[i]->GetSubband(m_currentLevel,
HH)->PlaceTile(*m_decoder, m_quant,
true, tileX, tileY);
508 m_decoder->SkipTileBuffer();
514 volatile OSError error = NoError;
515 #pragma omp parallel for default(shared)
516 for (
int i=0; i < m_header.channels; i++) {
518 if (error == NoError) {
519 OSError err = m_wtChannel[i]->InverseTransform(m_currentLevel, &m_width[i], &m_height[i], &m_channel[i]);
520 if (err != NoError) error = err;
522 ASSERT(m_channel[i]);
524 if (error != NoError) ReturnWithError(error);
530 if (m_cb) m_cb(m_cbArg);
534 percent += 3*percent;
535 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
541 if (m_currentLevel == 0) Close();
562 else rect.
left -= dx;
563 if (rect.
top < dy) rect.
top = 0;
586 #endif // __PGFROISUPPORT__
606 ASSERT(targetLen > 0);
610 m_decoder->SetStreamPosToStart();
613 UINT32 len =
__min(targetLen, GetEncodedHeaderLength());
616 len = m_decoder->ReadEncodedData(target, len);
617 ASSERT(len >= 0 && len <= targetLen);
639 ASSERT(level >= 0 && level < m_header.nLevels);
641 ASSERT(targetLen > 0);
645 m_decoder->SetStreamPosToData();
650 for (
int i=m_header.nLevels - 1; i > level; i--) {
651 offset += m_levelLength[m_header.nLevels - 1 - i];
653 m_decoder->Skip(offset);
656 UINT32 len =
__min(targetLen, GetEncodedLevelLength(level));
659 len = m_decoder->ReadEncodedData(target, len);
660 ASSERT(len >= 0 && len <= targetLen);
688 while(maxValue > 0) {
693 if (pot > bpc) pot = bpc;
694 if (pot > 31) pot = 31;
739 ASSERT(m_channel[0]);
742 RgbToYuv(pitch, buff, bpp, channelMap, cb, data);
746 for (
int i=1; i < m_header.channels; i++) {
760 const int oddW = w%2;
768 for (i=0; i < h2; i++) {
769 for (j=0; j < w2; j++) {
771 buff[sampledPos] = (buff[loPos] + buff[loPos + 1] + buff[hiPos] + buff[hiPos + 1]) >> 2;
772 loPos += 2; hiPos += 2;
776 buff[sampledPos] = (buff[loPos] + buff[hiPos]) >> 1;
780 loPos += w; hiPos += w;
783 for (j=0; j < w2; j++) {
784 buff[sampledPos] = (buff[loPos] + buff[loPos+1]) >> 1;
785 loPos += 2; hiPos += 2;
789 buff[sampledPos] = buff[loPos];
807 while (s > maxThumbnailWidth) {
841 #ifdef __PGFROISUPPORT__
843 m_streamReinitialized =
false;
847 memcpy(m_preHeader.magic,
Magic, 3);
869 m_quant = m_header.quality - 1;
871 m_downsample =
false;
872 m_quant = m_header.quality;
879 if (userDataLength && userData) {
880 m_postHeader.userData =
new(std::nothrow) UINT8[userDataLength];
881 if (!m_postHeader.userData) ReturnWithError(InsufficientMemory);
882 m_postHeader.userDataLen = userDataLength;
883 memcpy(m_postHeader.userData, userData, userDataLength);
884 m_preHeader.hSize += userDataLength;
888 for (
int i=0; i < m_header.channels; i++) {
890 m_width[i] = m_header.width;
891 m_height[i] = m_header.height;
894 ASSERT(!m_channel[i]);
895 m_channel[i] =
new(std::nothrow)
DataT[m_header.width*m_header.height];
899 delete[] m_channel[i]; m_channel[i] = 0;
902 ReturnWithError(InsufficientMemory);
915 ASSERT(m_header.nLevels <=
MaxLevel);
918 if (m_header.nLevels > 0) {
919 volatile OSError error = NoError;
921 #pragma omp parallel for default(shared)
922 for (
int i=0; i < m_header.channels; i++) {
924 if (error == NoError) {
925 if (m_wtChannel[i]) {
926 ASSERT(m_channel[i]);
928 int size = m_height[i]*m_width[i];
929 temp =
new(std::nothrow)
DataT[size];
931 memcpy(temp, m_channel[i], size*
DataTSize);
932 delete m_wtChannel[i];
934 error = InsufficientMemory;
937 if (error == NoError) {
938 if (temp) m_channel[i] = temp;
939 m_wtChannel[i] =
new CWaveletTransform(m_width[i], m_height[i], m_header.nLevels, m_channel[i]);
942 for (
int l=0; error == NoError && l < m_header.nLevels; l++) {
943 OSError err = m_wtChannel[i]->ForwardTransform(l, m_quant);
944 if (err != NoError) error = err;
949 if (error != NoError) ReturnWithError(error);
951 m_currentLevel = m_header.nLevels;
953 #ifdef __PGFROISUPPORT__
955 m_preHeader.version |=
PGFROI;
960 m_encoder =
new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_levelLength, m_useOMPinEncoder);
961 if (m_favorSpeedOverSize) m_encoder->FavorSpeedOverSize();
963 #ifdef __PGFROISUPPORT__
964 if (ROIisSupported()) {
971 return m_encoder->ComputeHeaderLength();
977 m_encoder =
new CEncoder(stream, m_preHeader, m_header, m_postHeader, m_levelLength, m_useOMPinEncoder);
980 for (
int c=0; c < m_header.channels; c++) {
981 const UINT32 size = m_width[c]*m_height[c];
984 for (UINT32 i=0; i < size; i++) {
986 stream->Write(&count, &m_channel[c][i]);
991 UINT32 nBytes = m_encoder->WriteLevelLength();
994 delete m_encoder; m_encoder = NULL;
1014 #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) {
1079 ASSERT(m_preHeader.hSize);
1081 #ifdef __PGFROISUPPORT__
1083 m_levelwise =
false;
1087 WriteHeader(stream);
1089 int levels = m_header.nLevels;
1090 double percent = pow(0.25, levels - 1);
1096 if ((*cb)(1,
true, data)) ReturnWithError(EscapePressed);
1104 for (m_currentLevel = levels; m_currentLevel > 0; ) {
1110 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1116 UINT32 nBytes = m_encoder->WriteLevelLength();
1119 delete m_encoder; m_encoder = NULL;
1122 if (nWrittenBytes) *nWrittenBytes += nBytes;
1128 #ifdef __PGFROISUPPORT__
1144 ASSERT(m_header.nLevels > 0);
1145 ASSERT(0 <= level && level < m_header.nLevels);
1147 ASSERT(ROIisSupported());
1150 UINT32 diff = m_encoder->ComputeBufferLength();
1152 m_streamReinitialized =
true;
1153 m_encoder->SetBufferStartPos();
1156 const int levelDiff = m_currentLevel - level;
1157 double percent = pow(0.25, levelDiff);
1158 UINT32 nWrittenBytes = 0;
1159 int levelIndex = m_header.nLevels - 1 - m_currentLevel;
1162 while (m_currentLevel > level) {
1167 if (m_levelLength) nWrittenBytes += m_levelLength[levelIndex];
1172 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1177 if (m_currentLevel == 0) {
1178 if (!m_streamReinitialized) {
1180 m_encoder->WriteLevelLength();
1183 delete m_encoder; m_encoder = NULL;
1186 return nWrittenBytes;
1188 #endif // __PGFROISUPPORT__
1241 if (iFirstColor + nColors >
ColorTableLen) ReturnWithError(ColorTableError);
1243 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1244 prgbColors[j] = m_postHeader.clut[i];
1255 if (iFirstColor + nColors >
ColorTableLen) ReturnWithError(ColorTableError);
1257 for (UINT32 i=iFirstColor, j=0; j < nColors; i++, j++) {
1258 m_postHeader.clut[i] = prgbColors[j];
1279 void CPGFImage::RgbToYuv(
int pitch, UINT8* buff, BYTE bpp,
int channelMap[], CallbackPtr cb,
void *data ) THROW_ {
1281 int yPos = 0, cnt = 0;
1283 const double dP = 1.0/m_header.height;
1284 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
1286 if (channelMap == NULL) channelMap = defMap;
1288 switch(m_header.mode) {
1291 ASSERT(m_header.channels == 1);
1292 ASSERT(m_header.bpp == 1);
1295 const UINT32 w = m_header.width;
1296 const UINT32 w2 = (m_header.width + 7)/8;
1297 DataT* y = m_channel[0]; ASSERT(y);
1299 for (UINT32 h=0; h < m_header.height; h++) {
1301 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1305 for (UINT32 j=0; j < w2; j++) {
1308 for (UINT32 j=w2; j < w; j++) {
1331 ASSERT(m_header.channels >= 1);
1332 ASSERT(m_header.bpp == m_header.channels*8);
1334 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1336 for (UINT32 h=0; h < m_header.height; h++) {
1338 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1343 for (UINT32 w=0; w < m_header.width; w++) {
1344 for (
int c=0; c < m_header.channels; c++) {
1345 m_channel[c][yPos] = buff[cnt + channelMap[c]] -
YUVoffset8;
1357 ASSERT(m_header.channels >= 1);
1358 ASSERT(m_header.bpp == m_header.channels*16);
1359 ASSERT(bpp%16 == 0);
1361 UINT16 *buff16 = (UINT16 *)buff;
1362 const int pitch16 = pitch/2;
1363 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1364 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1365 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1367 for (UINT32 h=0; h < m_header.height; h++) {
1369 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1374 for (UINT32 w=0; w < m_header.width; w++) {
1375 for (
int c=0; c < m_header.channels; c++) {
1376 m_channel[c][yPos] = (buff16[cnt + channelMap[c]] >> shift) - yuvOffset16;
1387 ASSERT(m_header.channels == 3);
1388 ASSERT(m_header.bpp == m_header.channels*8);
1391 DataT* y = m_channel[0]; ASSERT(y);
1392 DataT* u = m_channel[1]; ASSERT(u);
1393 DataT* v = m_channel[2]; ASSERT(v);
1394 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1397 for (UINT32 h=0; h < m_header.height; h++) {
1399 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1404 for (UINT32 w=0; w < m_header.width; w++) {
1405 b = buff[cnt + channelMap[0]];
1406 g = buff[cnt + channelMap[1]];
1407 r = buff[cnt + channelMap[2]];
1409 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset8;
1421 ASSERT(m_header.channels == 3);
1422 ASSERT(m_header.bpp == m_header.channels*16);
1423 ASSERT(bpp%16 == 0);
1425 UINT16 *buff16 = (UINT16 *)buff;
1426 const int pitch16 = pitch/2;
1427 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1428 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1429 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1431 DataT* y = m_channel[0]; ASSERT(y);
1432 DataT* u = m_channel[1]; ASSERT(u);
1433 DataT* v = m_channel[2]; ASSERT(v);
1436 for (UINT32 h=0; h < m_header.height; h++) {
1438 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1443 for (UINT32 w=0; w < m_header.width; w++) {
1444 b = buff16[cnt + channelMap[0]] >> shift;
1445 g = buff16[cnt + channelMap[1]] >> shift;
1446 r = buff16[cnt + channelMap[2]] >> shift;
1448 y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1461 ASSERT(m_header.channels == 4);
1462 ASSERT(m_header.bpp == m_header.channels*8);
1464 const int channels = bpp/8; ASSERT(channels >= m_header.channels);
1466 DataT* y = m_channel[0]; ASSERT(y);
1467 DataT* u = m_channel[1]; ASSERT(u);
1468 DataT* v = m_channel[2]; ASSERT(v);
1469 DataT* a = m_channel[3]; ASSERT(a);
1472 for (UINT32 h=0; h < m_header.height; h++) {
1474 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1479 for (UINT32 w=0; w < m_header.width; w++) {
1480 b = buff[cnt + channelMap[0]];
1481 g = buff[cnt + channelMap[1]];
1482 r = buff[cnt + channelMap[2]];
1484 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset8;
1487 a[yPos++] = buff[cnt + channelMap[3]] -
YUVoffset8;
1496 ASSERT(m_header.channels == 4);
1497 ASSERT(m_header.bpp == m_header.channels*16);
1498 ASSERT(bpp%16 == 0);
1500 UINT16 *buff16 = (UINT16 *)buff;
1501 const int pitch16 = pitch/2;
1502 const int channels = bpp/16; ASSERT(channels >= m_header.channels);
1503 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1504 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1506 DataT* y = m_channel[0]; ASSERT(y);
1507 DataT* u = m_channel[1]; ASSERT(u);
1508 DataT* v = m_channel[2]; ASSERT(v);
1509 DataT* a = m_channel[3]; ASSERT(a);
1512 for (UINT32 h=0; h < m_header.height; h++) {
1514 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1519 for (UINT32 w=0; w < m_header.width; w++) {
1520 b = buff16[cnt + channelMap[0]] >> shift;
1521 g = buff16[cnt + channelMap[1]] >> shift;
1522 r = buff16[cnt + channelMap[2]] >> shift;
1524 y[yPos] = ((b + (g << 1) + r) >> 2) - yuvOffset16;
1527 a[yPos++] = (buff16[cnt + channelMap[3]] >> shift) - yuvOffset16;
1534 #ifdef __PGF32SUPPORT__
1537 ASSERT(m_header.channels == 1);
1538 ASSERT(m_header.bpp == 32);
1542 DataT* y = m_channel[0]; ASSERT(y);
1544 UINT32 *buff32 = (UINT32 *)buff;
1545 const int pitch32 = pitch/4;
1546 const int shift = 32 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1547 const DataT yuvOffset32 = 1 << (UsedBitsPerChannel() - 1);
1549 for (UINT32 h=0; h < m_header.height; h++) {
1551 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1555 for (UINT32 w=0; w < m_header.width; w++) {
1556 y[yPos++] = (buff32[w] >> shift) - yuvOffset32;
1565 ASSERT(m_header.channels == 3);
1566 ASSERT(m_header.bpp == m_header.channels*4);
1567 ASSERT(bpp == m_header.channels*4);
1569 DataT* y = m_channel[0]; ASSERT(y);
1570 DataT* u = m_channel[1]; ASSERT(u);
1571 DataT* v = m_channel[2]; ASSERT(v);
1573 UINT8 rgb = 0, b, g, r;
1575 for (UINT32 h=0; h < m_header.height; h++) {
1577 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1582 for (UINT32 w=0; w < m_header.width; w++) {
1587 g = (rgb & 0xF0) >> 4;
1593 b = (rgb & 0xF0) >> 4;
1597 r = (rgb & 0xF0) >> 4;
1602 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset4;
1613 ASSERT(m_header.channels == 3);
1614 ASSERT(m_header.bpp == 16);
1617 DataT* y = m_channel[0]; ASSERT(y);
1618 DataT* u = m_channel[1]; ASSERT(u);
1619 DataT* v = m_channel[2]; ASSERT(v);
1621 UINT16 *buff16 = (UINT16 *)buff;
1622 UINT16 rgb, b, g, r;
1623 const int pitch16 = pitch/2;
1625 for (UINT32 h=0; h < m_header.height; h++) {
1627 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1630 for (UINT32 w=0; w < m_header.width; w++) {
1632 r = (rgb & 0xF800) >> 10;
1633 g = (rgb & 0x07E0) >> 5;
1634 b = (rgb & 0x001F) << 1;
1636 y[yPos] = ((b + (g << 1) + r) >> 2) -
YUVoffset6;
1668 void CPGFImage::GetBitmap(
int pitch, UINT8* buff, BYTE bpp,
int channelMap[] , CallbackPtr cb ,
void *data )
const THROW_ {
1670 UINT32 w = m_width[0];
1671 UINT32 h = m_height[0];
1672 UINT8* targetBuff = 0;
1673 UINT8* buffStart = 0;
1674 int targetPitch = 0;
1676 #ifdef __PGFROISUPPORT__
1677 const PGFRect& roi = (ROIisSupported()) ? m_wtChannel[0]->GetROI(m_currentLevel) :
PGFRect(0, 0, w, h);
1678 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));
1683 if (ROIisSupported() && (levelRoi.
Width() < w || levelRoi.
Height() < h)) {
1686 targetPitch = pitch;
1691 buff = buffStart =
new(std::nothrow) UINT8[pitch*h];
1692 if (!buff) ReturnWithError(InsufficientMemory);
1696 const bool wOdd = (1 == w%2);
1698 const double dP = 1.0/h;
1699 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
1700 if (channelMap == NULL) channelMap = defMap;
1701 int sampledPos = 0, yPos = 0;
1706 switch(m_header.mode) {
1709 ASSERT(m_header.channels == 1);
1710 ASSERT(m_header.bpp == 1);
1713 const UINT32 w2 = (w + 7)/8;
1714 DataT* y = m_channel[0]; ASSERT(y);
1716 for (i=0; i < h; i++) {
1718 for (j=0; j < w2; j++) {
1738 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1748 ASSERT(m_header.channels >= 1);
1749 ASSERT(m_header.bpp == m_header.channels*8);
1752 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
1754 for (i=0; i < h; i++) {
1756 for (j=0; j < w; j++) {
1757 for (
int c=0; c < m_header.channels; c++) {
1758 buff[cnt + channelMap[c]] = Clamp8(m_channel[c][yPos] +
YUVoffset8);
1767 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1774 ASSERT(m_header.channels >= 1);
1775 ASSERT(m_header.bpp == m_header.channels*16);
1777 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1781 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1782 UINT16 *buff16 = (UINT16 *)buff;
1783 int pitch16 = pitch/2;
1784 channels = bpp/16; ASSERT(channels >= m_header.channels);
1786 for (i=0; i < h; i++) {
1788 for (j=0; j < w; j++) {
1789 for (
int c=0; c < m_header.channels; c++) {
1790 buff16[cnt + channelMap[c]] = Clamp16(m_channel[c][yPos] + yuvOffset16) << shift;
1799 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1804 const int shift =
__max(0, UsedBitsPerChannel() - 8);
1805 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]] = UINT8(Clamp16(m_channel[c][yPos] + yuvOffset16) >> shift);
1820 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1828 ASSERT(m_header.channels == 3);
1829 ASSERT(m_header.bpp == m_header.channels*8);
1831 ASSERT(bpp >= m_header.bpp);
1833 DataT* y = m_channel[0]; ASSERT(y);
1834 DataT* u = m_channel[1]; ASSERT(u);
1835 DataT* v = m_channel[2]; ASSERT(v);
1836 UINT8 *buffg = &buff[channelMap[1]],
1837 *buffr = &buff[channelMap[2]],
1838 *buffb = &buff[channelMap[0]];
1840 int cnt, channels = bpp/8;
1842 for (i=0; i < h; i++) {
1843 if (i%2) sampledPos -= (w + 1)/2;
1845 for (j=0; j < w; j++) {
1847 uAvg = u[sampledPos];
1848 vAvg = v[sampledPos];
1850 buffg[cnt] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
1851 buffr[cnt] = Clamp8(uAvg + g);
1852 buffb[cnt] = Clamp8(vAvg + g);
1855 if (j%2) sampledPos++;
1860 if (wOdd) sampledPos++;
1863 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1867 for (i=0; i < h; i++) {
1869 for (j = 0; j < w; j++) {
1873 buffg[cnt] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
1874 buffr[cnt] = Clamp8(uAvg + g);
1875 buffb[cnt] = Clamp8(vAvg + g);
1885 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1893 ASSERT(m_header.channels == 3);
1894 ASSERT(m_header.bpp == 48);
1896 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
1898 DataT* y = m_channel[0]; ASSERT(y);
1899 DataT* u = m_channel[1]; ASSERT(u);
1900 DataT* v = m_channel[2]; ASSERT(v);
1904 if (bpp >= 48 && bpp%16 == 0) {
1905 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
1906 UINT16 *buff16 = (UINT16 *)buff;
1907 int pitch16 = pitch/2;
1908 channels = bpp/16; ASSERT(channels >= m_header.channels);
1910 for (i=0; i < h; i++) {
1911 if (i%2) sampledPos -= (w + 1)/2;
1913 for (j=0; j < w; j++) {
1916 uAvg = u[sampledPos];
1917 vAvg = v[sampledPos];
1923 g = Clamp16(y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2));
1924 buff16[cnt + channelMap[1]] = g << shift;
1925 buff16[cnt + channelMap[2]] = Clamp16(uAvg + g) << shift;
1926 buff16[cnt + channelMap[0]] = Clamp16(vAvg + g) << shift;
1929 if (j%2) sampledPos++;
1932 if (wOdd) sampledPos++;
1936 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1941 const int shift =
__max(0, UsedBitsPerChannel() - 8);
1942 channels = bpp/8; ASSERT(channels >= m_header.channels);
1944 for (i=0; i < h; i++) {
1945 if (i%2) sampledPos -= (w + 1)/2;
1947 for (j=0; j < w; j++) {
1950 uAvg = u[sampledPos];
1951 vAvg = v[sampledPos];
1957 g = Clamp16(y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2));
1958 buff[cnt + channelMap[1]] = UINT8(g >> shift);
1959 buff[cnt + channelMap[2]] = UINT8(Clamp16(uAvg + g) >> shift);
1960 buff[cnt + channelMap[0]] = UINT8(Clamp16(vAvg + g) >> shift);
1963 if (j%2) sampledPos++;
1966 if (wOdd) sampledPos++;
1970 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
1978 ASSERT(m_header.channels == 3);
1979 ASSERT(m_header.bpp == m_header.channels*8);
1982 DataT* l = m_channel[0]; ASSERT(l);
1983 DataT* a = m_channel[1]; ASSERT(a);
1984 DataT* b = m_channel[2]; ASSERT(b);
1985 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
1987 for (i=0; i < h; i++) {
1988 if (i%2) sampledPos -= (w + 1)/2;
1990 for (j=0; j < w; j++) {
1993 uAvg = a[sampledPos];
1994 vAvg = b[sampledPos];
1999 buff[cnt + channelMap[0]] = Clamp8(l[yPos] +
YUVoffset8);
2000 buff[cnt + channelMap[1]] = Clamp8(uAvg +
YUVoffset8);
2001 buff[cnt + channelMap[2]] = Clamp8(vAvg +
YUVoffset8);
2004 if (j%2) sampledPos++;
2007 if (wOdd) sampledPos++;
2011 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2018 ASSERT(m_header.channels == 3);
2019 ASSERT(m_header.bpp == m_header.channels*16);
2021 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2023 DataT* l = m_channel[0]; ASSERT(l);
2024 DataT* a = m_channel[1]; ASSERT(a);
2025 DataT* b = m_channel[2]; ASSERT(b);
2029 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2030 UINT16 *buff16 = (UINT16 *)buff;
2031 int pitch16 = pitch/2;
2032 channels = bpp/16; ASSERT(channels >= m_header.channels);
2034 for (i=0; i < h; i++) {
2035 if (i%2) sampledPos -= (w + 1)/2;
2037 for (j=0; j < w; j++) {
2040 uAvg = a[sampledPos];
2041 vAvg = b[sampledPos];
2046 buff16[cnt + channelMap[0]] = Clamp16(l[yPos] + yuvOffset16) << shift;
2047 buff16[cnt + channelMap[1]] = Clamp16(uAvg + yuvOffset16) << shift;
2048 buff16[cnt + channelMap[2]] = Clamp16(vAvg + yuvOffset16) << shift;
2051 if (j%2) sampledPos++;
2054 if (wOdd) sampledPos++;
2058 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2063 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2064 channels = bpp/8; ASSERT(channels >= m_header.channels);
2066 for (i=0; i < h; i++) {
2067 if (i%2) sampledPos -= (w + 1)/2;
2069 for (j=0; j < w; j++) {
2072 uAvg = a[sampledPos];
2073 vAvg = b[sampledPos];
2078 buff[cnt + channelMap[0]] = UINT8(Clamp16(l[yPos] + yuvOffset16) >> shift);
2079 buff[cnt + channelMap[1]] = UINT8(Clamp16(uAvg + yuvOffset16) >> shift);
2080 buff[cnt + channelMap[2]] = UINT8(Clamp16(vAvg + yuvOffset16) >> shift);
2083 if (j%2) sampledPos++;
2086 if (wOdd) sampledPos++;
2090 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2099 ASSERT(m_header.channels == 4);
2100 ASSERT(m_header.bpp == m_header.channels*8);
2103 DataT* y = m_channel[0]; ASSERT(y);
2104 DataT* u = m_channel[1]; ASSERT(u);
2105 DataT* v = m_channel[2]; ASSERT(v);
2106 DataT* a = m_channel[3]; ASSERT(a);
2108 int cnt, channels = bpp/8; ASSERT(channels >= m_header.channels);
2110 for (i=0; i < h; i++) {
2111 if (i%2) sampledPos -= (w + 1)/2;
2113 for (j=0; j < w; j++) {
2116 uAvg = u[sampledPos];
2117 vAvg = v[sampledPos];
2125 buff[cnt + channelMap[1]] = g = Clamp8(y[yPos] +
YUVoffset8 - ((uAvg + vAvg ) >> 2));
2126 buff[cnt + channelMap[2]] = Clamp8(uAvg + g);
2127 buff[cnt + channelMap[0]] = Clamp8(vAvg + g);
2128 buff[cnt + channelMap[3]] = aAvg;
2131 if (j%2) sampledPos++;
2134 if (wOdd) sampledPos++;
2138 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2145 ASSERT(m_header.channels == 4);
2146 ASSERT(m_header.bpp == 64);
2148 const DataT yuvOffset16 = 1 << (UsedBitsPerChannel() - 1);
2150 DataT* y = m_channel[0]; ASSERT(y);
2151 DataT* u = m_channel[1]; ASSERT(u);
2152 DataT* v = m_channel[2]; ASSERT(v);
2153 DataT* a = m_channel[3]; ASSERT(a);
2158 const int shift = 16 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2159 UINT16 *buff16 = (UINT16 *)buff;
2160 int pitch16 = pitch/2;
2161 channels = bpp/16; 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];
2171 aAvg = Clamp16(a[sampledPos] + yuvOffset16);
2175 aAvg = Clamp16(a[yPos] + yuvOffset16);
2178 g = Clamp16(y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2));
2179 buff16[cnt + channelMap[1]] = g << shift;
2180 buff16[cnt + channelMap[2]] = Clamp16(uAvg + g) << shift;
2181 buff16[cnt + channelMap[0]] = Clamp16(vAvg + g) << shift;
2182 buff16[cnt + channelMap[3]] = aAvg << shift;
2185 if (j%2) sampledPos++;
2188 if (wOdd) sampledPos++;
2192 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2197 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2198 channels = bpp/8; ASSERT(channels >= m_header.channels);
2200 for (i=0; i < h; i++) {
2201 if (i%2) sampledPos -= (w + 1)/2;
2203 for (j=0; j < w; j++) {
2206 uAvg = u[sampledPos];
2207 vAvg = v[sampledPos];
2208 aAvg = Clamp16(a[sampledPos] + yuvOffset16);
2212 aAvg = Clamp16(a[yPos] + yuvOffset16);
2215 g = Clamp16(y[yPos] + yuvOffset16 - ((uAvg + vAvg ) >> 2));
2216 buff[cnt + channelMap[1]] = UINT8(g >> shift);
2217 buff[cnt + channelMap[2]] = UINT8(Clamp16(uAvg + g) >> shift);
2218 buff[cnt + channelMap[0]] = UINT8(Clamp16(vAvg + g) >> shift);
2219 buff[cnt + channelMap[3]] = UINT8(aAvg >> shift);
2222 if (j%2) sampledPos++;
2225 if (wOdd) sampledPos++;
2229 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2235 #ifdef __PGF32SUPPORT__
2238 ASSERT(m_header.channels == 1);
2239 ASSERT(m_header.bpp == 32);
2241 const int yuvOffset32 = 1 << (UsedBitsPerChannel() - 1);
2243 DataT* y = m_channel[0]; ASSERT(y);
2246 const int shift = 32 - UsedBitsPerChannel(); ASSERT(shift >= 0);
2247 UINT32 *buff32 = (UINT32 *)buff;
2248 int pitch32 = pitch/4;
2250 for (i=0; i < h; i++) {
2251 for (j=0; j < w; j++) {
2252 buff32[j] = Clamp31(y[yPos++] + yuvOffset32) << shift;
2258 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2261 }
else if (bpp == 16) {
2262 const int usedBits = UsedBitsPerChannel();
2263 UINT16 *buff16 = (UINT16 *)buff;
2264 int pitch16 = pitch/2;
2266 if (usedBits < 16) {
2267 const int shift = 16 - usedBits;
2268 for (i=0; i < h; i++) {
2269 for (j=0; j < w; j++) {
2270 buff16[j] = Clamp16(y[yPos++] + yuvOffset32) << shift;
2276 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2280 const int shift =
__max(0, usedBits - 16);
2281 for (i=0; i < h; i++) {
2282 for (j=0; j < w; j++) {
2283 buff16[j] = UINT16(Clamp31(y[yPos++] + yuvOffset32) >> shift);
2289 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2295 const int shift =
__max(0, UsedBitsPerChannel() - 8);
2297 for (i=0; i < h; i++) {
2298 for (j=0; j < w; j++) {
2299 buff[j] = UINT8(Clamp31(y[yPos++] + yuvOffset32) >> shift);
2305 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2314 ASSERT(m_header.channels == 3);
2315 ASSERT(m_header.bpp == m_header.channels*4);
2316 ASSERT(bpp == m_header.channels*4);
2317 ASSERT(!m_downsample);
2319 DataT* y = m_channel[0]; ASSERT(y);
2320 DataT* u = m_channel[1]; ASSERT(u);
2321 DataT* v = m_channel[2]; ASSERT(v);
2325 for (i=0; i < h; i++) {
2327 for (j=0; j < w; j++) {
2331 yval = Clamp4(y[yPos++] +
YUVoffset4 - ((uAvg + vAvg ) >> 2));
2333 buff[cnt] = UINT8(Clamp4(vAvg + yval) | (yval << 4));
2335 buff[cnt] = Clamp4(uAvg + yval);
2337 buff[cnt] |= Clamp4(vAvg + yval) << 4;
2339 buff[cnt] = UINT8(yval | (Clamp4(uAvg + yval) << 4));
2347 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2354 ASSERT(m_header.channels == 3);
2355 ASSERT(m_header.bpp == 16);
2357 ASSERT(!m_downsample);
2359 DataT* y = m_channel[0]; ASSERT(y);
2360 DataT* u = m_channel[1]; ASSERT(u);
2361 DataT* v = m_channel[2]; ASSERT(v);
2363 UINT16 *buff16 = (UINT16 *)buff;
2364 int pitch16 = pitch/2;
2366 for (i=0; i < h; i++) {
2367 for (j=0; j < w; j++) {
2371 yval = Clamp6(y[yPos++] +
YUVoffset6 - ((uAvg + vAvg ) >> 2));
2372 buff16[j] = (yval << 5) | ((Clamp6(uAvg + yval) >> 1) << 11) | (Clamp6(vAvg + yval) >> 1);
2378 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2387 #ifdef __PGFROISUPPORT__
2392 buff = buffStart + (levelRoi.
top - roi.
top)*pitch + (levelRoi.
left - roi.
left)*bypp;
2393 w = levelRoi.
Width()*bypp;
2396 for (i=0; i < h; i++) {
2397 for (j=0; j < w; j++) {
2398 targetBuff[j] = buff[j];
2400 targetBuff += targetPitch;
2428 const UINT32 w = m_width[0];
2429 const UINT32 h = m_height[0];
2430 const bool wOdd = (1 == w%2);
2431 const int dataBits =
DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2434 const double dP = 1.0/h;
2436 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
2437 if (channelMap == NULL) channelMap = defMap;
2438 int sampledPos = 0, yPos = 0;
2443 if (m_header.channels == 3) {
2444 ASSERT(bpp%dataBits == 0);
2446 DataT* y = m_channel[0]; ASSERT(y);
2447 DataT* u = m_channel[1]; ASSERT(u);
2448 DataT* v = m_channel[2]; ASSERT(v);
2449 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2451 for (i=0; i < h; i++) {
2452 if (i%2) sampledPos -= (w + 1)/2;
2454 for (j=0; j < w; j++) {
2457 uAvg = u[sampledPos];
2458 vAvg = v[sampledPos];
2463 buff[cnt + channelMap[0]] = y[yPos];
2464 buff[cnt + channelMap[1]] = uAvg;
2465 buff[cnt + channelMap[2]] = vAvg;
2468 if (j%2) sampledPos++;
2471 if (wOdd) sampledPos++;
2475 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2478 }
else if (m_header.channels == 4) {
2479 ASSERT(m_header.bpp == m_header.channels*8);
2480 ASSERT(bpp%dataBits == 0);
2482 DataT* y = m_channel[0]; ASSERT(y);
2483 DataT* u = m_channel[1]; ASSERT(u);
2484 DataT* v = m_channel[2]; ASSERT(v);
2485 DataT* a = m_channel[3]; ASSERT(a);
2487 int cnt, channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2489 for (i=0; i < h; i++) {
2490 if (i%2) sampledPos -= (w + 1)/2;
2492 for (j=0; j < w; j++) {
2495 uAvg = u[sampledPos];
2496 vAvg = v[sampledPos];
2497 aAvg = Clamp8(a[sampledPos] + yuvOffset);
2501 aAvg = Clamp8(a[yPos] + yuvOffset);
2504 buff[cnt + channelMap[0]] = y[yPos];
2505 buff[cnt + channelMap[1]] = uAvg;
2506 buff[cnt + channelMap[2]] = vAvg;
2507 buff[cnt + channelMap[3]] = aAvg;
2510 if (j%2) sampledPos++;
2513 if (wOdd) sampledPos++;
2517 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2539 const double dP = 1.0/m_header.height;
2540 const int dataBits =
DataTSize*8; ASSERT(dataBits == 16 || dataBits == 32);
2544 int yPos = 0, cnt = 0;
2546 int defMap[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; ASSERT(
sizeof(defMap)/
sizeof(defMap[0]) ==
MaxChannels);
2548 if (channelMap == NULL) channelMap = defMap;
2550 if (m_header.channels == 3) {
2551 ASSERT(bpp%dataBits == 0);
2553 DataT* y = m_channel[0]; ASSERT(y);
2554 DataT* u = m_channel[1]; ASSERT(u);
2555 DataT* v = m_channel[2]; ASSERT(v);
2556 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2558 for (UINT32 h=0; h < m_header.height; h++) {
2560 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2565 for (UINT32 w=0; w < m_header.width; w++) {
2566 y[yPos] = buff[cnt + channelMap[0]];
2567 u[yPos] = buff[cnt + channelMap[1]];
2568 v[yPos] = buff[cnt + channelMap[2]];
2574 }
else if (m_header.channels == 4) {
2575 ASSERT(bpp%dataBits == 0);
2577 DataT* y = m_channel[0]; ASSERT(y);
2578 DataT* u = m_channel[1]; ASSERT(u);
2579 DataT* v = m_channel[2]; ASSERT(v);
2580 DataT* a = m_channel[3]; ASSERT(a);
2581 const int channels = bpp/dataBits; ASSERT(channels >= m_header.channels);
2583 for (UINT32 h=0; h < m_header.height; h++) {
2585 if ((*cb)(percent,
true, data)) ReturnWithError(EscapePressed);
2590 for (UINT32 w=0; w < m_header.width; w++) {
2591 y[yPos] = buff[cnt + channelMap[0]];
2592 u[yPos] = buff[cnt + channelMap[1]];
2593 v[yPos] = buff[cnt + channelMap[2]];
2594 a[yPos] = buff[cnt + channelMap[3]] - yuvOffset;
2604 for (
int i=1; i < m_header.channels; i++) {