Final
Dependencies: DebounceIn NokiaLCD WiflyInterface mbed
Fork of Websocket_Wifly_HelloWorld by
picojpeg.c
00001 //------------------------------------------------------------------------------ 00002 // picojpeg v1.0 - Public domain, Rich Geldreich <richgel99@gmail.com> 00003 // Last modified Nov. 27, 2010 00004 //------------------------------------------------------------------------------ 00005 #include "picojpeg.h" 00006 //------------------------------------------------------------------------------ 00007 typedef unsigned char uint8; 00008 typedef unsigned short uint16; 00009 typedef signed char int8; 00010 typedef signed short int16; 00011 //------------------------------------------------------------------------------ 00012 // Change as needed - the PJPG_MAX_WIDTH/PJPG_MAX_HEIGHT checks are only present 00013 // to quickly detect bogus files. 00014 #define PJPG_MAX_WIDTH 16384 00015 #define PJPG_MAX_HEIGHT 16384 00016 00017 #define PJPG_MAXCOMPSINSCAN 3 00018 //------------------------------------------------------------------------------ 00019 typedef enum 00020 { 00021 M_SOF0 = 0xC0, 00022 M_SOF1 = 0xC1, 00023 M_SOF2 = 0xC2, 00024 M_SOF3 = 0xC3, 00025 00026 M_SOF5 = 0xC5, 00027 M_SOF6 = 0xC6, 00028 M_SOF7 = 0xC7, 00029 00030 M_JPG = 0xC8, 00031 M_SOF9 = 0xC9, 00032 M_SOF10 = 0xCA, 00033 M_SOF11 = 0xCB, 00034 00035 M_SOF13 = 0xCD, 00036 M_SOF14 = 0xCE, 00037 M_SOF15 = 0xCF, 00038 00039 M_DHT = 0xC4, 00040 00041 M_DAC = 0xCC, 00042 00043 M_RST0 = 0xD0, 00044 M_RST1 = 0xD1, 00045 M_RST2 = 0xD2, 00046 M_RST3 = 0xD3, 00047 M_RST4 = 0xD4, 00048 M_RST5 = 0xD5, 00049 M_RST6 = 0xD6, 00050 M_RST7 = 0xD7, 00051 00052 M_SOI = 0xD8, 00053 M_EOI = 0xD9, 00054 M_SOS = 0xDA, 00055 M_DQT = 0xDB, 00056 M_DNL = 0xDC, 00057 M_DRI = 0xDD, 00058 M_DHP = 0xDE, 00059 M_EXP = 0xDF, 00060 00061 M_APP0 = 0xE0, 00062 M_APP15 = 0xEF, 00063 00064 M_JPG0 = 0xF0, 00065 M_JPG13 = 0xFD, 00066 M_COM = 0xFE, 00067 00068 M_TEM = 0x01, 00069 00070 M_ERROR = 0x100 00071 } JPEG_MARKER; 00072 00073 #define RST0 0xD0 00074 //------------------------------------------------------------------------------ 00075 const int8 ZAG[] = 00076 { 00077 0, 1, 8, 16, 9, 2, 3, 10, 00078 17, 24, 32, 25, 18, 11, 4, 5, 00079 12, 19, 26, 33, 40, 48, 41, 34, 00080 27, 20, 13, 6, 7, 14, 21, 28, 00081 35, 42, 49, 56, 57, 50, 43, 36, 00082 29, 22, 15, 23, 30, 37, 44, 51, 00083 58, 59, 52, 45, 38, 31, 39, 46, 00084 53, 60, 61, 54, 47, 55, 62, 63, 00085 }; 00086 //------------------------------------------------------------------------------ 00087 // 128 bytes 00088 static int16 gCoeffBuf[8*8]; 00089 00090 // 8*8*4 bytes * 3 = 768 00091 static uint8 gMCUBufR[256]; 00092 static uint8 gMCUBufG[256]; 00093 static uint8 gMCUBufB[256]; 00094 00095 // 256 bytes 00096 static int16 gQuant0[8*8]; 00097 static int16 gQuant1[8*8]; 00098 00099 // 6 bytes 00100 static int16 gLastDC[3]; 00101 00102 typedef struct HuffTableT 00103 { 00104 uint16 mMinCode[16]; 00105 uint16 mMaxCode[16]; 00106 uint8 mValPtr[16]; 00107 } HuffTable; 00108 00109 // DC - 192 00110 static HuffTable gHuffTab0; 00111 00112 static uint8 gHuffVal0[16]; 00113 00114 static HuffTable gHuffTab1; 00115 static uint8 gHuffVal1[16]; 00116 00117 // AC - 672 00118 static HuffTable gHuffTab2; 00119 static uint8 gHuffVal2[256]; 00120 00121 static HuffTable gHuffTab3; 00122 static uint8 gHuffVal3[256]; 00123 00124 static uint8 gValidHuffTables; 00125 static uint8 gValidQuantTables; 00126 00127 static uint8 gTemFlag; 00128 #define MAX_IN_BUF_SIZE 256 00129 static uint8 gInBuf[MAX_IN_BUF_SIZE]; 00130 static uint8 gInBufOfs; 00131 static uint8 gInBufLeft; 00132 00133 static uint16 gBitBuf; 00134 static uint8 gBitsLeft; 00135 //------------------------------------------------------------------------------ 00136 static uint16 gImageXSize; 00137 static uint16 gImageYSize; 00138 static uint8 gCompsInFrame; 00139 static uint8 gCompIdent[3]; 00140 static uint8 gCompHSamp[3]; 00141 static uint8 gCompVSamp[3]; 00142 static uint8 gCompQuant[3]; 00143 00144 static uint16 gRestartInterval; 00145 static uint16 gNextRestartNum; 00146 static uint16 gRestartsLeft; 00147 00148 static uint8 gCompsInScan; 00149 static uint8 gCompList[3]; 00150 static uint8 gCompDCTab[3]; // 0,1 00151 static uint8 gCompACTab[3]; // 0,1 00152 00153 static pjpeg_scan_type_t gScanType; 00154 00155 static uint8 gMaxBlocksPerMCU; 00156 static uint8 gMaxMCUXSize; 00157 static uint8 gMaxMCUYSize; 00158 static uint16 gMaxMCUSPerRow; 00159 static uint16 gMaxMCUSPerCol; 00160 static uint16 gNumMCUSRemaining; 00161 static uint8 gMCUOrg[6]; 00162 00163 static pjpeg_need_bytes_callback_t g_pNeedBytesCallback; 00164 static void *g_pCallback_data; 00165 //------------------------------------------------------------------------------ 00166 static uint8 fillInBuf(void) 00167 { 00168 unsigned char status; 00169 00170 // Reserve a few bytes at the beginning of the buffer for putting back ("stuffing") chars. 00171 gInBufOfs = 4; 00172 gInBufLeft = 0; 00173 00174 status = (*g_pNeedBytesCallback)(gInBuf + gInBufOfs, MAX_IN_BUF_SIZE - gInBufOfs, &gInBufLeft, g_pCallback_data); 00175 if (status) 00176 return status; 00177 00178 return 0; 00179 } 00180 //------------------------------------------------------------------------------ 00181 static uint8 getChar(void) 00182 { 00183 if (!gInBufLeft) 00184 { 00185 fillInBuf(); 00186 if (!gInBufLeft) 00187 { 00188 gTemFlag = ~gTemFlag; 00189 return gTemFlag ? 0xFF : 0xD9; 00190 } 00191 } 00192 00193 gInBufLeft--; 00194 return gInBuf[gInBufOfs++]; 00195 } 00196 //------------------------------------------------------------------------------ 00197 static void stuffChar(uint8 i) 00198 { 00199 gInBufOfs--; 00200 gInBuf[gInBufOfs] = i; 00201 gInBufLeft++; 00202 } 00203 //------------------------------------------------------------------------------ 00204 static uint8 getOctet(uint8 FFCheck) 00205 { 00206 uint8 c = getChar(); 00207 00208 if ((FFCheck) && (c == 0xFF)) 00209 { 00210 uint8 n = getChar(); 00211 00212 if (n) 00213 { 00214 stuffChar(n); 00215 stuffChar(0xFF); 00216 } 00217 } 00218 00219 return c; 00220 } 00221 //------------------------------------------------------------------------------ 00222 static uint16 getBits(uint8 numBits, uint8 FFCheck) 00223 { 00224 uint8 origBits = numBits; 00225 uint16 ret = gBitBuf; 00226 00227 if (numBits > 8) 00228 { 00229 numBits -= 8; 00230 00231 gBitBuf <<= gBitsLeft; 00232 00233 gBitBuf |= getOctet(FFCheck); 00234 00235 gBitBuf <<= (8 - gBitsLeft); 00236 00237 ret = (ret & 0xFF00) | (gBitBuf >> 8); 00238 } 00239 00240 if (gBitsLeft < numBits) 00241 { 00242 gBitBuf <<= gBitsLeft; 00243 00244 gBitBuf |= getOctet(FFCheck); 00245 00246 gBitBuf <<= (numBits - gBitsLeft); 00247 00248 gBitsLeft = 8 - (numBits - gBitsLeft); 00249 } 00250 else 00251 { 00252 gBitsLeft = (uint8)(gBitsLeft - numBits); 00253 gBitBuf <<= numBits; 00254 } 00255 00256 return ret >> (16 - origBits); 00257 } 00258 //------------------------------------------------------------------------------ 00259 static uint16 getBits1(uint8 numBits) 00260 { 00261 return getBits(numBits, 0); 00262 } 00263 //------------------------------------------------------------------------------ 00264 static uint16 getBits2(uint8 numBits) 00265 { 00266 return getBits(numBits, 1); 00267 } 00268 //------------------------------------------------------------------------------ 00269 static uint8 getBit(void) 00270 { 00271 uint8 ret = 0; 00272 if (gBitBuf & 0x8000) 00273 ret = 1; 00274 00275 if (!gBitsLeft) 00276 { 00277 gBitBuf |= getOctet(1); 00278 00279 gBitsLeft += 8; 00280 } 00281 00282 gBitsLeft--; 00283 gBitBuf <<= 1; 00284 00285 return ret; 00286 } 00287 //------------------------------------------------------------------------------ 00288 static uint16 getExtendTest(uint8 i) 00289 { 00290 switch (i) 00291 { 00292 case 0: return 0; 00293 case 1: return 0x0001; 00294 case 2: return 0x0002; 00295 case 3: return 0x0004; 00296 case 4: return 0x0008; 00297 case 5: return 0x0010; 00298 case 6: return 0x0020; 00299 case 7: return 0x0040; 00300 case 8: return 0x0080; 00301 case 9: return 0x0100; 00302 case 10: return 0x0200; 00303 case 11: return 0x0400; 00304 case 12: return 0x0800; 00305 case 13: return 0x1000; 00306 case 14: return 0x2000; 00307 case 15: return 0x4000; 00308 default: return 0; 00309 } 00310 } 00311 //------------------------------------------------------------------------------ 00312 static int16 getExtendOffset(uint8 i) 00313 { 00314 switch (i) 00315 { 00316 case 0: return 0; 00317 case 1: return ((-1)<<1) + 1; 00318 case 2: return ((-1)<<2) + 1; 00319 case 3: return ((-1)<<3) + 1; 00320 case 4: return ((-1)<<4) + 1; 00321 case 5: return ((-1)<<5) + 1; 00322 case 6: return ((-1)<<6) + 1; 00323 case 7: return ((-1)<<7) + 1; 00324 case 8: return ((-1)<<8) + 1; 00325 case 9: return ((-1)<<9) + 1; 00326 case 10: return ((-1)<<10) + 1; 00327 case 11: return ((-1)<<11) + 1; 00328 case 12: return ((-1)<<12) + 1; 00329 case 13: return ((-1)<<13) + 1; 00330 case 14: return ((-1)<<14) + 1; 00331 case 15: return ((-1)<<15) + 1; 00332 default: return 0; 00333 } 00334 }; 00335 //------------------------------------------------------------------------------ 00336 static int16 huffExtend(uint16 x, uint8 s) 00337 { 00338 return ((x < getExtendTest(s)) ? ((int16)x + getExtendOffset(s)) : (int16)x); 00339 } 00340 //------------------------------------------------------------------------------ 00341 static uint8 huffDecode(const HuffTable* pHuffTable, const uint8* pHuffVal) 00342 { 00343 uint8 i = 0; 00344 uint8 j; 00345 uint16 code = getBit(); 00346 00347 for ( ; ; ) 00348 { 00349 uint16 maxCode; 00350 00351 if (i == 16) 00352 return 0; 00353 00354 maxCode = pHuffTable->mMaxCode[i]; 00355 if ((code <= maxCode) && (maxCode != 0xFFFF)) 00356 break; 00357 00358 i++; 00359 code <<= 1; 00360 code |= getBit(); 00361 } 00362 00363 j = pHuffTable->mValPtr[i]; 00364 j = (uint8)(j + (code - pHuffTable->mMinCode[i])); 00365 00366 return pHuffVal[j]; 00367 } 00368 //------------------------------------------------------------------------------ 00369 static void huffCreate(const uint8* pBits, HuffTable* pHuffTable) 00370 { 00371 uint8 i = 0; 00372 uint8 j = 0; 00373 00374 uint16 code = 0; 00375 00376 for ( ; ; ) 00377 { 00378 uint8 num = pBits[i]; 00379 00380 if (!num) 00381 { 00382 pHuffTable->mMinCode[i] = 0x0000; 00383 pHuffTable->mMaxCode[i] = 0xFFFF; 00384 pHuffTable->mValPtr[i] = 0; 00385 } 00386 else 00387 { 00388 pHuffTable->mMinCode[i] = code; 00389 pHuffTable->mMaxCode[i] = code + num - 1; 00390 pHuffTable->mValPtr[i] = j; 00391 00392 j = (uint8)(j + num); 00393 00394 code = (uint16)(code + num); 00395 } 00396 00397 code <<= 1; 00398 00399 i++; 00400 if (i > 15) 00401 break; 00402 } 00403 } 00404 //------------------------------------------------------------------------------ 00405 static HuffTable* getHuffTable(uint8 index) 00406 { 00407 // 0-1 = DC 00408 // 2-3 = AC 00409 switch (index) 00410 { 00411 case 0: return &gHuffTab0; 00412 case 1: return &gHuffTab1; 00413 case 2: return &gHuffTab2; 00414 case 3: return &gHuffTab3; 00415 default: return 0; 00416 } 00417 } 00418 //------------------------------------------------------------------------------ 00419 static uint8* getHuffVal(uint8 index) 00420 { 00421 // 0-1 = DC 00422 // 2-3 = AC 00423 switch (index) 00424 { 00425 case 0: return gHuffVal0; 00426 case 1: return gHuffVal1; 00427 case 2: return gHuffVal2; 00428 case 3: return gHuffVal3; 00429 default: return 0; 00430 } 00431 } 00432 //------------------------------------------------------------------------------ 00433 static uint16 getMaxHuffCodes(uint8 index) 00434 { 00435 return (index < 2) ? 12 : 255; 00436 } 00437 //------------------------------------------------------------------------------ 00438 static uint8 readDHTMarker(void) 00439 { 00440 uint8 bits[16]; 00441 uint16 left = getBits1(16); 00442 00443 if (left < 2) 00444 return PJPG_BAD_DHT_MARKER; 00445 00446 left -= 2; 00447 00448 while (left) 00449 { 00450 uint8 i, tableIndex, index; 00451 uint8* pHuffVal; 00452 HuffTable* pHuffTable; 00453 uint16 count, totalRead; 00454 00455 index = (uint8)getBits1(8); 00456 00457 if ( ((index & 0xF) > 1) || ((index & 0xF0) > 0x10) ) 00458 return PJPG_BAD_DHT_INDEX; 00459 00460 tableIndex = ((index >> 3) & 2) + (index & 1); 00461 00462 pHuffTable = getHuffTable(tableIndex); 00463 pHuffVal = getHuffVal(tableIndex); 00464 00465 gValidHuffTables |= (1 << tableIndex); 00466 00467 count = 0; 00468 for (i = 0; i <= 15; i++) 00469 { 00470 uint8 n = (uint8)getBits1(8); 00471 bits[i] = n; 00472 count = (uint16)(count + n); 00473 } 00474 00475 if (count > getMaxHuffCodes(tableIndex)) 00476 return PJPG_BAD_DHT_COUNTS; 00477 00478 for (i = 0; i < count; i++) 00479 pHuffVal[i] = (uint8)getBits1(8); 00480 00481 totalRead = 1 + 16 + count; 00482 00483 if (left < totalRead) 00484 return PJPG_BAD_DHT_MARKER; 00485 00486 left = (uint16)(left - totalRead); 00487 00488 huffCreate(bits, pHuffTable); 00489 } 00490 00491 return 0; 00492 } 00493 //------------------------------------------------------------------------------ 00494 static void createWinogradQuant(int16* pQuant); 00495 00496 static uint8 readDQTMarker(void) 00497 { 00498 uint16 left = getBits1(16); 00499 00500 if (left < 2) 00501 return PJPG_BAD_DQT_MARKER; 00502 00503 left -= 2; 00504 00505 while (left) 00506 { 00507 uint8 i; 00508 uint8 n = (uint8)getBits1(8); 00509 uint8 prec = n >> 4; 00510 uint16 totalRead; 00511 00512 n &= 0x0F; 00513 00514 if (n > 1) 00515 return PJPG_BAD_DQT_TABLE; 00516 00517 gValidQuantTables |= (n ? 2 : 1); 00518 00519 // read quantization entries, in zag order 00520 for (i = 0; i < 64; i++) 00521 { 00522 uint16 temp = getBits1(8); 00523 00524 if (prec) 00525 temp = (temp << 8) + getBits1(8); 00526 00527 if (n) 00528 gQuant1[i] = (int16)temp; 00529 else 00530 gQuant0[i] = (int16)temp; 00531 } 00532 00533 createWinogradQuant(n ? gQuant1 : gQuant0); 00534 00535 totalRead = 64 + 1; 00536 00537 if (prec) 00538 totalRead += 64; 00539 00540 if (left < totalRead) 00541 return PJPG_BAD_DQT_LENGTH; 00542 00543 left = (uint16)(left - totalRead); 00544 } 00545 00546 return 0; 00547 } 00548 //------------------------------------------------------------------------------ 00549 static uint8 readSOFMarker(void) 00550 { 00551 uint8 i; 00552 uint16 left = getBits1(16); 00553 00554 if (getBits1(8) != 8) 00555 return PJPG_BAD_PRECISION; 00556 00557 gImageYSize = getBits1(16); 00558 00559 if ((!gImageYSize) || (gImageYSize > PJPG_MAX_HEIGHT)) 00560 return PJPG_BAD_HEIGHT; 00561 00562 gImageXSize = getBits1(16); 00563 00564 if ((!gImageXSize) || (gImageXSize > PJPG_MAX_WIDTH)) 00565 return PJPG_BAD_WIDTH; 00566 00567 gCompsInFrame = (uint8)getBits1(8); 00568 00569 if (gCompsInFrame > 3) 00570 return PJPG_TOO_MANY_COMPONENTS; 00571 00572 if (left != (gCompsInFrame + gCompsInFrame + gCompsInFrame + 8)) 00573 return PJPG_BAD_SOF_LENGTH; 00574 00575 for (i = 0; i < gCompsInFrame; i++) 00576 { 00577 gCompIdent[i] = (uint8)getBits1(8); 00578 gCompHSamp[i] = (uint8)getBits1(4); 00579 gCompVSamp[i] = (uint8)getBits1(4); 00580 gCompQuant[i] = (uint8)getBits1(8); 00581 00582 if (gCompQuant[i] > 1) 00583 return PJPG_UNSUPPORTED_QUANT_TABLE; 00584 } 00585 00586 return 0; 00587 } 00588 //------------------------------------------------------------------------------ 00589 // Used to skip unrecognized markers. 00590 static uint8 skipVariableMarker(void) 00591 { 00592 uint16 left = getBits1(16); 00593 00594 if (left < 2) 00595 return PJPG_BAD_VARIABLE_MARKER; 00596 00597 left -= 2; 00598 00599 while (left) 00600 { 00601 getBits1(8); 00602 left--; 00603 } 00604 00605 return 0; 00606 } 00607 //------------------------------------------------------------------------------ 00608 // Read a define restart interval (DRI) marker. 00609 static uint8 readDRIMarker(void) 00610 { 00611 if (getBits1(16) != 4) 00612 return PJPG_BAD_DRI_LENGTH; 00613 00614 gRestartInterval = getBits1(16); 00615 00616 return 0; 00617 } 00618 //------------------------------------------------------------------------------ 00619 // Read a start of scan (SOS) marker. 00620 static uint8 readSOSMarker(void) 00621 { 00622 uint8 i; 00623 uint16 left = getBits1(16); 00624 uint8 spectral_start, spectral_end, successive_high, successive_low; 00625 00626 gCompsInScan = (uint8)getBits1(8); 00627 00628 left -= 3; 00629 00630 if ( (left != (gCompsInScan + gCompsInScan + 3)) || (gCompsInScan < 1) || (gCompsInScan > PJPG_MAXCOMPSINSCAN) ) 00631 return PJPG_BAD_SOS_LENGTH; 00632 00633 for (i = 0; i < gCompsInScan; i++) 00634 { 00635 uint8 cc = (uint8)getBits1(8); 00636 uint8 c = (uint8)getBits1(8); 00637 uint8 ci; 00638 00639 left -= 2; 00640 00641 for (ci = 0; ci < gCompsInFrame; ci++) 00642 if (cc == gCompIdent[ci]) 00643 break; 00644 00645 if (ci >= gCompsInFrame) 00646 return PJPG_BAD_SOS_COMP_ID; 00647 00648 gCompList[i] = ci; 00649 gCompDCTab[ci] = (c >> 4) & 15; 00650 gCompACTab[ci] = (c & 15); 00651 } 00652 00653 spectral_start = (uint8)getBits1(8); 00654 spectral_end = (uint8)getBits1(8); 00655 successive_high = (uint8)getBits1(4); 00656 successive_low = (uint8)getBits1(4); 00657 00658 left -= 3; 00659 00660 while (left) 00661 { 00662 getBits1(8); 00663 left--; 00664 } 00665 00666 return 0; 00667 } 00668 //------------------------------------------------------------------------------ 00669 static uint8 nextMarker(void) 00670 { 00671 uint8 c; 00672 uint8 bytes = 0; 00673 00674 do 00675 { 00676 do 00677 { 00678 bytes++; 00679 00680 c = (uint8)getBits1(8); 00681 00682 } while (c != 0xFF); 00683 00684 do 00685 { 00686 c = (uint8)getBits1(8); 00687 00688 } while (c == 0xFF); 00689 00690 } while (c == 0); 00691 00692 // If bytes > 0 here, there where extra bytes before the marker (not good). 00693 00694 return c; 00695 } 00696 //------------------------------------------------------------------------------ 00697 // Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is 00698 // encountered. 00699 static uint8 processMarkers(uint8* pMarker) 00700 { 00701 for ( ; ; ) 00702 { 00703 uint8 c = nextMarker(); 00704 00705 switch (c) 00706 { 00707 case M_SOF0: 00708 case M_SOF1: 00709 case M_SOF2: 00710 case M_SOF3: 00711 case M_SOF5: 00712 case M_SOF6: 00713 case M_SOF7: 00714 // case M_JPG: 00715 case M_SOF9: 00716 case M_SOF10: 00717 case M_SOF11: 00718 case M_SOF13: 00719 case M_SOF14: 00720 case M_SOF15: 00721 case M_SOI: 00722 case M_EOI: 00723 case M_SOS: 00724 { 00725 *pMarker = c; 00726 return 0; 00727 } 00728 case M_DHT: 00729 { 00730 readDHTMarker(); 00731 break; 00732 } 00733 // Sorry, no arithmitic support at this time. Dumb patents! 00734 case M_DAC: 00735 { 00736 return PJPG_NO_ARITHMITIC_SUPPORT; 00737 } 00738 case M_DQT: 00739 { 00740 readDQTMarker(); 00741 break; 00742 } 00743 case M_DRI: 00744 { 00745 readDRIMarker(); 00746 break; 00747 } 00748 //case M_APP0: /* no need to read the JFIF marker */ 00749 00750 case M_JPG: 00751 case M_RST0: /* no parameters */ 00752 case M_RST1: 00753 case M_RST2: 00754 case M_RST3: 00755 case M_RST4: 00756 case M_RST5: 00757 case M_RST6: 00758 case M_RST7: 00759 case M_TEM: 00760 { 00761 return PJPG_UNEXPECTED_MARKER; 00762 } 00763 default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */ 00764 { 00765 skipVariableMarker(); 00766 break; 00767 } 00768 } 00769 } 00770 // return 0; 00771 } 00772 //------------------------------------------------------------------------------ 00773 // Finds the start of image (SOI) marker. 00774 static uint8 locateSOIMarker(void) 00775 { 00776 uint16 bytesleft; 00777 00778 uint8 lastchar = (uint8)getBits1(8); 00779 00780 uint8 thischar = (uint8)getBits1(8); 00781 00782 /* ok if it's a normal JPEG file without a special header */ 00783 00784 if ((lastchar == 0xFF) && (thischar == M_SOI)) 00785 return 0; 00786 00787 bytesleft = 4096; //512; 00788 00789 for ( ; ; ) 00790 { 00791 if (--bytesleft == 0) 00792 return PJPG_NOT_JPEG; 00793 00794 lastchar = thischar; 00795 00796 thischar = (uint8)getBits1(8); 00797 00798 if (lastchar == 0xFF) 00799 { 00800 if (thischar == M_SOI) 00801 break; 00802 else if (thischar == M_EOI) //getBits1 will keep returning M_EOI if we read past the end 00803 return PJPG_NOT_JPEG; 00804 } 00805 } 00806 00807 /* Check the next character after marker: if it's not 0xFF, it can't 00808 be the start of the next marker, so the file is bad */ 00809 00810 thischar = (uint8)((gBitBuf >> 8) & 0xFF); 00811 00812 if (thischar != 0xFF) 00813 return PJPG_NOT_JPEG; 00814 00815 return 0; 00816 } 00817 //------------------------------------------------------------------------------ 00818 // Find a start of frame (SOF) marker. 00819 static uint8 locateSOFMarker(void) 00820 { 00821 uint8 c; 00822 00823 uint8 status = locateSOIMarker(); 00824 if (status) 00825 return status; 00826 00827 status = processMarkers(&c); 00828 if (status) 00829 return status; 00830 00831 switch (c) 00832 { 00833 case M_SOF2: 00834 { 00835 return PJPG_UNSUPPORTED_MODE; 00836 } 00837 case M_SOF0: /* baseline DCT */ 00838 { 00839 status = readSOFMarker(); 00840 if (status) 00841 return status; 00842 00843 break; 00844 } 00845 case M_SOF9: 00846 { 00847 return PJPG_NO_ARITHMITIC_SUPPORT; 00848 } 00849 case M_SOF1: /* extended sequential DCT */ 00850 default: 00851 { 00852 return PJPG_UNSUPPORTED_MARKER; 00853 } 00854 } 00855 00856 return 0; 00857 } 00858 //------------------------------------------------------------------------------ 00859 // Find a start of scan (SOS) marker. 00860 static uint8 locateSOSMarker(uint8* pFoundEOI) 00861 { 00862 uint8 c; 00863 uint8 status; 00864 00865 *pFoundEOI = 0; 00866 00867 status = processMarkers(&c); 00868 if (status) 00869 return status; 00870 00871 if (c == M_EOI) 00872 { 00873 *pFoundEOI = 1; 00874 return 0; 00875 } 00876 else if (c != M_SOS) 00877 return PJPG_UNEXPECTED_MARKER; 00878 00879 return readSOSMarker(); 00880 } 00881 //------------------------------------------------------------------------------ 00882 static uint8 init(void) 00883 { 00884 gImageXSize = 0; 00885 gImageYSize = 0; 00886 gCompsInFrame = 0; 00887 gRestartInterval = 0; 00888 gCompsInScan = 0; 00889 gValidHuffTables = 0; 00890 gValidQuantTables = 0; 00891 gTemFlag = 0; 00892 gInBufOfs = 0; 00893 gInBufLeft = 0; 00894 gBitBuf = 0; 00895 gBitsLeft = 8; 00896 00897 getBits1(8); 00898 getBits1(8); 00899 00900 return 0; 00901 } 00902 //------------------------------------------------------------------------------ 00903 // This method throws back into the stream any bytes that where read 00904 // into the bit buffer during initial marker scanning. 00905 static void fixInBuffer(void) 00906 { 00907 /* In case any 0xFF's where pulled into the buffer during marker scanning */ 00908 00909 if (gBitsLeft > 0) 00910 stuffChar((uint8)gBitBuf); 00911 00912 stuffChar((uint8)(gBitBuf >> 8)); 00913 00914 gBitsLeft = 8; 00915 getBits2(8); 00916 getBits2(8); 00917 } 00918 //------------------------------------------------------------------------------ 00919 // Restart interval processing. 00920 static uint8 processRestart(void) 00921 { 00922 // Let's scan a little bit to find the marker, but not _too_ far. 00923 // 1536 is a "fudge factor" that determines how much to scan. 00924 uint16 i; 00925 uint8 c = 0; 00926 00927 for (i = 1536; i > 0; i--) 00928 if (getChar() == 0xFF) 00929 break; 00930 00931 if (i == 0) 00932 return PJPG_BAD_RESTART_MARKER; 00933 00934 for ( ; i > 0; i--) 00935 if ((c = getChar()) != 0xFF) 00936 break; 00937 00938 if (i == 0) 00939 return PJPG_BAD_RESTART_MARKER; 00940 00941 // Is it the expected marker? If not, something bad happened. 00942 if (c != (gNextRestartNum + M_RST0)) 00943 return PJPG_BAD_RESTART_MARKER; 00944 00945 // Reset each component's DC prediction values. 00946 gLastDC[0] = 0; 00947 gLastDC[1] = 0; 00948 gLastDC[2] = 0; 00949 00950 gRestartsLeft = gRestartInterval; 00951 00952 gNextRestartNum = (gNextRestartNum + 1) & 7; 00953 00954 // Get the bit buffer going again... 00955 00956 gBitsLeft = 8; 00957 getBits2(8); 00958 getBits2(8); 00959 00960 return 0; 00961 } 00962 //------------------------------------------------------------------------------ 00963 static uint8 findEOI(void) 00964 { 00965 uint8 c; 00966 uint8 status; 00967 00968 // Prime the bit buffer 00969 gBitsLeft = 8; 00970 getBits1(8); 00971 getBits1(8); 00972 00973 // The next marker _should_ be EOI 00974 status = processMarkers(&c); 00975 if (status) 00976 return status; 00977 00978 //gTotalBytesRead -= in_buf_left; 00979 if (c != M_EOI) 00980 return PJPG_UNEXPECTED_MARKER; 00981 00982 return 0; 00983 } 00984 //------------------------------------------------------------------------------ 00985 static uint8 checkHuffTables(void) 00986 { 00987 uint8 i; 00988 00989 for (i = 0; i < gCompsInScan; i++) 00990 { 00991 uint8 compDCTab = gCompDCTab[gCompList[i]]; 00992 uint8 compACTab = gCompACTab[gCompList[i]] + 2; 00993 00994 if ( ((gValidHuffTables & (1 << compDCTab)) == 0) || 00995 ((gValidHuffTables & (1 << compACTab)) == 0) ) 00996 return PJPG_UNDEFINED_HUFF_TABLE; 00997 } 00998 00999 return 0; 01000 } 01001 //------------------------------------------------------------------------------ 01002 static uint8 checkQuantTables(void) 01003 { 01004 uint8 i; 01005 01006 for (i = 0; i < gCompsInScan; i++) 01007 { 01008 uint8 compQuantMask = gCompQuant[gCompList[i]] ? 2 : 1; 01009 01010 if ((gValidQuantTables & compQuantMask) == 0) 01011 return PJPG_UNDEFINED_QUANT_TABLE; 01012 } 01013 01014 return 0; 01015 } 01016 //------------------------------------------------------------------------------ 01017 static uint8 initScan(void) 01018 { 01019 uint8 foundEOI; 01020 uint8 status = locateSOSMarker(&foundEOI); 01021 if (status) 01022 return status; 01023 if (foundEOI) 01024 return PJPG_UNEXPECTED_MARKER; 01025 01026 status = checkHuffTables(); 01027 if (status) 01028 return status; 01029 01030 status = checkQuantTables(); 01031 if (status) 01032 return status; 01033 01034 gLastDC[0] = 0; 01035 gLastDC[1] = 0; 01036 gLastDC[2] = 0; 01037 01038 if (gRestartInterval) 01039 { 01040 gRestartsLeft = gRestartInterval; 01041 gNextRestartNum = 0; 01042 } 01043 01044 fixInBuffer(); 01045 01046 return 0; 01047 } 01048 //------------------------------------------------------------------------------ 01049 static uint8 initFrame(void) 01050 { 01051 if (gCompsInFrame == 1) 01052 { 01053 if ((gCompHSamp[0] != 1) || (gCompVSamp[0] != 1)) 01054 return PJPG_UNSUPPORTED_SAMP_FACTORS; 01055 01056 gScanType = PJPG_GRAYSCALE; 01057 01058 gMaxBlocksPerMCU = 1; 01059 gMCUOrg[0] = 0; 01060 01061 gMaxMCUXSize = 8; 01062 gMaxMCUYSize = 8; 01063 } 01064 else if (gCompsInFrame == 3) 01065 { 01066 if ( ((gCompHSamp[1] != 1) || (gCompVSamp[1] != 1)) || 01067 ((gCompHSamp[2] != 1) || (gCompVSamp[2] != 1)) ) 01068 return PJPG_UNSUPPORTED_SAMP_FACTORS; 01069 01070 if ((gCompHSamp[0] == 1) && (gCompVSamp[0] == 1)) 01071 { 01072 gScanType = PJPG_YH1V1; 01073 01074 gMaxBlocksPerMCU = 3; 01075 gMCUOrg[0] = 0; 01076 gMCUOrg[1] = 1; 01077 gMCUOrg[2] = 2; 01078 01079 gMaxMCUXSize = 8; 01080 gMaxMCUYSize = 8; 01081 } 01082 else if ((gCompHSamp[0] == 2) && (gCompVSamp[0] == 2)) 01083 { 01084 gScanType = PJPG_YH2V2; 01085 01086 gMaxBlocksPerMCU = 6; 01087 gMCUOrg[0] = 0; 01088 gMCUOrg[1] = 0; 01089 gMCUOrg[2] = 0; 01090 gMCUOrg[3] = 0; 01091 gMCUOrg[4] = 1; 01092 gMCUOrg[5] = 2; 01093 01094 gMaxMCUXSize = 16; 01095 gMaxMCUYSize = 16; 01096 } 01097 else 01098 return PJPG_UNSUPPORTED_SAMP_FACTORS; 01099 } 01100 else 01101 return PJPG_UNSUPPORTED_COLORSPACE; 01102 01103 gMaxMCUSPerRow = (gImageXSize + (gMaxMCUXSize - 1)) >> ((gMaxMCUXSize == 8) ? 3 : 4); 01104 gMaxMCUSPerCol = (gImageYSize + (gMaxMCUYSize - 1)) >> ((gMaxMCUYSize == 8) ? 3 : 4); 01105 01106 gNumMCUSRemaining = gMaxMCUSPerRow * gMaxMCUSPerCol; 01107 01108 return 0; 01109 } 01110 /*----------------------------------------------------------------------------*/ 01111 #define DCT_SCALE_BITS 7 01112 01113 #define DCT_SCALE (1U << DCT_SCALE_BITS) 01114 01115 #define DESCALE(x) (((x) + (1U << (DCT_SCALE_BITS - 1))) >> DCT_SCALE_BITS) 01116 01117 #define WFIX(x) ((x) * DCT_SCALE + 0.5f) 01118 01119 #define WINOGRAD_QUANT_SCALE_BITS 10 01120 01121 const uint8 gWinogradQuant[] = 01122 { 01123 128, 178, 178, 167, 246, 167, 151, 232, 01124 232, 151, 128, 209, 219, 209, 128, 101, 01125 178, 197, 197, 178, 101, 69, 139, 167, 01126 177, 167, 139, 69, 35, 96, 131, 151, 01127 151, 131, 96, 35, 49, 91, 118, 128, 01128 118, 91, 49, 46, 81, 101, 101, 81, 01129 46, 42, 69, 79, 69, 42, 35, 54, 01130 54, 35, 28, 37, 28, 19, 19, 10, 01131 }; 01132 01133 static void createWinogradQuant(int16* pQuant) 01134 { 01135 uint8 i; 01136 01137 for (i = 0; i < 64; i++) 01138 { 01139 long x = pQuant[i]; 01140 x *= gWinogradQuant[i]; 01141 pQuant[i] = (int16)((x + (1 << (WINOGRAD_QUANT_SCALE_BITS - DCT_SCALE_BITS - 1))) >> (WINOGRAD_QUANT_SCALE_BITS - DCT_SCALE_BITS)); 01142 } 01143 } 01144 01145 // 1/cos(4*pi/16) 01146 // 362, 256+106 01147 #define b1 362 01148 01149 // 1/cos(6*pi/16) 01150 // 669, 256+256+157 01151 #define b2 669 01152 01153 // 1/cos(4*pi/16) 01154 // 362, 256+106 01155 #define b3 362 01156 01157 // 1/cos(2*pi/16) 01158 // 277, 256+21 01159 #define b4 277 01160 01161 // 1/(cos(2*pi/16) + cos(6*pi/16)) 01162 // 196, 196 01163 #define b5 196 01164 01165 static int16 imul_b1_b3(int16 w) 01166 { 01167 long x = (w * 362L); 01168 x += 128L; 01169 return (int16)(x >> 8); 01170 } 01171 01172 static int16 imul_b2(int16 w) 01173 { 01174 long x = (w * 669L); 01175 x += 128L; 01176 return (int16)(x >> 8); 01177 } 01178 01179 static int16 imul_b4(int16 w) 01180 { 01181 long x = (w * 277L); 01182 x += 128L; 01183 return (int16)(x >> 8); 01184 } 01185 01186 static int16 imul_b5(int16 w) 01187 { 01188 long x = (w * 196L); 01189 x += 128L; 01190 return (int16)(x >> 8); 01191 } 01192 01193 static uint8 clamp(int16 s) 01194 { 01195 if ((uint16)s > 255U) 01196 { 01197 if (s < 0) 01198 return 0; 01199 else if (s > 255) 01200 return 255; 01201 } 01202 01203 return (uint8)s; 01204 } 01205 01206 static void idctRows(void) 01207 { 01208 uint8 i; 01209 int16* pSrc = gCoeffBuf; 01210 01211 for (i = 0; i < 8; i++) 01212 { 01213 int16 src4 = *(pSrc+5); 01214 int16 src7 = *(pSrc+3); 01215 int16 x4 = src4 - src7; 01216 int16 x7 = src4 + src7; 01217 01218 int16 src5 = *(pSrc+1); 01219 int16 src6 = *(pSrc+7); 01220 int16 x5 = src5 + src6; 01221 int16 x6 = src5 - src6; 01222 01223 int16 tmp1 = imul_b5(x4 - x6); 01224 int16 stg26 = imul_b4(x6) - tmp1; 01225 01226 int16 x24 = tmp1 - imul_b2(x4); 01227 01228 int16 x15 = x5 - x7; 01229 int16 x17 = x5 + x7; 01230 01231 int16 tmp2 = stg26 - x17; 01232 int16 tmp3 = imul_b1_b3(x15) - tmp2; 01233 int16 x44 = tmp3 + x24; 01234 01235 int16 src0 = *(pSrc+0); 01236 int16 src1 = *(pSrc+4); 01237 int16 x30 = src0 + src1; 01238 int16 x31 = src0 - src1; 01239 01240 int16 src2 = *(pSrc+2); 01241 int16 src3 = *(pSrc+6); 01242 int16 x12 = src2 - src3; 01243 int16 x13 = src2 + src3; 01244 01245 int16 x32 = imul_b1_b3(x12) - x13; 01246 01247 int16 x40 = x30 + x13; 01248 int16 x43 = x30 - x13; 01249 int16 x41 = x31 + x32; 01250 int16 x42 = x31 - x32; 01251 01252 *(pSrc+0) = x40 + x17; 01253 *(pSrc+1) = x41 + tmp2; 01254 *(pSrc+2) = x42 + tmp3; 01255 *(pSrc+3) = x43 - x44; 01256 *(pSrc+4) = x43 + x44; 01257 *(pSrc+5) = x42 - tmp3; 01258 *(pSrc+6) = x41 - tmp2; 01259 *(pSrc+7) = x40 - x17; 01260 01261 pSrc += 8; 01262 } 01263 } 01264 01265 static void idctCols(void) 01266 { 01267 uint8 i; 01268 01269 int16* pSrc = gCoeffBuf; 01270 01271 for (i = 0; i < 8; i++) 01272 { 01273 int16 src4 = *(pSrc+5*8); 01274 int16 src7 = *(pSrc+3*8); 01275 int16 x4 = src4 - src7; 01276 int16 x7 = src4 + src7; 01277 01278 int16 src5 = *(pSrc+1*8); 01279 int16 src6 = *(pSrc+7*8); 01280 int16 x5 = src5 + src6; 01281 int16 x6 = src5 - src6; 01282 01283 int16 tmp1 = imul_b5(x4 - x6); 01284 int16 stg26 = imul_b4(x6) - tmp1; 01285 01286 int16 x24 = tmp1 - imul_b2(x4); 01287 01288 int16 x15 = x5 - x7; 01289 int16 x17 = x5 + x7; 01290 01291 int16 tmp2 = stg26 - x17; 01292 int16 tmp3 = imul_b1_b3(x15) - tmp2; 01293 int16 x44 = tmp3 + x24; 01294 01295 int16 src0 = *(pSrc+0*8); 01296 int16 src1 = *(pSrc+4*8); 01297 int16 x30 = src0 + src1; 01298 int16 x31 = src0 - src1; 01299 01300 int16 src2 = *(pSrc+2*8); 01301 int16 src3 = *(pSrc+6*8); 01302 int16 x12 = src2 - src3; 01303 int16 x13 = src2 + src3; 01304 01305 int16 x32 = imul_b1_b3(x12) - x13; 01306 01307 int16 x40 = x30 + x13; 01308 int16 x43 = x30 - x13; 01309 int16 x41 = x31 + x32; 01310 int16 x42 = x31 - x32; 01311 01312 *(pSrc+0*8) = clamp(DESCALE(x40 + x17) + 128); 01313 *(pSrc+1*8) = clamp(DESCALE(x41 + tmp2) + 128); 01314 *(pSrc+2*8) = clamp(DESCALE(x42 + tmp3) + 128); 01315 *(pSrc+3*8) = clamp(DESCALE(x43 - x44) + 128); 01316 *(pSrc+4*8) = clamp(DESCALE(x43 + x44) + 128); 01317 *(pSrc+5*8) = clamp(DESCALE(x42 - tmp3) + 128); 01318 *(pSrc+6*8) = clamp(DESCALE(x41 - tmp2) + 128); 01319 *(pSrc+7*8) = clamp(DESCALE(x40 - x17) + 128); 01320 01321 pSrc++; 01322 } 01323 } 01324 01325 /*----------------------------------------------------------------------------*/ 01326 static uint8 addAndClamp(uint8 a, int16 b) 01327 { 01328 b = a + b; 01329 01330 if ((uint16)b > 255U) 01331 { 01332 if (b < 0) 01333 return 0; 01334 else if (b > 255) 01335 return 255; 01336 } 01337 01338 return (uint8)b; 01339 } 01340 /*----------------------------------------------------------------------------*/ 01341 static uint8 subAndClamp(uint8 a, int16 b) 01342 { 01343 b = a - b; 01344 01345 if ((uint16)b > 255U) 01346 { 01347 if (b < 0) 01348 return 0; 01349 else if (b > 255) 01350 return 255; 01351 } 01352 01353 return (uint8)b; 01354 } 01355 /*----------------------------------------------------------------------------*/ 01356 // 103/256 01357 //R = Y + 1.402 (Cr-128) 01358 01359 // 88/256, 183/256 01360 //G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128) 01361 01362 // 198/256 01363 //B = Y + 1.772 (Cb-128) 01364 /*----------------------------------------------------------------------------*/ 01365 static void upsampleCb(uint8 srcOfs, uint8 dstOfs) 01366 { 01367 // Cb - affects G and B 01368 uint8 x, y; 01369 int16* pSrc = gCoeffBuf + srcOfs; 01370 uint8* pDstG = gMCUBufG + dstOfs; 01371 uint8* pDstB = gMCUBufB + dstOfs; 01372 for (y = 0; y < 4; y++) 01373 { 01374 for (x = 0; x < 4; x++) 01375 { 01376 uint8 cb = (uint8)*pSrc++; 01377 int16 cbG, cbB; 01378 01379 cbG = ((cb * 88U) >> 8U) - 44U; 01380 pDstG[0] = subAndClamp(pDstG[0], cbG); 01381 pDstG[1] = subAndClamp(pDstG[1], cbG); 01382 pDstG[8] = subAndClamp(pDstG[8], cbG); 01383 pDstG[9] = subAndClamp(pDstG[9], cbG); 01384 01385 cbB = (cb + ((cb * 198U) >> 8U)) - 227U; 01386 pDstB[0] = addAndClamp(pDstB[0], cbB); 01387 pDstB[1] = addAndClamp(pDstB[1], cbB); 01388 pDstB[8] = addAndClamp(pDstB[8], cbB); 01389 pDstB[9] = addAndClamp(pDstB[9], cbB); 01390 01391 pDstG += 2; 01392 pDstB += 2; 01393 } 01394 01395 pSrc = pSrc - 4 + 8; 01396 pDstG = pDstG - 8 + 16; 01397 pDstB = pDstB - 8 + 16; 01398 } 01399 } 01400 /*----------------------------------------------------------------------------*/ 01401 // 103/256 01402 //R = Y + 1.402 (Cr-128) 01403 01404 // 88/256, 183/256 01405 //G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128) 01406 01407 // 198/256 01408 //B = Y + 1.772 (Cb-128) 01409 /*----------------------------------------------------------------------------*/ 01410 static void upsampleCr(uint8 srcOfs, uint8 dstOfs) 01411 { 01412 // Cr - affects R and G 01413 uint8 x, y; 01414 int16* pSrc = gCoeffBuf + srcOfs; 01415 uint8* pDstR = gMCUBufR + dstOfs; 01416 uint8* pDstG = gMCUBufG + dstOfs; 01417 for (y = 0; y < 4; y++) 01418 { 01419 for (x = 0; x < 4; x++) 01420 { 01421 uint8 cr = (uint8)*pSrc++; 01422 int16 crR, crG; 01423 01424 crR = (cr + ((cr * 103U) >> 8U)) - 179; 01425 pDstR[0] = addAndClamp(pDstR[0], crR); 01426 pDstR[1] = addAndClamp(pDstR[1], crR); 01427 pDstR[8] = addAndClamp(pDstR[8], crR); 01428 pDstR[9] = addAndClamp(pDstR[9], crR); 01429 01430 crG = ((cr * 183U) >> 8U) - 91; 01431 pDstG[0] = subAndClamp(pDstG[0], crG); 01432 pDstG[1] = subAndClamp(pDstG[1], crG); 01433 pDstG[8] = subAndClamp(pDstG[8], crG); 01434 pDstG[9] = subAndClamp(pDstG[9], crG); 01435 01436 pDstR += 2; 01437 pDstG += 2; 01438 } 01439 01440 pSrc = pSrc - 4 + 8; 01441 pDstR = pDstR - 8 + 16; 01442 pDstG = pDstG - 8 + 16; 01443 } 01444 } 01445 /*----------------------------------------------------------------------------*/ 01446 static void copyY(uint8 dstOfs) 01447 { 01448 uint8 i; 01449 uint8* pRDst = gMCUBufR + dstOfs; 01450 uint8* pGDst = gMCUBufG + dstOfs; 01451 uint8* pBDst = gMCUBufB + dstOfs; 01452 int16* pSrc = gCoeffBuf; 01453 01454 for (i = 64; i > 0; i--) 01455 { 01456 uint8 c = (uint8)*pSrc++; 01457 01458 *pRDst++ = c; 01459 *pGDst++ = c; 01460 *pBDst++ = c; 01461 } 01462 } 01463 /*----------------------------------------------------------------------------*/ 01464 static void convertCb(uint8 dstOfs) 01465 { 01466 uint8 i; 01467 uint8* pDstG = gMCUBufG + dstOfs; 01468 uint8* pDstB = gMCUBufB + dstOfs; 01469 int16* pSrc = gCoeffBuf; 01470 01471 for (i = 64; i > 0; i--) 01472 { 01473 uint8 cb = (uint8)*pSrc++; 01474 int16 cbG, cbB; 01475 01476 cbG = ((cb * 88U) >> 8U) - 44U; 01477 *pDstG++ = subAndClamp(pDstG[0], cbG); 01478 01479 cbB = (cb + ((cb * 198U) >> 8U)) - 227U; 01480 *pDstB++ = addAndClamp(pDstB[0], cbB); 01481 } 01482 } 01483 /*----------------------------------------------------------------------------*/ 01484 static void convertCr(uint8 dstOfs) 01485 { 01486 uint8 i; 01487 uint8* pDstR = gMCUBufR + dstOfs; 01488 uint8* pDstG = gMCUBufG + dstOfs; 01489 int16* pSrc = gCoeffBuf; 01490 01491 for (i = 64; i > 0; i--) 01492 { 01493 uint8 cr = (uint8)*pSrc++; 01494 int16 crR, crG; 01495 01496 crR = (cr + ((cr * 103U) >> 8U)) - 179; 01497 *pDstR++ = addAndClamp(pDstR[0], crR); 01498 01499 crG = ((cr * 183U) >> 8U) - 91; 01500 *pDstG++ = subAndClamp(pDstG[0], crG); 01501 } 01502 } 01503 /*----------------------------------------------------------------------------*/ 01504 static void transformBlock(uint8 mcuBlock) 01505 { 01506 idctRows(); 01507 idctCols(); 01508 01509 switch (gScanType) 01510 { 01511 case PJPG_GRAYSCALE: 01512 { 01513 copyY(0); 01514 break; 01515 } 01516 case PJPG_YH1V1: 01517 { 01518 switch (mcuBlock) 01519 { 01520 case 0: 01521 { 01522 copyY(0); 01523 break; 01524 } 01525 case 1: 01526 { 01527 convertCb(0); 01528 break; 01529 } 01530 case 2: 01531 { 01532 convertCr(0); 01533 break; 01534 } 01535 } 01536 01537 break; 01538 } 01539 case PJPG_YH2V2: 01540 { 01541 switch (mcuBlock) 01542 { 01543 case 0: 01544 { 01545 copyY(0); 01546 break; 01547 } 01548 case 1: 01549 { 01550 copyY(64); 01551 break; 01552 } 01553 case 2: 01554 { 01555 copyY(128); 01556 break; 01557 } 01558 case 3: 01559 { 01560 copyY(192); 01561 break; 01562 } 01563 case 4: 01564 { 01565 upsampleCb(0, 0); 01566 upsampleCb(4, 64); 01567 upsampleCb(4*8, 128); 01568 upsampleCb(4+4*8, 192); 01569 break; 01570 } 01571 case 5: 01572 { 01573 upsampleCr(0, 0); 01574 upsampleCr(4, 64); 01575 upsampleCr(4*8, 128); 01576 upsampleCr(4+4*8, 192); 01577 break; 01578 } 01579 } 01580 } 01581 } 01582 } 01583 //------------------------------------------------------------------------------ 01584 static uint8 decodeNextMCU(void) 01585 { 01586 uint8 status; 01587 uint8 mcuBlock; 01588 01589 if (gRestartInterval) 01590 { 01591 if (gRestartsLeft == 0) 01592 { 01593 status = processRestart(); 01594 if (status) 01595 return status; 01596 } 01597 gRestartsLeft--; 01598 } 01599 01600 for (mcuBlock = 0; mcuBlock < gMaxBlocksPerMCU; mcuBlock++) 01601 { 01602 uint8 componentID = gMCUOrg[mcuBlock]; 01603 uint8 compQuant = gCompQuant[componentID]; 01604 uint8 compDCTab = gCompDCTab[componentID]; 01605 uint8 numExtraBits, compACTab, k; 01606 const int16* pQ = compQuant ? gQuant1 : gQuant0; 01607 uint16 r, dc; 01608 01609 uint8 s = huffDecode(compDCTab ? &gHuffTab1 : &gHuffTab0, compDCTab ? gHuffVal1 : gHuffVal0); 01610 01611 r = 0; 01612 numExtraBits = s & 0xF; 01613 if (numExtraBits) 01614 r = getBits2(numExtraBits); 01615 dc = huffExtend(r, s); 01616 01617 dc = dc + gLastDC[componentID]; 01618 gLastDC[componentID] = dc; 01619 01620 gCoeffBuf[0] = dc * pQ[0]; 01621 01622 compACTab = gCompACTab[componentID]; 01623 01624 for (k = 1; k < 64; k++) 01625 { 01626 uint16 extraBits; 01627 01628 s = huffDecode(compACTab ? &gHuffTab3 : &gHuffTab2, compACTab ? gHuffVal3 : gHuffVal2); 01629 01630 extraBits = 0; 01631 numExtraBits = s & 0xF; 01632 if (numExtraBits) 01633 extraBits = getBits2(numExtraBits); 01634 01635 r = s >> 4; 01636 s &= 15; 01637 01638 if (s) 01639 { 01640 int16 ac; 01641 01642 if (r) 01643 { 01644 if ((k + r) > 63) 01645 return PJPG_DECODE_ERROR; 01646 01647 while (r) 01648 { 01649 gCoeffBuf[ZAG[k++]] = 0; 01650 r--; 01651 } 01652 } 01653 01654 ac = huffExtend(extraBits, s); 01655 01656 gCoeffBuf[ZAG[k]] = ac * pQ[k]; 01657 } 01658 else 01659 { 01660 if (r == 15) 01661 { 01662 if ((k + 16) > 64) 01663 return PJPG_DECODE_ERROR; 01664 01665 for (r = 16; r > 0; r--) 01666 gCoeffBuf[ZAG[k++]] = 0; 01667 01668 k--; // - 1 because the loop counter is k 01669 } 01670 else 01671 break; 01672 } 01673 } 01674 01675 while (k < 64) 01676 gCoeffBuf[ZAG[k++]] = 0; 01677 01678 transformBlock(mcuBlock); 01679 } 01680 01681 return 0; 01682 } 01683 //------------------------------------------------------------------------------ 01684 unsigned char pjpeg_decode_mcu(void) 01685 { 01686 uint8 status; 01687 01688 if (!gNumMCUSRemaining) 01689 return PJPG_NO_MORE_BLOCKS; 01690 01691 status = decodeNextMCU(); 01692 if (status) 01693 return status; 01694 01695 gNumMCUSRemaining--; 01696 01697 return 0; 01698 } 01699 //------------------------------------------------------------------------------ 01700 unsigned char pjpeg_decode_init(pjpeg_image_info_t *pInfo, pjpeg_need_bytes_callback_t pNeed_bytes_callback, void *pCallback_data) 01701 { 01702 uint8 status; 01703 01704 g_pNeedBytesCallback = pNeed_bytes_callback; 01705 g_pCallback_data = pCallback_data; 01706 01707 status = init(); 01708 if (status) 01709 return status; 01710 01711 status = locateSOFMarker(); 01712 if (status) 01713 return status; 01714 01715 status = initFrame(); 01716 if (status) 01717 return status; 01718 01719 status = initScan(); 01720 if (status) 01721 return status; 01722 01723 pInfo->m_width = gImageXSize; 01724 pInfo->m_height = gImageYSize; 01725 pInfo->m_comps = gCompsInFrame; 01726 pInfo->m_scanType = gScanType; 01727 pInfo->m_MCUSPerRow = gMaxMCUSPerRow; 01728 pInfo->m_MCUSPerCol = gMaxMCUSPerCol; 01729 pInfo->m_MCUWidth = gMaxMCUXSize; 01730 pInfo->m_MCUHeight = gMaxMCUYSize; 01731 pInfo->m_pMCUBufR = gMCUBufR; 01732 pInfo->m_pMCUBufG = gMCUBufG; 01733 pInfo->m_pMCUBufB = gMCUBufB; 01734 01735 return 0; 01736 }
Generated on Wed Jul 13 2022 05:24:08 by 1.7.2