| Line No. | Rev | Author | Line | 
|---|---|---|---|
| 1 | 32 | kaklik | #define __JPEGDECODER_C__ | 
| 2 | /****************************************************************************** | ||
| 3 | |||
| 4 | * FileName:        JpegDecoder.c | ||
| 5 | * Dependencies:    Image decoding library; project requires File System library | ||
| 6 | * Processor:       PIC24/dsPIC30/dsPIC33/PIC32MX | ||
| 7 | * Compiler:        C30 v2.01/C32 v0.00.18 | ||
| 8 | * Company:         Microchip Technology, Inc. | ||
| 9 | |||
| 10 |  * Software License Agreement | ||
| 11 |  * | ||
| 12 |  * Copyright © 2008 Microchip Technology Inc.  All rights reserved. | ||
| 13 |  * Microchip licenses to you the right to use, modify, copy and distribute | ||
| 14 |  * Software only when embedded on a Microchip microcontroller or digital | ||
| 15 |  * signal controller, which is integrated into your product or third party | ||
| 16 |  * product (pursuant to the sublicense terms in the accompanying license | ||
| 17 |  * agreement).   | ||
| 18 |  * | ||
| 19 |  * You should refer to the license agreement accompanying this Software | ||
| 20 |  * for additional information regarding your rights and obligations. | ||
| 21 |  * | ||
| 22 |  * SOFTWARE AND DOCUMENTATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY | ||
| 23 |  * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY | ||
| 24 |  * OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR | ||
| 25 |  * PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR | ||
| 26 |  * OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, | ||
| 27 |  * BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT | ||
| 28 |  * DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, | ||
| 29 |  * INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, | ||
| 30 |  * COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY | ||
| 31 |  * CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), | ||
| 32 |  * OR OTHER SIMILAR COSTS. | ||
| 33 | |||
| 34 | Author                 Date           Comments | ||
| 35 | -------------------------------------------------------------------------------- | ||
| 36 | Pradeep Budagutta    03-Mar-2008    First release | ||
| 37 | *******************************************************************************/ | ||
| 38 | |||
| 39 | #include "Image Decoders\ImageDecoder.h" | ||
| 40 | |||
| 41 | #ifdef IMG_SUPPORT_JPEG | ||
| 42 | |||
| 43 | #define JPEG_SAMPLE_1x1 0 | ||
| 44 | #define JPEG_SAMPLE_1x2 1 | ||
| 45 | #define JPEG_SAMPLE_2x1 2 | ||
| 46 | #define JPEG_SAMPLE_2x2 3 | ||
| 47 | |||
| 48 | /*****************************/ | ||
| 49 | /**** FUNCTION PROTOTYPES ****/ | ||
| 50 | /*****************************/ | ||
| 51 | void jpeg_idct_islow (SHORT *inbuf, WORD *quantptr); | ||
| 52 | |||
| 53 | /*************************/ | ||
| 54 | /**** DATA STRUCTURES ****/ | ||
| 55 | /*************************/ | ||
| 56 | typedef struct _JPEGDECODER | ||
| 57 | { | ||
| 58 |         IMG_FILE *pImageFile;                       /* Image file pointer */ | ||
| 59 | |||
| 60 |         /*********** From APP0 ***********/ | ||
| 61 |         BYTE blJFIF;                            /* JFIF marker found flag */ | ||
| 62 |         BYTE bMajorRev;                         /* Should be 1 */ | ||
| 63 |         BYTE bMinorRev;                         /* Should be 0-2 but is not a show stopper */ | ||
| 64 |         /*------- The x/y densities and thumbnail data are ignored --------*/ | ||
| 65 | |||
| 66 |         /*********** From SOF0 ***********/ | ||
| 67 |         BYTE bDataBits;                         /* Data precision, can be 8(, 12 or 16) */ | ||
| 68 |         WORD wWidth;                            /* Width in pixels */ | ||
| 69 |         WORD wHeight;                           /* Height in pixels */ | ||
| 70 |         BYTE bChannels;                         /* Number of channels e.g. YCbCr = 3 */ | ||
| 71 |         BYTE abChannelType[MAX_CHANNELS]; | ||
| 72 |         BYTE abChannelHSampFactor[MAX_CHANNELS]; | ||
| 73 |         BYTE abChannelVSampFactor[MAX_CHANNELS]; | ||
| 74 |         BYTE abChannelQuantTableMap[MAX_CHANNELS]; | ||
| 75 | |||
| 76 |         /*********** From DQT ***********/ | ||
| 77 |         BYTE blQuantUses16bits;                 /* If flag is set, it is an error as 16 bit is not supported */ | ||
| 78 |         WORD awQuantTable[MAX_CHANNELS][64];    /* Supports only 8 & 16 bit resolutions */ | ||
| 79 | |||
| 80 |         /*********** From DRI ***********/ | ||
| 81 |         WORD wRestartInterval;                  /* The restart interval in blocks */ | ||
| 82 | |||
| 83 |         /*********** From DHT ***********/ | ||
| 84 |         BYTE bHuffTables; | ||
| 85 |         BYTE abHuffAcSymLen[MAX_HUFF_TABLES][16];   /* Supports only 8 bit resolution */ | ||
| 86 |         BYTE abHuffAcSymbol[MAX_HUFF_TABLES][256];  /* Maximum possible symbols are 256 */ | ||
| 87 |         BYTE abHuffDcSymLen[MAX_HUFF_TABLES][16];   /* Supports only 8 bit resolution */ | ||
| 88 |         BYTE abHuffDcSymbol[MAX_HUFF_TABLES][16];   /* Maximum possible symbols are 16 for DC :-) */ | ||
| 89 |         /*********** For Huffman-Decoding ***********/ | ||
| 90 |         WORD awHuffAcSymStart[MAX_HUFF_TABLES][16]; /* Starting symbol for each length */ | ||
| 91 |         WORD awHuffDcSymStart[MAX_HUFF_TABLES][16]; /* Starting symbol for each length */ | ||
| 92 | |||
| 93 |         /*********** From SOS ***********/ | ||
| 94 |         BYTE abChannelHuffAcTableMap[MAX_CHANNELS]; | ||
| 95 |         BYTE abChannelHuffDcTableMap[MAX_CHANNELS]; | ||
| 96 | |||
| 97 |         BYTE bError; | ||
| 98 | |||
| 99 |         /*********** Work memory ***********/ | ||
| 100 |         WORD wWorkBits; | ||
| 101 |         BYTE bBitsAvailable; | ||
| 102 |         BYTE bBlocksInOnePass; | ||
| 103 |         SHORT asOneBlock[MAX_BLOCKS][64];     /* Temporary storage for a 8x8 block */ | ||
| 104 |         WORD  wBlockNumber; | ||
| 105 |         BYTE  abChannelMap[MAX_BLOCKS]; | ||
| 106 |         BYTE  bSubSampleType; | ||
| 107 |         SHORT asPrevDcValue[MAX_CHANNELS]; | ||
| 108 |         BYTE *pbCurrentHuffSymLenTable; | ||
| 109 |         BYTE *pbCurrentHuffSymbolTable; | ||
| 110 |         WORD *pwCurrentHuffSymStartTable; | ||
| 111 |         WORD *pwCurrentQuantTable; | ||
| 112 |         BYTE abDataBuffer[MAX_DATA_BUF_LEN]; | ||
| 113 |         WORD wBufferLen; | ||
| 114 |         WORD wBufferIndex; | ||
| 115 |         BYTE bFirstBit; | ||
| 116 | |||
| 117 |         WORD wPrevX; | ||
| 118 |         WORD wPrevY; | ||
| 119 | } JPEGDECODER; | ||
| 120 | |||
| 121 | /**************************/ | ||
| 122 | /**** CONSTANT TABLES  ****/ | ||
| 123 | /**************************/ | ||
| 124 | static const BYTE abZigzag[64] =  | ||
| 125 | { | ||
| 126 |   0,  1,  8,  16, 9,  2,  3,  10, | ||
| 127 |   17, 24, 32, 25, 18, 11, 4,  5, | ||
| 128 |   12, 19, 26, 33, 40, 48, 41, 34, | ||
| 129 |   27, 20, 13, 6,  7,  14, 21, 28, | ||
| 130 |   35, 42, 49, 56, 57, 50, 43, 36, | ||
| 131 |   29, 22, 15, 23, 30, 37, 44, 51, | ||
| 132 |   58, 59, 52, 45, 38, 31, 39, 46, | ||
| 133 |   53, 60, 61, 54, 47, 55, 62, 63 | ||
| 134 | }; | ||
| 135 | |||
| 136 | /**************************/ | ||
| 137 | /******* FUNCTIONS  *******/ | ||
| 138 | /**************************/ | ||
| 139 | |||
| 140 | /******************************************************************************* | ||
| 141 | Function:       void JPEG_vResetDecoder(JPEGDECODER *pJpegDecoder) | ||
| 142 | |||
| 143 | Precondition:   None | ||
| 144 | |||
| 145 | Overview:       This function resets the variables so that new jpeg image can be | ||
| 146 |                 decoded | ||
| 147 | |||
| 148 | Input:          JPEGDECODER | ||
| 149 | |||
| 150 | Output:         None | ||
| 151 | *******************************************************************************/ | ||
| 152 | static void JPEG_vResetDecoder(JPEGDECODER *pJpegDecoder) | ||
| 153 | { | ||
| 154 |         WORD wIndex; | ||
| 155 |         BYTE *pbptr = (BYTE*)pJpegDecoder; | ||
| 156 |         for(wIndex = 0; wIndex < sizeof(JPEGDECODER); wIndex++) | ||
| 157 |         { | ||
| 158 |                   pbptr[wIndex] = 0; | ||
| 159 |         } | ||
| 160 | } | ||
| 161 | |||
| 162 | /******************************************************************************* | ||
| 163 | Function:       WORD JPEG_wReadWord(IMG_FILE *pfile) | ||
| 164 | |||
| 165 | Precondition:   None | ||
| 166 | |||
| 167 | Overview:       This function reads and returns a single word obtained as | ||
| 168 |                 Higher byte first followed by lower byte | ||
| 169 | |||
| 170 | Input:          Image file | ||
| 171 | |||
| 172 | Output:         One word | ||
| 173 | *******************************************************************************/ | ||
| 174 | static WORD JPEG_wReadWord(IMG_FILE *pfile) | ||
| 175 | { | ||
| 176 |      BYTE btemp; | ||
| 177 |      WORD wData; | ||
| 178 | |||
| 179 |      IMG_FREAD(&btemp, sizeof(btemp), 1, pfile); | ||
| 180 |      wData = btemp; | ||
| 181 |      IMG_FREAD(&btemp, sizeof(btemp), 1, pfile); | ||
| 182 |      wData = (wData << 8) | btemp; | ||
| 183 | |||
| 184 |      return wData; | ||
| 185 | } | ||
| 186 | |||
| 187 | /******************************************************************************* | ||
| 188 | Function:       BYTE JPEG_bReadByte(IMG_FILE *pfile) | ||
| 189 | |||
| 190 | Precondition:   None | ||
| 191 | |||
| 192 | Overview:       This function reads and returns a single byte from the file | ||
| 193 | |||
| 194 | Input:          Image file | ||
| 195 | |||
| 196 | Output:         One byte | ||
| 197 | *******************************************************************************/ | ||
| 198 | static BYTE JPEG_bReadByte(IMG_FILE *pfile) | ||
| 199 | { | ||
| 200 |      BYTE bData; | ||
| 201 | |||
| 202 |      IMG_FREAD(&bData, sizeof(bData), 1, pfile); | ||
| 203 | |||
| 204 |      return bData; | ||
| 205 | } | ||
| 206 | |||
| 207 | /******************************************************************************* | ||
| 208 | Function:       BYTE JPEG_bReadHeader(JPEGDECODER *pJpegDecoder) | ||
| 209 | |||
| 210 | Precondition:   None | ||
| 211 | |||
| 212 | Overview:       This function reads the JPEG file header and  | ||
| 213 |                 fills the data structure | ||
| 214 | |||
| 215 | Input:          JPEGDECODER | ||
| 216 | |||
| 217 | Output:         Error code - '0' means no error | ||
| 218 | *******************************************************************************/ | ||
| 219 | static BYTE JPEG_bReadHeader(JPEGDECODER *pJpegDecoder) | ||
| 220 | { | ||
| 221 |      BYTE blSOSOver = FALSE; | ||
| 222 |      while(!IMG_FEOF(pJpegDecoder->pImageFile)) | ||
| 223 |      { | ||
| 224 |              BYTE btemp, bcount, bsection; | ||
| 225 |              WORD wSegLen, wOffset; | ||
| 226 | |||
| 227 |              if(blSOSOver == TRUE) | ||
| 228 |              { | ||
| 229 |                      if(pJpegDecoder->bChannels == 1) | ||
| 230 |                      { | ||
| 231 |                              pJpegDecoder->bBlocksInOnePass = 1; | ||
| 232 |                              pJpegDecoder->bSubSampleType = JPEG_SAMPLE_1x1; | ||
| 233 |                      }     | ||
| 234 |                      else if(pJpegDecoder->bChannels == 3) | ||
| 235 |                      { | ||
| 236 |                              if((pJpegDecoder->abChannelHSampFactor[0] == 1 && pJpegDecoder->abChannelVSampFactor[0] == 1) && | ||
| 237 |                                 (pJpegDecoder->abChannelHSampFactor[1] == 1 && pJpegDecoder->abChannelVSampFactor[1] == 1) && | ||
| 238 |                                 (pJpegDecoder->abChannelHSampFactor[2] == 1 && pJpegDecoder->abChannelVSampFactor[2] == 1)) | ||
| 239 |                              { | ||
| 240 |                                      pJpegDecoder->bBlocksInOnePass = 3; | ||
| 241 |                                      pJpegDecoder->abChannelMap[0] = 0; | ||
| 242 |                                      pJpegDecoder->abChannelMap[1] = 1; | ||
| 243 |                                      pJpegDecoder->abChannelMap[2] = 2; | ||
| 244 |                                      pJpegDecoder->bSubSampleType = JPEG_SAMPLE_1x1; | ||
| 245 |                              } | ||
| 246 |                              else if((pJpegDecoder->abChannelHSampFactor[0] == 1 && pJpegDecoder->abChannelVSampFactor[0] == 2) && | ||
| 247 |                                      (pJpegDecoder->abChannelHSampFactor[1] == 1 && pJpegDecoder->abChannelVSampFactor[1] == 1) && | ||
| 248 |                                      (pJpegDecoder->abChannelHSampFactor[2] == 1 && pJpegDecoder->abChannelVSampFactor[2] == 1)) | ||
| 249 |                              { | ||
| 250 |                                      pJpegDecoder->bBlocksInOnePass = 4; | ||
| 251 |                                      pJpegDecoder->abChannelMap[0] = 0; | ||
| 252 |                                      pJpegDecoder->abChannelMap[1] = 0; | ||
| 253 |                                      pJpegDecoder->abChannelMap[2] = 1; | ||
| 254 |                                      pJpegDecoder->abChannelMap[3] = 2; | ||
| 255 |                                      pJpegDecoder->bSubSampleType = JPEG_SAMPLE_1x2; | ||
| 256 |                              } | ||
| 257 |                              else if((pJpegDecoder->abChannelHSampFactor[0] == 2 && pJpegDecoder->abChannelVSampFactor[0] == 1) && | ||
| 258 |                                      (pJpegDecoder->abChannelHSampFactor[1] == 1 && pJpegDecoder->abChannelVSampFactor[1] == 1) && | ||
| 259 |                                      (pJpegDecoder->abChannelHSampFactor[2] == 1 && pJpegDecoder->abChannelVSampFactor[2] == 1)) | ||
| 260 |                              { | ||
| 261 |                                      pJpegDecoder->bBlocksInOnePass = 4; | ||
| 262 |                                      pJpegDecoder->abChannelMap[0] = 0; | ||
| 263 |                                      pJpegDecoder->abChannelMap[1] = 0; | ||
| 264 |                                      pJpegDecoder->abChannelMap[2] = 1; | ||
| 265 |                                      pJpegDecoder->abChannelMap[3] = 2; | ||
| 266 |                                      pJpegDecoder->bSubSampleType = JPEG_SAMPLE_2x1; | ||
| 267 |                              } | ||
| 268 |                              else if((pJpegDecoder->abChannelHSampFactor[0] == 2 && pJpegDecoder->abChannelVSampFactor[0] == 2) && | ||
| 269 |                                      (pJpegDecoder->abChannelHSampFactor[1] == 1 && pJpegDecoder->abChannelVSampFactor[1] == 1) && | ||
| 270 |                                      (pJpegDecoder->abChannelHSampFactor[2] == 1 && pJpegDecoder->abChannelVSampFactor[2] == 1)) | ||
| 271 |                              { | ||
| 272 |                                      pJpegDecoder->bBlocksInOnePass = 6; | ||
| 273 |                                      pJpegDecoder->abChannelMap[0] = 0; | ||
| 274 |                                      pJpegDecoder->abChannelMap[1] = 0; | ||
| 275 |                                      pJpegDecoder->abChannelMap[2] = 0; | ||
| 276 |                                      pJpegDecoder->abChannelMap[3] = 0; | ||
| 277 |                                      pJpegDecoder->abChannelMap[4] = 1; | ||
| 278 |                                      pJpegDecoder->abChannelMap[5] = 2; | ||
| 279 |                                      pJpegDecoder->bSubSampleType = JPEG_SAMPLE_2x2; | ||
| 280 |                              } | ||
| 281 |                              else | ||
| 282 |                              { | ||
| 283 |                                      JPEG_SendError(100); | ||
| 284 |                              } | ||
| 285 |                      } | ||
| 286 |                      return 0; | ||
| 287 |              } | ||
| 288 | |||
| 289 |              IMG_FREAD(&btemp, sizeof(btemp), 1, pJpegDecoder->pImageFile); | ||
| 290 | |||
| 291 |              if(btemp != 0xFF) | ||
| 292 |              { | ||
| 293 |                      continue; | ||
| 294 |              } | ||
| 295 | |||
| 296 |              IMG_FREAD(&bsection, sizeof(bsection), 1, pJpegDecoder->pImageFile); | ||
| 297 |              switch(bsection) | ||
| 298 |              { | ||
| 299 |                case SOI: | ||
| 300 |                case TEM: | ||
| 301 |                case EOI: | ||
| 302 |                case RST0: | ||
| 303 |                case RST1: | ||
| 304 |                case RST2: | ||
| 305 |                case RST3: | ||
| 306 |                case RST4: | ||
| 307 |                case RST5: | ||
| 308 |                case RST6: | ||
| 309 |                case RST7: break; | ||
| 310 | |||
| 311 |                case SOF0: /* Start of frame */ | ||
| 312 |                           wSegLen = JPEG_wReadWord(pJpegDecoder->pImageFile); | ||
| 313 |                           if(wSegLen <= 8) | ||
| 314 |                           { | ||
| 315 |                                      JPEG_SendError(100); | ||
| 316 |                                      break; | ||
| 317 |                           } | ||
| 318 |                           pJpegDecoder->bDataBits = JPEG_bReadByte(pJpegDecoder->pImageFile); | ||
| 319 |                           pJpegDecoder->wHeight   = JPEG_wReadWord(pJpegDecoder->pImageFile); | ||
| 320 |                           pJpegDecoder->wWidth    = JPEG_wReadWord(pJpegDecoder->pImageFile); | ||
| 321 |                           pJpegDecoder->bChannels = JPEG_bReadByte(pJpegDecoder->pImageFile); | ||
| 322 |                           if(wSegLen < 8 + (pJpegDecoder->bChannels * 3)) | ||
| 323 |                           { | ||
| 324 |                                      JPEG_SendError(100); | ||
| 325 |                                      break; | ||
| 326 |                           } | ||
| 327 |                           for(bcount = 0; bcount < pJpegDecoder->bChannels; bcount++) | ||
| 328 |                           { | ||
| 329 |                                      pJpegDecoder->abChannelType[bcount] = JPEG_bReadByte(pJpegDecoder->pImageFile); | ||
| 330 |                                      btemp = JPEG_bReadByte(pJpegDecoder->pImageFile); | ||
| 331 |                                      pJpegDecoder->abChannelHSampFactor[bcount] = btemp >> 4; | ||
| 332 |                                      pJpegDecoder->abChannelVSampFactor[bcount] = btemp & 0x0F; | ||
| 333 |                                      pJpegDecoder->abChannelQuantTableMap[bcount] = JPEG_bReadByte(pJpegDecoder->pImageFile); | ||
| 334 |                           } | ||
| 335 |                           break; | ||
| 336 | |||
| 337 |                case APP0: /* Start of Application */ | ||
| 338 |                           wSegLen = JPEG_wReadWord(pJpegDecoder->pImageFile); | ||
| 339 |                           if(wSegLen < 16) | ||
| 340 |                           { | ||
| 341 |                                      JPEG_SendError(100); | ||
| 342 |                                      break; | ||
| 343 |                           } | ||
| 344 |                           else | ||
| 345 |                           { | ||
| 346 |                                      unsigned char buf[5]; | ||
| 347 |                                      IMG_FREAD(buf, sizeof(buf[0]), 5, pJpegDecoder->pImageFile); | ||
| 348 |                                      if(buf[0] == 'J' && buf[1] == 'F' && buf[2] == 'I' && buf[3] == 'F' && buf[4] == '\0') | ||
| 349 |                                      { | ||
| 350 |                                                pJpegDecoder->blJFIF = TRUE; | ||
| 351 |                                      } | ||
| 352 |                           } | ||
| 353 |                           pJpegDecoder->bMajorRev = JPEG_bReadByte(pJpegDecoder->pImageFile); | ||
| 354 |                           pJpegDecoder->bMinorRev = JPEG_bReadByte(pJpegDecoder->pImageFile); | ||
| 355 |                           if(pJpegDecoder->bMajorRev != 1) | ||
| 356 |                           { | ||
| 357 |                                      JPEG_SendError(100); | ||
| 358 |                                      break; | ||
| 359 |                           } | ||
| 360 |                           /* Ignore other bytes in this segment */ | ||
| 361 |                           break; | ||
| 362 | |||
| 363 |                case DRI: /* Start of Quantization table */ | ||
| 364 |                           wSegLen = JPEG_wReadWord(pJpegDecoder->pImageFile); | ||
| 365 |                           if(wSegLen == 4) | ||
| 366 |                           { | ||
| 367 |                                      pJpegDecoder->wRestartInterval = JPEG_wReadWord(pJpegDecoder->pImageFile); | ||
| 368 |                           } | ||
| 369 |                           break; | ||
| 370 | |||
| 371 |                case DQT: /* Start of Quantization table */ | ||
| 372 |                           wSegLen = JPEG_wReadWord(pJpegDecoder->pImageFile); | ||
| 373 |                           if(wSegLen < 67) | ||
| 374 |                           { | ||
| 375 |                                      JPEG_SendError(100); | ||
| 376 |                                      break; | ||
| 377 |                           } | ||
| 378 | |||
| 379 |                           do | ||
| 380 |                           { | ||
| 381 |                                      BYTE bQTableIndex, bCounter; | ||
| 382 | |||
| 383 |                                      btemp = JPEG_bReadByte(pJpegDecoder->pImageFile); | ||
| 384 |                                      bQTableIndex = btemp & 0x0F; | ||
| 385 |                                      pJpegDecoder->blQuantUses16bits |= (btemp >> 4); | ||
| 386 | |||
| 387 |                                      for(bCounter = 0; bCounter < 64; bCounter++) | ||
| 388 |                                      { | ||
| 389 |                                                BYTE bData1, bData2 = 0; | ||
| 390 |                                                if(pJpegDecoder->blQuantUses16bits == 0) | ||
| 391 |                                                { | ||
| 392 |                                                          IMG_FREAD(&bData1, sizeof(BYTE), 1, pJpegDecoder->pImageFile); | ||
| 393 |                                                          pJpegDecoder->awQuantTable[bQTableIndex][abZigzag[bCounter]] = bData1; | ||
| 394 |                                                } | ||
| 395 |                                                else | ||
| 396 |                                                { | ||
| 397 |                                                          IMG_FREAD(&bData1, sizeof(BYTE), 1, pJpegDecoder->pImageFile); | ||
| 398 |                                                          IMG_FREAD(&bData2, sizeof(BYTE), 1, pJpegDecoder->pImageFile); | ||
| 399 |                                                          pJpegDecoder->awQuantTable[bQTableIndex][abZigzag[bCounter]] = (((WORD)bData1) << 8) + (WORD)bData2; | ||
| 400 |                                                } | ||
| 401 |                                      } | ||
| 402 |                                      wSegLen -= (pJpegDecoder->blQuantUses16bits == 0)? 65: 129; /* Table length + information byte */ | ||
| 403 |                           } while(wSegLen >= 67); | ||
| 404 |                           break; | ||
| 405 | |||
| 406 |                case DHT: /* Start of Huffmann table */ | ||
| 407 |                           wSegLen = JPEG_wReadWord(pJpegDecoder->pImageFile); | ||
| 408 |                           if(wSegLen < 19) | ||
| 409 |                           { | ||
| 410 |                                      JPEG_SendError(100); | ||
| 411 |                                      break; | ||
| 412 |                           } | ||
| 413 | |||
| 414 |                           do | ||
| 415 |                           { | ||
| 416 |                                      BYTE bHTableIndex, bCounter; | ||
| 417 |                                      WORD wNumOfSymbols; | ||
| 418 |                                      BYTE blIsAc; | ||
| 419 |                                      BYTE *pbLenTable, *pbSymTable; | ||
| 420 | |||
| 421 |                                      btemp = JPEG_bReadByte(pJpegDecoder->pImageFile); | ||
| 422 |                                      bHTableIndex = btemp & 0x0F; | ||
| 423 |                                      blIsAc = (btemp >> 4) & 0x01; | ||
| 424 | |||
| 425 |                                      if(blIsAc == 0) | ||
| 426 |                                      { | ||
| 427 |                                                pbLenTable = (BYTE*)&pJpegDecoder->abHuffDcSymLen[bHTableIndex][0]; | ||
| 428 |                                                pbSymTable = (BYTE*)&pJpegDecoder->abHuffDcSymbol[bHTableIndex][0]; | ||
| 429 |                                      } | ||
| 430 |                                      else | ||
| 431 |                                      { | ||
| 432 |                                                pbLenTable = (BYTE*)&pJpegDecoder->abHuffAcSymLen[bHTableIndex][0]; | ||
| 433 |                                                pbSymTable = (BYTE*)&pJpegDecoder->abHuffAcSymbol[bHTableIndex][0]; | ||
| 434 |                                      } | ||
| 435 | |||
| 436 |                                      IMG_FREAD(pbLenTable, sizeof(BYTE), 16, pJpegDecoder->pImageFile); | ||
| 437 | |||
| 438 |                                      for(bCounter = 0, wNumOfSymbols = 0; bCounter < 16; bCounter++) | ||
| 439 |                                      { | ||
| 440 |                                                wNumOfSymbols += pbLenTable[bCounter]; | ||
| 441 |                                      } | ||
| 442 | |||
| 443 |                                      wSegLen -= 17; /* This table length + information byte */ | ||
| 444 | |||
| 445 |                                      if(wSegLen < wNumOfSymbols || (blIsAc == 1 && wNumOfSymbols > 256) || (blIsAc == 0 && wNumOfSymbols > 16)) | ||
| 446 |                                      { | ||
| 447 |                                                JPEG_SendError(100); | ||
| 448 |                                                break; | ||
| 449 |                                      } | ||
| 450 | |||
| 451 |                                      IMG_FREAD(pbSymTable, sizeof(BYTE), wNumOfSymbols, pJpegDecoder->pImageFile); | ||
| 452 |                                      wSegLen -= wNumOfSymbols; /* This table length + information byte */ | ||
| 453 |                                      pJpegDecoder->bHuffTables++; | ||
| 454 |                           } while(wSegLen >= 19); | ||
| 455 |                           break; | ||
| 456 | |||
| 457 |                case SOS: /* Start of Scan parameters */ | ||
| 458 |                           wSegLen = JPEG_wReadWord(pJpegDecoder->pImageFile); | ||
| 459 |                           if(wSegLen < 3) | ||
| 460 |                           { | ||
| 461 |                                      JPEG_SendError(100); | ||
| 462 |                                      break; | ||
| 463 |                           } | ||
| 464 | |||
| 465 |                           btemp = JPEG_bReadByte(pJpegDecoder->pImageFile); | ||
| 466 |                           wOffset = wSegLen - (3 + (btemp * 2)); | ||
| 467 | |||
| 468 |                           if(pJpegDecoder->bChannels != btemp || wSegLen < 3 + (btemp * 2)) | ||
| 469 |                           { | ||
| 470 |                                      JPEG_SendError(100); | ||
| 471 |                                      break; | ||
| 472 |                           } | ||
| 473 |                           else | ||
| 474 |                           { | ||
| 475 |                                      BYTE bCounter, bChannelId = 0xFF; | ||
| 476 | |||
| 477 |                                      for(bCounter = 0; bCounter < pJpegDecoder->bChannels; bCounter++) | ||
| 478 |                                      { | ||
| 479 |                                                BYTE bindex; | ||
| 480 | |||
| 481 |                                                btemp = JPEG_bReadByte(pJpegDecoder->pImageFile); | ||
| 482 |                                                for(bindex = 0; bindex < MAX_CHANNELS; bindex++) | ||
| 483 |                                                { | ||
| 484 |                                                           if(pJpegDecoder->abChannelType[bindex] == btemp) | ||
| 485 |                                                           { | ||
| 486 |                                                                     bChannelId = bindex; | ||
| 487 |                                                                     break; | ||
| 488 |                                                           } | ||
| 489 |                                                } | ||
| 490 | |||
| 491 |                                                if(bChannelId < MAX_CHANNELS) | ||
| 492 |                                                { | ||
| 493 |                                                           btemp = JPEG_bReadByte(pJpegDecoder->pImageFile); | ||
| 494 |                                                           pJpegDecoder->abChannelHuffAcTableMap[bChannelId] = btemp & 0x0F; | ||
| 495 |                                                           pJpegDecoder->abChannelHuffDcTableMap[bChannelId] = btemp >> 4; | ||
| 496 |                                                } | ||
| 497 |                                      } | ||
| 498 |                                      IMG_FSEEK(pJpegDecoder->pImageFile, wOffset, 1); | ||
| 499 |                           } | ||
| 500 |                           blSOSOver = TRUE; | ||
| 501 |                           break; | ||
| 502 | |||
| 503 |                default: /* Any other segment with length */ | ||
| 504 |                           wSegLen = JPEG_wReadWord(pJpegDecoder->pImageFile); | ||
| 505 |                           if(wSegLen < 2) | ||
| 506 |                           { | ||
| 507 |                                      JPEG_SendError(100); | ||
| 508 |                                      break; | ||
| 509 |                           } | ||
| 510 |                           IMG_FSEEK(pJpegDecoder->pImageFile, wSegLen - 2, 1); | ||
| 511 |              } | ||
| 512 |      } | ||
| 513 |      return 0; | ||
| 514 | } | ||
| 515 | |||
| 516 | /******************************************************************************* | ||
| 517 | Function:       BYTE JPEG_bGenerateHuffmanTables(JPEGDECODER *pJpegDecoder) | ||
| 518 | |||
| 519 | Precondition:   None | ||
| 520 | |||
| 521 | Overview:       This function generated the table required for Huffman decoding | ||
| 522 |                 from the data read from the header | ||
| 523 | |||
| 524 | Input:          JPEGDECODER | ||
| 525 | |||
| 526 | Output:         Error code - '0' means no error | ||
| 527 | *******************************************************************************/ | ||
| 528 | static BYTE JPEG_bGenerateHuffmanTables(JPEGDECODER *pJpegDecoder) | ||
| 529 | { | ||
| 530 |      BYTE bLength, bTable; | ||
| 531 | |||
| 532 |      for(bTable = 0; bTable < pJpegDecoder->bHuffTables / 2; bTable++) | ||
| 533 |      { | ||
| 534 |             pJpegDecoder->awHuffAcSymStart[bTable][0] = 0; | ||
| 535 |             pJpegDecoder->awHuffDcSymStart[bTable][0] = 0; | ||
| 536 | |||
| 537 |             for(bLength = 1; bLength < 16; bLength++) | ||
| 538 |             { | ||
| 539 |                    pJpegDecoder->awHuffAcSymStart[bTable][bLength] = (pJpegDecoder->awHuffAcSymStart[bTable][bLength - 1] + pJpegDecoder->abHuffAcSymLen[bTable][bLength - 1]) << 1; | ||
| 540 |                    pJpegDecoder->awHuffDcSymStart[bTable][bLength] = (pJpegDecoder->awHuffDcSymStart[bTable][bLength - 1] + pJpegDecoder->abHuffDcSymLen[bTable][bLength - 1]) << 1; | ||
| 541 |             } | ||
| 542 |      } | ||
| 543 |      return 0; | ||
| 544 | } | ||
| 545 | |||
| 546 | /******************************************************************************* | ||
| 547 | Function:       BYTE JPEG_bGet1Bit(JPEGDECODER *pJpegDecoder) | ||
| 548 | |||
| 549 | Precondition:   None | ||
| 550 | |||
| 551 | Overview:       This function returns 1 bit as the lsb of the returned byte. | ||
| 552 |                 It automatically fills the buffer if it becomes empty. | ||
| 553 |                 It also converts 0xFF00 into 0. | ||
| 554 | |||
| 555 | Input:          JPEGDECODER | ||
| 556 | |||
| 557 | Output:         One bit | ||
| 558 | *******************************************************************************/ | ||
| 559 | static BYTE JPEG_bGet1Bit(JPEGDECODER *pJpegDecoder) | ||
| 560 | { | ||
| 561 |      BYTE bBit = 0; | ||
| 562 | |||
| 563 |      if(pJpegDecoder->wBufferIndex >= pJpegDecoder->wBufferLen) | ||
| 564 |      { | ||
| 565 |             pJpegDecoder->wBufferLen = IMG_FREAD(&pJpegDecoder->abDataBuffer[0], sizeof(BYTE), MAX_DATA_BUF_LEN, pJpegDecoder->pImageFile); | ||
| 566 |             while(pJpegDecoder->abDataBuffer[pJpegDecoder->wBufferLen - 1] == 0xFF) | ||
| 567 |             { | ||
| 568 |                    pJpegDecoder->wBufferLen--; | ||
| 569 |                    IMG_FSEEK(pJpegDecoder->pImageFile, -1, 1); | ||
| 570 |             } | ||
| 571 |             pJpegDecoder->wBufferIndex = 0; | ||
| 572 |      } | ||
| 573 | |||
| 574 |      while(pJpegDecoder->bBitsAvailable == 0) /* Be very careful to touch this part of code! You must know exactly what you are doing */ | ||
| 575 |      { | ||
| 576 |             pJpegDecoder->bBitsAvailable = 16; | ||
| 577 |             pJpegDecoder->wWorkBits = pJpegDecoder->abDataBuffer[pJpegDecoder->wBufferIndex++]; | ||
| 578 |             pJpegDecoder->wWorkBits = (pJpegDecoder->wWorkBits << 8) + pJpegDecoder->abDataBuffer[pJpegDecoder->wBufferIndex++]; | ||
| 579 |             if(pJpegDecoder->wBufferIndex > pJpegDecoder->wBufferLen) /* wBufferIndex need not be even because of the below condition */ | ||
| 580 |             { | ||
| 581 |                    pJpegDecoder->bBitsAvailable = 8; | ||
| 582 |             } | ||
| 583 |             else if((pJpegDecoder->wWorkBits & 0x00FF) == 0x00FF) | ||
| 584 |             { | ||
| 585 |                    pJpegDecoder->bBitsAvailable = 8; | ||
| 586 |                    pJpegDecoder->wBufferIndex--; | ||
| 587 |             } | ||
| 588 |             else if(pJpegDecoder->wWorkBits >= 0xFF00) | ||
| 589 |             { | ||
| 590 |                    if(pJpegDecoder->wWorkBits == 0xFF00) | ||
| 591 |                    { | ||
| 592 |                          pJpegDecoder->bBitsAvailable = 8; | ||
| 593 |                    } | ||
| 594 |             } | ||
| 595 |      } | ||
| 596 | |||
| 597 |      bBit = (pJpegDecoder->wWorkBits & 0x8000)? 0x01: 0; | ||
| 598 | |||
| 599 |      pJpegDecoder->wWorkBits <<= 1; | ||
| 600 |      pJpegDecoder->bBitsAvailable--; | ||
| 601 | |||
| 602 |      return bBit; | ||
| 603 | } | ||
| 604 | |||
| 605 | /******************************************************************************* | ||
| 606 | Function:       WORD JPEG_wGetBits(JPEGDECODER *pJpegDecoder, BYTE bLen) | ||
| 607 | |||
| 608 | Precondition:   None | ||
| 609 | |||
| 610 | Overview:       This function returns bLen number of bits as the lsb of the | ||
| 611 |                 returned word and it automatically fills the buffer | ||
| 612 |                 if it becomes empty. | ||
| 613 | |||
| 614 | Input:          JPEGDECODER, Number of bits | ||
| 615 | |||
| 616 | Output:         Requested number of bits | ||
| 617 | *******************************************************************************/ | ||
| 618 | static WORD JPEG_wGetBits(JPEGDECODER *pJpegDecoder, BYTE bLen) | ||
| 619 | { | ||
| 620 |      WORD wVal = 0; | ||
| 621 | |||
| 622 |      wVal = pJpegDecoder->bFirstBit = JPEG_bGet1Bit(pJpegDecoder); | ||
| 623 |      bLen--; | ||
| 624 | |||
| 625 |      while(bLen) | ||
| 626 |      { | ||
| 627 |             wVal = (wVal << 1) + JPEG_bGet1Bit(pJpegDecoder); | ||
| 628 |             bLen--; | ||
| 629 |      } | ||
| 630 | |||
| 631 |      return wVal;    | ||
| 632 | } | ||
| 633 | |||
| 634 | /******************************************************************************* | ||
| 635 | Function:       WORD JPEG_wGetRestartWord(JPEGDECODER *pJpegDecoder) | ||
| 636 | |||
| 637 | Precondition:   File pointer must point to the restart word | ||
| 638 | |||
| 639 | Overview:       Returns the restart word | ||
| 640 | |||
| 641 | Input:          JPEGDECODER | ||
| 642 | |||
| 643 | Output:         Restart word | ||
| 644 | *******************************************************************************/ | ||
| 645 | static WORD JPEG_wGetRestartWord(JPEGDECODER *pJpegDecoder) | ||
| 646 | { | ||
| 647 |      WORD wRestartWord; | ||
| 648 |      while((pJpegDecoder->bBitsAvailable & 0x07) != 0) /* This is to clearoff wnwanted bits to go to fresh byte */ | ||
| 649 |      { | ||
| 650 |             JPEG_bGet1Bit(pJpegDecoder); | ||
| 651 |      } | ||
| 652 |      wRestartWord = JPEG_wGetBits(pJpegDecoder, 16); | ||
| 653 |      return(wRestartWord); | ||
| 654 | } | ||
| 655 | |||
| 656 | /******************************************************************************* | ||
| 657 | Function:       SHORT JPEG_sGetBitsValue(JPEGDECODER *pJpegDecoder, BYTE bLen) | ||
| 658 | |||
| 659 | Precondition:   None | ||
| 660 | |||
| 661 | Overview:       Returns the signed value of the bLen bits of data | ||
| 662 | |||
| 663 | Input:          JPEGDECODER, Number of bits | ||
| 664 | |||
| 665 | Output:         Signed number | ||
| 666 | *******************************************************************************/ | ||
| 667 | static SHORT JPEG_sGetBitsValue(JPEGDECODER *pJpegDecoder, BYTE bLen) | ||
| 668 | { | ||
| 669 |      WORD wVal = 0; | ||
| 670 | |||
| 671 |      if(bLen != 0) | ||
| 672 |      {   | ||
| 673 |             wVal = JPEG_wGetBits(pJpegDecoder, bLen); | ||
| 674 |             if(pJpegDecoder->bFirstBit == 0) | ||
| 675 |             { | ||
| 676 |                    wVal = ~(wVal | (0xFFFF << bLen)); | ||
| 677 |                    return ((SHORT)wVal * -1); | ||
| 678 |             } | ||
| 679 |      } | ||
| 680 |      return (SHORT)wVal; | ||
| 681 | } | ||
| 682 | |||
| 683 | /******************************************************************************* | ||
| 684 | Function:       BYTE JPEG_bGetNextHuffByte(JPEGDECODER *pJpegDecoder) | ||
| 685 | |||
| 686 | Precondition:   File pointer must point to the Huffman data | ||
| 687 | |||
| 688 | Overview:       Returns the Huffman decoded data | ||
| 689 | |||
| 690 | Input:          JPEGDECODER | ||
| 691 | |||
| 692 | Output:         Huffman decoded data | ||
| 693 | *******************************************************************************/ | ||
| 694 | static BYTE JPEG_bGetNextHuffByte(JPEGDECODER *pJpegDecoder) | ||
| 695 | { | ||
| 696 |      BYTE bBits, bSymbol = 0; | ||
| 697 |      WORD wBitPattern = 0, wSymbolOffset = 0; | ||
| 698 | |||
| 699 |      for(bBits = 0; bBits < 16; bBits++) | ||
| 700 |      { | ||
| 701 |             BYTE bSymbols; | ||
| 702 |             WORD wDiff; | ||
| 703 | |||
| 704 |             wBitPattern = (wBitPattern << 1) + JPEG_bGet1Bit(pJpegDecoder); | ||
| 705 |             bSymbols = pJpegDecoder->pbCurrentHuffSymLenTable[bBits]; | ||
| 706 |             if(bSymbols == 0) | ||
| 707 |             { | ||
| 708 |                    continue; | ||
| 709 |             } | ||
| 710 | |||
| 711 |             wDiff = wBitPattern - pJpegDecoder->pwCurrentHuffSymStartTable[bBits]; | ||
| 712 |             if(wDiff < bSymbols) | ||
| 713 |             { | ||
| 714 |                    bSymbol = pJpegDecoder->pbCurrentHuffSymbolTable[wSymbolOffset + wDiff]; | ||
| 715 |                    break; | ||
| 716 |             } | ||
| 717 |             wSymbolOffset += bSymbols; | ||
| 718 |      } | ||
| 719 |      return bSymbol; | ||
| 720 | } | ||
| 721 | |||
| 722 | #define range_limit(x) (x<0)?0:(x>0xFF)?0xFF:x | ||
| 723 | /******************************************************************************* | ||
| 724 | Function:       BYTE JPEG_bDecodeOneBlock(JPEGDECODER *pJpegDecoder) | ||
| 725 | |||
| 726 | Precondition:   File pointer must point to a new block of data | ||
| 727 | |||
| 728 | Overview:       Decodes the 8x8 pixel values of all the channels | ||
| 729 |                 (A multiple of 8x8 block if subsampling is used) | ||
| 730 | |||
| 731 | Input:          JPEGDECODER | ||
| 732 | |||
| 733 | Output:         Error code - '0' means no error | ||
| 734 | *******************************************************************************/ | ||
| 735 | static BYTE JPEG_bDecodeOneBlock(JPEGDECODER *pJpegDecoder) | ||
| 736 | { | ||
| 737 |      BYTE bBlock, bCounter; | ||
| 738 | |||
| 739 |      IMG_vLoopCallback(); | ||
| 740 |      for(bBlock = 0; bBlock < pJpegDecoder->bBlocksInOnePass; bBlock++) | ||
| 741 |      { | ||
| 742 |             BYTE bByteCount, bHuffbyte; | ||
| 743 | |||
| 744 |             if((pJpegDecoder->wRestartInterval > 0) && (pJpegDecoder->wBlockNumber == pJpegDecoder->wRestartInterval * pJpegDecoder->bBlocksInOnePass)) | ||
| 745 |             { | ||
| 746 |                    WORD wRestartWord = JPEG_wGetRestartWord(pJpegDecoder); | ||
| 747 |                    if(wRestartWord < 0xFFD0 || wRestartWord > 0xFFD7) | ||
| 748 |                    { | ||
| 749 |                             JPEG_SendError(100); | ||
| 750 |                    }                           | ||
| 751 |                    for(bCounter = 0; bCounter < MAX_CHANNELS; bCounter++) | ||
| 752 |                    { | ||
| 753 |                             pJpegDecoder->asPrevDcValue[bCounter] = 0; | ||
| 754 |                    }                    | ||
| 755 |                    pJpegDecoder->wBlockNumber = 0; | ||
| 756 |             } | ||
| 757 | |||
| 758 |             for(bCounter = 0; bCounter < 64; bCounter++) | ||
| 759 |             { | ||
| 760 |                    pJpegDecoder->asOneBlock[bBlock][bCounter] = 0; | ||
| 761 |             } | ||
| 762 | |||
| 763 |             pJpegDecoder->pwCurrentQuantTable = &pJpegDecoder->awQuantTable[pJpegDecoder->abChannelQuantTableMap[pJpegDecoder->abChannelMap[bBlock]]][0]; | ||
| 764 | |||
| 765 |             /* Decode DC value */ | ||
| 766 |             bByteCount = 0; | ||
| 767 |             pJpegDecoder->pbCurrentHuffSymLenTable = &pJpegDecoder->abHuffDcSymLen[pJpegDecoder->abChannelHuffDcTableMap[pJpegDecoder->abChannelMap[bBlock]]][0]; | ||
| 768 |             pJpegDecoder->pbCurrentHuffSymbolTable = &pJpegDecoder->abHuffDcSymbol[pJpegDecoder->abChannelHuffDcTableMap[pJpegDecoder->abChannelMap[bBlock]]][0]; | ||
| 769 |             pJpegDecoder->pwCurrentHuffSymStartTable = &pJpegDecoder->awHuffDcSymStart[pJpegDecoder->abChannelHuffDcTableMap[pJpegDecoder->abChannelMap[bBlock]]][0]; | ||
| 770 |             bHuffbyte = JPEG_bGetNextHuffByte(pJpegDecoder); | ||
| 771 |             pJpegDecoder->asOneBlock[bBlock][0] = JPEG_sGetBitsValue(pJpegDecoder, bHuffbyte & 0x0F) + pJpegDecoder->asPrevDcValue[pJpegDecoder->abChannelMap[bBlock]]; | ||
| 772 |             pJpegDecoder->asPrevDcValue[pJpegDecoder->abChannelMap[bBlock]] = pJpegDecoder->asOneBlock[bBlock][0]; | ||
| 773 | |||
| 774 |             /* Decode AC value */ | ||
| 775 |             bByteCount = 1; | ||
| 776 |             pJpegDecoder->pbCurrentHuffSymLenTable = &pJpegDecoder->abHuffAcSymLen[pJpegDecoder->abChannelHuffAcTableMap[pJpegDecoder->abChannelMap[bBlock]]][0]; | ||
| 777 |             pJpegDecoder->pbCurrentHuffSymbolTable = &pJpegDecoder->abHuffAcSymbol[pJpegDecoder->abChannelHuffAcTableMap[pJpegDecoder->abChannelMap[bBlock]]][0]; | ||
| 778 |             pJpegDecoder->pwCurrentHuffSymStartTable = &pJpegDecoder->awHuffAcSymStart[pJpegDecoder->abChannelHuffAcTableMap[pJpegDecoder->abChannelMap[bBlock]]][0]; | ||
| 779 |             while(bByteCount < 64) | ||
| 780 |             { | ||
| 781 |                    bHuffbyte = JPEG_bGetNextHuffByte(pJpegDecoder); | ||
| 782 |                    bByteCount += (bHuffbyte >> 4); | ||
| 783 |                    if(bHuffbyte == 0 /* EOB */) | ||
| 784 |                    { | ||
| 785 |                           break; | ||
| 786 |                    } | ||
| 787 |                    if(bByteCount > 63) | ||
| 788 |                    { | ||
| 789 |                           JPEG_SendError(100); | ||
| 790 |                    } | ||
| 791 |                    pJpegDecoder->asOneBlock[bBlock][abZigzag[bByteCount++]] = JPEG_sGetBitsValue(pJpegDecoder, bHuffbyte & 0x0F); | ||
| 792 |             } | ||
| 793 |             pJpegDecoder->wBlockNumber++; | ||
| 794 |             jpeg_idct_islow(&pJpegDecoder->asOneBlock[bBlock][0],pJpegDecoder->pwCurrentQuantTable); | ||
| 795 |      } | ||
| 796 | |||
| 797 | //     SetVisualPage(1); | ||
| 798 | |||
| 799 |      return 0; | ||
| 800 | } | ||
| 801 | |||
| 802 | #define JPEG_WRITE_TO_DISPLAY | ||
| 803 | /******************************************************************************* | ||
| 804 | Function:       void JPEG_vInitDisplay(JPEGDECODER *pJpegDecoder) | ||
| 805 | |||
| 806 | Precondition:   None | ||
| 807 | |||
| 808 | Overview:       Initializes the (x, y) co-ordinates to (0, 0) | ||
| 809 | |||
| 810 | Input:          JPEGDECODER | ||
| 811 | |||
| 812 | Output:         None | ||
| 813 | *******************************************************************************/ | ||
| 814 | static void JPEG_vInitDisplay(JPEGDECODER *pJpegDecoder) | ||
| 815 | { | ||
| 816 |  #ifndef JPEG_WRITE_TO_DISPLAY | ||
| 817 |      printf("%4u %4u\n", pJpegDecoder->wWidth, pJpegDecoder->wHeight); | ||
| 818 |  #else | ||
| 819 |     pJpegDecoder->wPrevX = 0; | ||
| 820 |     pJpegDecoder->wPrevY = 0; | ||
| 821 | //    SetActivePage(1); | ||
| 822 |  #endif | ||
| 823 | } | ||
| 824 | |||
| 825 | /******************************************************************************* | ||
| 826 | Function:       BYTE JPEG_bPaintOneBlock(JPEGDECODER *pJpegDecoder) | ||
| 827 | |||
| 828 | Precondition:   One block - 8x8 pixel data of all channels must be decoded | ||
| 829 | |||
| 830 | Overview:       Displays one 8x8 on the screen | ||
| 831 |                 (A multiple of 8x8 block if subsampling is used) | ||
| 832 | |||
| 833 | Input:          JPEGDECODER | ||
| 834 | |||
| 835 | Output:         Error code - '0' means no error | ||
| 836 | *******************************************************************************/ | ||
| 837 | static BYTE JPEG_bPaintOneBlock(JPEGDECODER *pJpegDecoder) | ||
| 838 | { | ||
| 839 |      BYTE bCounter; | ||
| 840 | |||
| 841 |  #ifndef JPEG_WRITE_TO_DISPLAY | ||
| 842 | |||
| 843 |      for(bCounter = 0; bCounter < 64; bCounter++) | ||
| 844 |      { | ||
| 845 |             printf("%3u %3u %3u\n", abBlockR[bCounter]&0xF8, abBlockG[bCounter]&0xFC, abBlockB[bCounter]&0xF8); | ||
| 846 |      } | ||
| 847 | |||
| 848 |  #else | ||
| 849 | |||
| 850 |      WORD wX, wY; | ||
| 851 |      bCounter = 0; | ||
| 852 |      BYTE r,g,b; | ||
| 853 | |||
| 854 |      if(pJpegDecoder->bSubSampleType == JPEG_SAMPLE_1x1) | ||
| 855 |      { | ||
| 856 |             SHORT *psY = &pJpegDecoder->asOneBlock[0][0], *psCb = &pJpegDecoder->asOneBlock[1][0], *psCr = &pJpegDecoder->asOneBlock[2][0]; | ||
| 857 | |||
| 858 |             for(wY = 0; wY < 8; wY++) | ||
| 859 |             { | ||
| 860 |                     for(wX = 0; wX < 8; wX++) | ||
| 861 |                     { | ||
| 862 |                             LONG s1 = ((*psY) + 128)*128, s2 = (*psCb), s3 = (*psCr); | ||
| 863 |                             r = range_limit((s1 + 180*s3)>>7); | ||
| 864 |                             g = range_limit((s1 - 44*s2 - 91*s3)>>7); | ||
| 865 |                             b = range_limit((s1 + 227*s2)>>7); | ||
| 866 |                             IMG_vSetColor(r, g, b); | ||
| 867 |                             IMG_vPutPixel(pJpegDecoder->wPrevX + wX, pJpegDecoder->wPrevY + wY); | ||
| 868 |                             psY++; psCb++; psCr++; | ||
| 869 |                     }   | ||
| 870 |              } | ||
| 871 | |||
| 872 |             pJpegDecoder->wPrevX += 8; | ||
| 873 | |||
| 874 |             if(pJpegDecoder->wPrevX >= pJpegDecoder->wWidth) | ||
| 875 |             { | ||
| 876 |                     pJpegDecoder->wPrevX = 0; | ||
| 877 |                     pJpegDecoder->wPrevY += 8; | ||
| 878 |             } | ||
| 879 |      }        | ||
| 880 |      else if(pJpegDecoder->bSubSampleType == JPEG_SAMPLE_1x2) | ||
| 881 |      { | ||
| 882 |             SHORT *psY, *psCb = &pJpegDecoder->asOneBlock[2][0], *psCr = &pJpegDecoder->asOneBlock[3][0]; | ||
| 883 |             BYTE bBlock, bOffsetY[2] = {0,8}; | ||
| 884 | |||
| 885 |             for(bBlock = 0; bBlock < 2; bBlock++) | ||
| 886 |             { | ||
| 887 |                     psY = &pJpegDecoder->asOneBlock[bBlock][0]; | ||
| 888 |                     psCb = &pJpegDecoder->asOneBlock[2][bBlock*32]; | ||
| 889 |                     psCr = &pJpegDecoder->asOneBlock[3][bBlock*32]; | ||
| 890 |                     for(wY = 0; wY < 8; wY++) | ||
| 891 |                     { | ||
| 892 |                             for(wX = 0; wX < 8; wX++) | ||
| 893 |                             { | ||
| 894 |                                      LONG s1 = ((*psY) + 128)*128; | ||
| 895 |                                      LONG s2 = psCb[(wY>>1)*8+wX]; | ||
| 896 |                                      LONG s3 = psCr[(wY>>1)*8+wX]; | ||
| 897 |                                      r = range_limit((s1 + 180*s3)>>7); | ||
| 898 |                                      g = range_limit((s1 - 44*s2 - 91*s3)>>7); | ||
| 899 |                                      b = range_limit((s1 + 227*s2)>>7); | ||
| 900 |                                      IMG_vSetColor(r, g, b); | ||
| 901 |                                      IMG_vPutPixel(pJpegDecoder->wPrevX + wX, | ||
| 902 |                                               pJpegDecoder->wPrevY + bOffsetY[bBlock] + wY); | ||
| 903 |                                      psY++; | ||
| 904 |                             } | ||
| 905 |                     } | ||
| 906 |             } | ||
| 907 | |||
| 908 |             pJpegDecoder->wPrevX += 8; | ||
| 909 | |||
| 910 |             if(pJpegDecoder->wPrevX >= pJpegDecoder->wWidth) | ||
| 911 |             { | ||
| 912 |                     pJpegDecoder->wPrevX = 0; | ||
| 913 |                     pJpegDecoder->wPrevY += 16; | ||
| 914 |             } | ||
| 915 |      }        | ||
| 916 |      else if(pJpegDecoder->bSubSampleType == JPEG_SAMPLE_2x1) | ||
| 917 |      { | ||
| 918 |             SHORT *psY, *psCb = &pJpegDecoder->asOneBlock[2][0], *psCr = &pJpegDecoder->asOneBlock[3][0]; | ||
| 919 |             BYTE bBlock, bOffsetX[2] = {0,8}; | ||
| 920 | |||
| 921 |             for(bBlock = 0; bBlock < 2; bBlock++) | ||
| 922 |             { | ||
| 923 |                     psY = &pJpegDecoder->asOneBlock[bBlock][0]; | ||
| 924 |                     psCb = &pJpegDecoder->asOneBlock[2][bBlock*4]; | ||
| 925 |                     psCr = &pJpegDecoder->asOneBlock[3][bBlock*4]; | ||
| 926 |                     for(wY = 0; wY < 8; wY++) | ||
| 927 |                     { | ||
| 928 |                             for(wX = 0; wX < 8; wX++) | ||
| 929 |                             { | ||
| 930 |                                      LONG s1 = ((*psY) + 128)*128; | ||
| 931 |                                      LONG s2 = psCb[(wY*8)+(wX>>1)]; | ||
| 932 |                                      LONG s3 = psCr[(wY*8)+(wX>>1)]; | ||
| 933 |                                      r = range_limit((s1 + 180*s3)>>7); | ||
| 934 |                                      g = range_limit((s1 - 44*s2 - 91*s3)>>7); | ||
| 935 |                                      b = range_limit((s1 + 227*s2)>>7); | ||
| 936 |                                      IMG_vSetColor(r, g, b); | ||
| 937 |                                      IMG_vPutPixel(pJpegDecoder->wPrevX + bOffsetX[bBlock] + wX, | ||
| 938 |                                               pJpegDecoder->wPrevY + wY); | ||
| 939 |                                      psY++; | ||
| 940 |                             } | ||
| 941 |                     } | ||
| 942 |             } | ||
| 943 | |||
| 944 |             pJpegDecoder->wPrevX += 16; | ||
| 945 | |||
| 946 |             if(pJpegDecoder->wPrevX >= pJpegDecoder->wWidth) | ||
| 947 |             { | ||
| 948 |                     pJpegDecoder->wPrevX = 0; | ||
| 949 |                     pJpegDecoder->wPrevY += 8; | ||
| 950 |             } | ||
| 951 |      } | ||
| 952 |      else if(pJpegDecoder->bSubSampleType == JPEG_SAMPLE_2x2) | ||
| 953 |      { | ||
| 954 |             SHORT *psY, *psCb, *psCr; | ||
| 955 |             BYTE bBlock, bOffsetX[4] = {0,8,0,8}, bOffsetY[4] = {0,0,8,8}, bCbCrOffset[4] = {0,4,32,36}; | ||
| 956 | |||
| 957 |             for(bBlock = 0; bBlock < 4; bBlock++) | ||
| 958 |             { | ||
| 959 |                     psY = &pJpegDecoder->asOneBlock[bBlock][0]; | ||
| 960 |                     psCb = &pJpegDecoder->asOneBlock[4][bCbCrOffset[bBlock]]; | ||
| 961 |                     psCr = &pJpegDecoder->asOneBlock[5][bCbCrOffset[bBlock]]; | ||
| 962 |                     for(wY = 0; wY < 8; wY++) | ||
| 963 |                     { | ||
| 964 |                             for(wX = 0; wX < 8; wX++) | ||
| 965 |                             { | ||
| 966 |                                      LONG s1 = ((*psY) + 128)*128; | ||
| 967 |                                      LONG s2 = psCb[(wY>>1)*8+(wX>>1)]; | ||
| 968 |                                      LONG s3 = psCr[(wY>>1)*8+(wX>>1)]; | ||
| 969 |                                      r = range_limit((s1 + 180*s3)>>7); | ||
| 970 |                                      g = range_limit((s1 - 44*s2 - 91*s3)>>7); | ||
| 971 |                                      b = range_limit((s1 + 227*s2)>>7); | ||
| 972 |                                      IMG_vSetColor(r, g, b); | ||
| 973 |                                      IMG_vPutPixel(pJpegDecoder->wPrevX + bOffsetX[bBlock] + wX, | ||
| 974 |                                               pJpegDecoder->wPrevY + bOffsetY[bBlock] + wY); | ||
| 975 |                                      psY++; | ||
| 976 |                             } | ||
| 977 |                     } | ||
| 978 |             } | ||
| 979 | |||
| 980 |             pJpegDecoder->wPrevX += 16; | ||
| 981 | |||
| 982 |             if(pJpegDecoder->wPrevX >= pJpegDecoder->wWidth) | ||
| 983 |             { | ||
| 984 |                     pJpegDecoder->wPrevX = 0; | ||
| 985 |                     pJpegDecoder->wPrevY += 16; | ||
| 986 |             } | ||
| 987 |      }        | ||
| 988 | |||
| 989 |  #endif | ||
| 990 |      return 0; | ||
| 991 | } | ||
| 992 | |||
| 993 | #ifndef IMG_USE_NON_BLOCKING_DECODING | ||
| 994 | |||
| 995 | /******************************************************************************* | ||
| 996 | Function:       BYTE JPEG_bDecode(IMG_FILE *pfile, BOOL bFirstTime) | ||
| 997 | |||
| 998 | Precondition:   The global variables of Image decoder must be set | ||
| 999 | |||
| 1000 | Overview:       This function decodes and displays a jpeg image | ||
| 1001 | |||
| 1002 | Input:          Image file, ignored BOOLean | ||
| 1003 | |||
| 1004 | Output:         Error code - '0' means no error | ||
| 1005 | *******************************************************************************/ | ||
| 1006 | BYTE JPEG_bDecode(IMG_FILE *pfile, BOOL bFirstTime) | ||
| 1007 | { | ||
| 1008 |      WORD whblocks, wvblocks; | ||
| 1009 |      WORD wi, wj; | ||
| 1010 |      JPEGDECODER JPEG_JpegDecoder; | ||
| 1011 | |||
| 1012 |      JPEG_vResetDecoder(&JPEG_JpegDecoder); | ||
| 1013 |      JPEG_JpegDecoder.pImageFile = pfile; | ||
| 1014 |      if(JPEG_bReadHeader(&JPEG_JpegDecoder) != 0) | ||
| 1015 |      { | ||
| 1016 |          return JPEG_JpegDecoder.bError; | ||
| 1017 |      } | ||
| 1018 | |||
| 1019 |      IMG_wImageWidth = JPEG_JpegDecoder.wWidth; | ||
| 1020 |      IMG_wImageHeight = JPEG_JpegDecoder.wHeight; | ||
| 1021 |      IMG_vSetboundaries(); | ||
| 1022 | |||
| 1023 |      JPEG_bGenerateHuffmanTables(&JPEG_JpegDecoder); | ||
| 1024 | |||
| 1025 |      whblocks = JPEG_JpegDecoder.wWidth >> 3; | ||
| 1026 |      wvblocks = JPEG_JpegDecoder.wHeight >> 3; | ||
| 1027 | |||
| 1028 |      if(whblocks * 8 < JPEG_JpegDecoder.wWidth) /* Odd sizes */ | ||
| 1029 |      { | ||
| 1030 |          whblocks++; | ||
| 1031 |      } | ||
| 1032 | |||
| 1033 |      if(wvblocks * 8 < JPEG_JpegDecoder.wHeight) /* Odd sizes */ | ||
| 1034 |      { | ||
| 1035 |          wvblocks++; | ||
| 1036 |      } | ||
| 1037 | |||
| 1038 |      if(JPEG_JpegDecoder.bSubSampleType == JPEG_SAMPLE_1x2) | ||
| 1039 |      { | ||
| 1040 |          wvblocks =  (wvblocks>>1) + (wvblocks&1); | ||
| 1041 |      } | ||
| 1042 |      else if(JPEG_JpegDecoder.bSubSampleType == JPEG_SAMPLE_2x1) | ||
| 1043 |      { | ||
| 1044 |          whblocks = (whblocks>>1) + (whblocks&1); | ||
| 1045 |      } | ||
| 1046 |      else if(JPEG_JpegDecoder.bSubSampleType == JPEG_SAMPLE_2x2) | ||
| 1047 |      { | ||
| 1048 |          wvblocks =  (wvblocks>>1) + (wvblocks&1); | ||
| 1049 |          whblocks = (whblocks>>1) + (whblocks&1); | ||
| 1050 |      } | ||
| 1051 | |||
| 1052 |      JPEG_vInitDisplay(&JPEG_JpegDecoder); | ||
| 1053 | |||
| 1054 |      for(wi = 0; wi < whblocks; wi++) | ||
| 1055 |      { | ||
| 1056 |             for(wj = 0; wj < wvblocks; wj++) | ||
| 1057 |             { | ||
| 1058 |                    IMG_vCheckAndAbort(); | ||
| 1059 |                    JPEG_bDecodeOneBlock(&JPEG_JpegDecoder); /* Fills a block after correcting the zigzag, dequantizing, IDCR and color conversion to RGB */ | ||
| 1060 |                    JPEG_bPaintOneBlock(&JPEG_JpegDecoder); /* Sends the block to the Graphics unit */ | ||
| 1061 |             } | ||
| 1062 |      } | ||
| 1063 |      return JPEG_JpegDecoder.bError; | ||
| 1064 | } | ||
| 1065 | |||
| 1066 | #else | ||
| 1067 | |||
| 1068 | /******************************************************************************* | ||
| 1069 | Function:       BYTE JPEG_bDecode(IMG_FILE *pfile, BOOL bFirstTime) | ||
| 1070 | |||
| 1071 | Precondition:   The global variables of Image decoder must be set | ||
| 1072 | |||
| 1073 | Overview:       This function decodes and displays a jpeg image | ||
| 1074 | |||
| 1075 | Input:          Image file, BOOLean indicating if this is the first time calling  | ||
| 1076 | 				the JPEG_bDecode function (needed to reset internal decoding  | ||
| 1077 | 				state variables).  If bFirstTime is TRUE, pfile must be set.   | ||
| 1078 | 				If bFirstTime is FALSE, pfile is ignored (uses previously  | ||
| 1079 | 				provided file handle). | ||
| 1080 | |||
| 1081 | Output:         Error code - '0' means not yet completed | ||
| 1082 | *******************************************************************************/ | ||
| 1083 | BYTE JPEG_bDecode(IMG_FILE *pfile, BOOL bFirstTime) | ||
| 1084 | { | ||
| 1085 | 	static WORD whblocks, wvblocks; | ||
| 1086 | 	static WORD wi, wj; | ||
| 1087 | 	static JPEGDECODER JPEG_JpegDecoder; | ||
| 1088 | 	static enum | ||
| 1089 | 	{ | ||
| 1090 | 		INITIAL, | ||
| 1091 | 		HEADER_DECODED, | ||
| 1092 | 		BLOCK_DECODE, | ||
| 1093 | 		DECODE_DONE | ||
| 1094 | 	} decodestate; | ||
| 1095 | |||
| 1096 | |||
| 1097 | 	if(bFirstTime) | ||
| 1098 | 		decodestate = INITIAL; | ||
| 1099 | |||
| 1100 |     switch(decodestate) | ||
| 1101 |     { | ||
| 1102 | |||
| 1103 |         case INITIAL:   JPEG_vResetDecoder(&JPEG_JpegDecoder); | ||
| 1104 |                         JPEG_JpegDecoder.pImageFile = pfile; | ||
| 1105 |                         if(JPEG_bReadHeader(&JPEG_JpegDecoder) != 0) | ||
| 1106 |                         { | ||
| 1107 |                             return 1; | ||
| 1108 |                         } | ||
| 1109 |                         decodestate = HEADER_DECODED; | ||
| 1110 |                         return 0; | ||
| 1111 | |||
| 1112 |         case HEADER_DECODED: | ||
| 1113 |                             IMG_wImageWidth = JPEG_JpegDecoder.wWidth; | ||
| 1114 |                             IMG_wImageHeight = JPEG_JpegDecoder.wHeight; | ||
| 1115 |                             IMG_vSetboundaries(); | ||
| 1116 | |||
| 1117 |                             JPEG_bGenerateHuffmanTables(&JPEG_JpegDecoder); | ||
| 1118 | |||
| 1119 |                             whblocks = JPEG_JpegDecoder.wWidth >> 3; | ||
| 1120 |                             wvblocks = JPEG_JpegDecoder.wHeight >> 3; | ||
| 1121 | |||
| 1122 |                             if(whblocks * 8 < JPEG_JpegDecoder.wWidth) /* Odd sizes */ | ||
| 1123 |                             { | ||
| 1124 |                                 whblocks++; | ||
| 1125 |                             } | ||
| 1126 | |||
| 1127 |                             if(wvblocks * 8 < JPEG_JpegDecoder.wHeight) /* Odd sizes */ | ||
| 1128 |                             { | ||
| 1129 |                                 wvblocks++; | ||
| 1130 |                             } | ||
| 1131 | |||
| 1132 |                             if(JPEG_JpegDecoder.bSubSampleType == JPEG_SAMPLE_1x2) | ||
| 1133 |                             { | ||
| 1134 |                                 wvblocks =  (wvblocks>>1) + (wvblocks&1); | ||
| 1135 |                             } | ||
| 1136 |                             else if(JPEG_JpegDecoder.bSubSampleType == JPEG_SAMPLE_2x1) | ||
| 1137 |                             { | ||
| 1138 |                                 whblocks = (whblocks>>1) + (whblocks&1); | ||
| 1139 |                             } | ||
| 1140 |                             else if(JPEG_JpegDecoder.bSubSampleType == JPEG_SAMPLE_2x2) | ||
| 1141 |                             { | ||
| 1142 |                                 wvblocks =  (wvblocks>>1) + (wvblocks&1); | ||
| 1143 |                                 whblocks = (whblocks>>1) + (whblocks&1); | ||
| 1144 |                             } | ||
| 1145 | |||
| 1146 |                             JPEG_vInitDisplay(&JPEG_JpegDecoder); | ||
| 1147 | |||
| 1148 |                             wi = 0; | ||
| 1149 |                             wj = 0; | ||
| 1150 | |||
| 1151 |                             decodestate = BLOCK_DECODE; | ||
| 1152 |                             return 0; | ||
| 1153 | |||
| 1154 |         case BLOCK_DECODE:  if(wi < whblocks) | ||
| 1155 |                             { | ||
| 1156 |                                 JPEG_bDecodeOneBlock(&JPEG_JpegDecoder); /* Fills a block after correcting the zigzag, dequantizing, IDCR and color conversion to RGB */ | ||
| 1157 |                                 JPEG_bPaintOneBlock(&JPEG_JpegDecoder); /* Sends the block to the Graphics unit */ | ||
| 1158 |                                 wj++; | ||
| 1159 | |||
| 1160 |                                 if(wj >= wvblocks) | ||
| 1161 |                                 { | ||
| 1162 |                                     wj = 0; | ||
| 1163 |                                     wi++; | ||
| 1164 |                                 } | ||
| 1165 |                                 return 0; | ||
| 1166 |                             } | ||
| 1167 | |||
| 1168 |                             decodestate = DECODE_DONE; | ||
| 1169 |                             // No break needed | ||
| 1170 | |||
| 1171 |         case DECODE_DONE:	return 1; | ||
| 1172 | |||
| 1173 |         default:            return 1; | ||
| 1174 |     } | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | #endif /* #ifndef IMG_USE_NON_BLOCKING_DECODING */ | ||
| 1178 | |||
| 1179 | #endif /* #ifdef IMG_SUPPORT_JPEG */ | ||
| 1180 | |||
| 1181 | #undef __JPEGDECODER_C__ | 
Powered by WebSVN v2.8.3