This is a code which generates the various zoomed versions of an image stored in an SD card and displays it on a Nokia LCD based on the keys pressed on a capacitive touch pad.

Dependencies:   FatFileSystem mbed

Fork of Lab3 by Martin Sturm

Revision:
1:6048138606a0
Parent:
0:c546b51ecf0b
--- a/picojpeg/picojpeg.c	Tue Oct 11 01:24:18 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1736 +0,0 @@
-//------------------------------------------------------------------------------
-// picojpeg v1.0 - Public domain, Rich Geldreich <richgel99@gmail.com>
-// Last modified Nov. 27, 2010
-//------------------------------------------------------------------------------
-#include "picojpeg.h"
-//------------------------------------------------------------------------------
-typedef unsigned char   uint8;
-typedef unsigned short  uint16;
-typedef signed char     int8;
-typedef signed short    int16;
-//------------------------------------------------------------------------------
-// Change as needed - the PJPG_MAX_WIDTH/PJPG_MAX_HEIGHT checks are only present
-// to quickly detect bogus files.
-#define PJPG_MAX_WIDTH 16384
-#define PJPG_MAX_HEIGHT 16384
-
-#define PJPG_MAXCOMPSINSCAN 3
-//------------------------------------------------------------------------------
-typedef enum
-{
-   M_SOF0  = 0xC0,
-   M_SOF1  = 0xC1,
-   M_SOF2  = 0xC2,
-   M_SOF3  = 0xC3,
-
-   M_SOF5  = 0xC5,
-   M_SOF6  = 0xC6,
-   M_SOF7  = 0xC7,
-
-   M_JPG   = 0xC8,
-   M_SOF9  = 0xC9,
-   M_SOF10 = 0xCA,
-   M_SOF11 = 0xCB,
-
-   M_SOF13 = 0xCD,
-   M_SOF14 = 0xCE,
-   M_SOF15 = 0xCF,
-
-   M_DHT   = 0xC4,
-
-   M_DAC   = 0xCC,
-
-   M_RST0  = 0xD0,
-   M_RST1  = 0xD1,
-   M_RST2  = 0xD2,
-   M_RST3  = 0xD3,
-   M_RST4  = 0xD4,
-   M_RST5  = 0xD5,
-   M_RST6  = 0xD6,
-   M_RST7  = 0xD7,
-
-   M_SOI   = 0xD8,
-   M_EOI   = 0xD9,
-   M_SOS   = 0xDA,
-   M_DQT   = 0xDB,
-   M_DNL   = 0xDC,
-   M_DRI   = 0xDD,
-   M_DHP   = 0xDE,
-   M_EXP   = 0xDF,
-
-   M_APP0  = 0xE0,
-   M_APP15 = 0xEF,
-
-   M_JPG0  = 0xF0,
-   M_JPG13 = 0xFD,
-   M_COM   = 0xFE,
-
-   M_TEM   = 0x01,
-
-   M_ERROR = 0x100
-} JPEG_MARKER;
-
-#define RST0 0xD0
-//------------------------------------------------------------------------------
-const int8 ZAG[] = 
-{
-   0,  1,  8, 16,  9,  2,  3, 10,
-   17, 24, 32, 25, 18, 11,  4,  5,
-   12, 19, 26, 33, 40, 48, 41, 34,
-   27, 20, 13,  6,  7, 14, 21, 28,
-   35, 42, 49, 56, 57, 50, 43, 36,
-   29, 22, 15, 23, 30, 37, 44, 51,
-   58, 59, 52, 45, 38, 31, 39, 46,
-   53, 60, 61, 54, 47, 55, 62, 63,
-};
-//------------------------------------------------------------------------------
-// 128 bytes
-static int16 gCoeffBuf[8*8];
-
-// 8*8*4 bytes * 3 = 768
-static uint8 gMCUBufR[256];
-static uint8 gMCUBufG[256];
-static uint8 gMCUBufB[256];
-
-// 256 bytes
-static int16 gQuant0[8*8];
-static int16 gQuant1[8*8];
-
-// 6 bytes
-static int16 gLastDC[3];
-
-typedef struct HuffTableT
-{
-   uint16 mMinCode[16];
-   uint16 mMaxCode[16];
-   uint8 mValPtr[16];
-} HuffTable;
-
-// DC - 192
-static HuffTable gHuffTab0;
-
-static uint8 gHuffVal0[16];
-
-static HuffTable gHuffTab1;
-static uint8 gHuffVal1[16];
-
-// AC - 672
-static HuffTable gHuffTab2;
-static uint8 gHuffVal2[256];
-
-static HuffTable gHuffTab3;
-static uint8 gHuffVal3[256];
-
-static uint8 gValidHuffTables;
-static uint8 gValidQuantTables;
-
-static uint8 gTemFlag;
-#define MAX_IN_BUF_SIZE 256
-static uint8 gInBuf[MAX_IN_BUF_SIZE];
-static uint8 gInBufOfs;
-static uint8 gInBufLeft;
-
-static uint16 gBitBuf;
-static uint8 gBitsLeft;
-//------------------------------------------------------------------------------
-static uint16 gImageXSize;
-static uint16 gImageYSize;
-static uint8 gCompsInFrame;
-static uint8 gCompIdent[3];
-static uint8 gCompHSamp[3];
-static uint8 gCompVSamp[3];
-static uint8 gCompQuant[3];
-
-static uint16 gRestartInterval;
-static uint16 gNextRestartNum;
-static uint16 gRestartsLeft;
-
-static uint8 gCompsInScan;
-static uint8 gCompList[3];
-static uint8 gCompDCTab[3]; // 0,1
-static uint8 gCompACTab[3]; // 0,1
-
-static pjpeg_scan_type_t gScanType;
-
-static uint8 gMaxBlocksPerMCU;
-static uint8 gMaxMCUXSize;
-static uint8 gMaxMCUYSize;
-static uint16 gMaxMCUSPerRow;
-static uint16 gMaxMCUSPerCol;
-static uint16 gNumMCUSRemaining;
-static uint8 gMCUOrg[6];
-
-static pjpeg_need_bytes_callback_t g_pNeedBytesCallback;
-static void *g_pCallback_data;
-//------------------------------------------------------------------------------
-static uint8 fillInBuf(void)
-{
-   unsigned char status;
-
-   // Reserve a few bytes at the beginning of the buffer for putting back ("stuffing") chars.
-   gInBufOfs = 4;
-   gInBufLeft = 0;
-
-   status = (*g_pNeedBytesCallback)(gInBuf + gInBufOfs, MAX_IN_BUF_SIZE - gInBufOfs, &gInBufLeft, g_pCallback_data);
-   if (status)
-      return status;
-      
-   return 0;
-}   
-//------------------------------------------------------------------------------
-static uint8 getChar(void)
-{
-   if (!gInBufLeft)
-   {
-      fillInBuf();
-      if (!gInBufLeft)
-      {
-         gTemFlag = ~gTemFlag;
-         return gTemFlag ? 0xFF : 0xD9;
-      } 
-   }
-   
-   gInBufLeft--;
-   return gInBuf[gInBufOfs++];
-}
-//------------------------------------------------------------------------------
-static void stuffChar(uint8 i)
-{
-   gInBufOfs--;
-   gInBuf[gInBufOfs] = i;
-   gInBufLeft++;
-}
-//------------------------------------------------------------------------------
-static uint8 getOctet(uint8 FFCheck)
-{
-   uint8 c = getChar();
-      
-   if ((FFCheck) && (c == 0xFF))
-   {
-      uint8 n = getChar();
-
-      if (n)
-      {
-         stuffChar(n);
-         stuffChar(0xFF);
-      }
-   }
-
-   return c;
-}
-//------------------------------------------------------------------------------
-static uint16 getBits(uint8 numBits, uint8 FFCheck)
-{
-   uint8 origBits = numBits;
-   uint16 ret = gBitBuf;
-   
-   if (numBits > 8)
-   {
-      numBits -= 8;
-      
-      gBitBuf <<= gBitsLeft;
-      
-      gBitBuf |= getOctet(FFCheck);
-      
-      gBitBuf <<= (8 - gBitsLeft);
-      
-      ret = (ret & 0xFF00) | (gBitBuf >> 8);
-   }
-      
-   if (gBitsLeft < numBits)
-   {
-      gBitBuf <<= gBitsLeft;
-      
-      gBitBuf |= getOctet(FFCheck);
-      
-      gBitBuf <<= (numBits - gBitsLeft);
-                        
-      gBitsLeft = 8 - (numBits - gBitsLeft);
-   }
-   else
-   {
-      gBitsLeft = (uint8)(gBitsLeft - numBits);
-      gBitBuf <<= numBits;
-   }
-   
-   return ret >> (16 - origBits);
-}
-//------------------------------------------------------------------------------
-static uint16 getBits1(uint8 numBits)
-{
-   return getBits(numBits, 0);
-}
-//------------------------------------------------------------------------------
-static uint16 getBits2(uint8 numBits)
-{
-   return getBits(numBits, 1);
-}
-//------------------------------------------------------------------------------
-static uint8 getBit(void)
-{
-   uint8 ret = 0;
-   if (gBitBuf & 0x8000) 
-      ret = 1;
-   
-   if (!gBitsLeft)
-   {
-      gBitBuf |= getOctet(1);
-
-      gBitsLeft += 8;
-   }
-   
-   gBitsLeft--;
-   gBitBuf <<= 1;
-   
-   return ret;
-}
-//------------------------------------------------------------------------------
-static uint16 getExtendTest(uint8 i)
-{
-   switch (i)
-   {
-      case 0: return 0;
-      case 1: return 0x0001;
-      case 2: return 0x0002;
-      case 3: return 0x0004;
-      case 4: return 0x0008;
-      case 5: return 0x0010; 
-      case 6: return 0x0020;
-      case 7: return 0x0040;
-      case 8:  return 0x0080;
-      case 9:  return 0x0100;
-      case 10: return 0x0200;
-      case 11: return 0x0400;
-      case 12: return 0x0800;
-      case 13: return 0x1000;
-      case 14: return 0x2000; 
-      case 15: return 0x4000;
-      default: return 0;
-   }      
-}
-//------------------------------------------------------------------------------
-static int16 getExtendOffset(uint8 i)
-{ 
-   switch (i)
-   {
-      case 0: return 0;
-      case 1: return ((-1)<<1) + 1; 
-      case 2: return ((-1)<<2) + 1; 
-      case 3: return ((-1)<<3) + 1; 
-      case 4: return ((-1)<<4) + 1; 
-      case 5: return ((-1)<<5) + 1; 
-      case 6: return ((-1)<<6) + 1; 
-      case 7: return ((-1)<<7) + 1; 
-      case 8: return ((-1)<<8) + 1; 
-      case 9: return ((-1)<<9) + 1;
-      case 10: return ((-1)<<10) + 1; 
-      case 11: return ((-1)<<11) + 1; 
-      case 12: return ((-1)<<12) + 1; 
-      case 13: return ((-1)<<13) + 1; 
-      case 14: return ((-1)<<14) + 1; 
-      case 15: return ((-1)<<15) + 1;
-      default: return 0;
-   }
-};
-//------------------------------------------------------------------------------
-static int16 huffExtend(uint16 x, uint8 s)
-{
-   return ((x < getExtendTest(s)) ? ((int16)x + getExtendOffset(s)) : (int16)x);
-}
-//------------------------------------------------------------------------------
-static uint8 huffDecode(const HuffTable* pHuffTable, const uint8* pHuffVal)
-{
-   uint8 i = 0;
-   uint8 j;
-   uint16 code = getBit();
-
-   for ( ; ; )
-   {
-      uint16 maxCode;
-
-      if (i == 16)
-         return 0;
-
-      maxCode = pHuffTable->mMaxCode[i];
-      if ((code <= maxCode) && (maxCode != 0xFFFF))
-         break;
-
-      i++;
-      code <<= 1;
-      code |= getBit();
-   }
-
-   j = pHuffTable->mValPtr[i];
-   j = (uint8)(j + (code - pHuffTable->mMinCode[i]));
-
-   return pHuffVal[j];
-}
-//------------------------------------------------------------------------------
-static void huffCreate(const uint8* pBits, HuffTable* pHuffTable)
-{
-   uint8 i = 0;
-   uint8 j = 0;
-
-   uint16 code = 0;
-      
-   for ( ; ; )
-   {
-      uint8 num = pBits[i];
-      
-      if (!num)
-      {
-         pHuffTable->mMinCode[i] = 0x0000;
-         pHuffTable->mMaxCode[i] = 0xFFFF;
-         pHuffTable->mValPtr[i] = 0;
-      }
-      else
-      {
-         pHuffTable->mMinCode[i] = code;
-         pHuffTable->mMaxCode[i] = code + num - 1;
-         pHuffTable->mValPtr[i] = j;
-         
-         j = (uint8)(j + num);
-         
-         code = (uint16)(code + num);
-      }
-      
-      code <<= 1;
-      
-      i++;
-      if (i > 15)
-         break;
-   }
-}
-//------------------------------------------------------------------------------
-static HuffTable* getHuffTable(uint8 index)
-{
-   // 0-1 = DC
-   // 2-3 = AC
-   switch (index)
-   {
-      case 0: return &gHuffTab0;
-      case 1: return &gHuffTab1;
-      case 2: return &gHuffTab2;
-      case 3: return &gHuffTab3;
-      default: return 0;
-   }
-}
-//------------------------------------------------------------------------------
-static uint8* getHuffVal(uint8 index)
-{
-   // 0-1 = DC
-   // 2-3 = AC
-   switch (index)
-   {
-      case 0: return gHuffVal0;
-      case 1: return gHuffVal1;
-      case 2: return gHuffVal2;
-      case 3: return gHuffVal3;
-      default: return 0;
-   }
-}
-//------------------------------------------------------------------------------
-static uint16 getMaxHuffCodes(uint8 index)
-{
-   return (index < 2) ? 12 : 255;
-}
-//------------------------------------------------------------------------------
-static uint8 readDHTMarker(void)
-{
-   uint8 bits[16];
-   uint16 left = getBits1(16);
-
-   if (left < 2)
-      return PJPG_BAD_DHT_MARKER;
-
-   left -= 2;
-
-   while (left)
-   {
-      uint8 i, tableIndex, index;
-      uint8* pHuffVal;
-      HuffTable* pHuffTable;
-      uint16 count, totalRead;
-            
-      index = (uint8)getBits1(8);
-      
-      if ( ((index & 0xF) > 1) || ((index & 0xF0) > 0x10) )
-         return PJPG_BAD_DHT_INDEX;
-      
-      tableIndex = ((index >> 3) & 2) + (index & 1);
-      
-      pHuffTable = getHuffTable(tableIndex);
-      pHuffVal = getHuffVal(tableIndex);
-      
-      gValidHuffTables |= (1 << tableIndex);
-            
-      count = 0;
-      for (i = 0; i <= 15; i++)
-      {
-         uint8 n = (uint8)getBits1(8);
-         bits[i] = n;
-         count = (uint16)(count + n);
-      }
-      
-      if (count > getMaxHuffCodes(tableIndex))
-         return PJPG_BAD_DHT_COUNTS;
-
-      for (i = 0; i < count; i++)
-         pHuffVal[i] = (uint8)getBits1(8);
-
-      totalRead = 1 + 16 + count;
-
-      if (left < totalRead)
-         return PJPG_BAD_DHT_MARKER;
-
-      left = (uint16)(left - totalRead);
-
-      huffCreate(bits, pHuffTable);
-   }
-      
-   return 0;
-}
-//------------------------------------------------------------------------------
-static void createWinogradQuant(int16* pQuant);
-
-static uint8 readDQTMarker(void)
-{
-   uint16 left = getBits1(16);
-
-   if (left < 2)
-      return PJPG_BAD_DQT_MARKER;
-
-   left -= 2;
-
-   while (left)
-   {
-      uint8 i;
-      uint8 n = (uint8)getBits1(8);
-      uint8 prec = n >> 4;
-      uint16 totalRead;
-
-      n &= 0x0F;
-
-      if (n > 1)
-         return PJPG_BAD_DQT_TABLE;
-
-      gValidQuantTables |= (n ? 2 : 1);         
-
-      // read quantization entries, in zag order
-      for (i = 0; i < 64; i++)
-      {
-         uint16 temp = getBits1(8);
-
-         if (prec)
-            temp = (temp << 8) + getBits1(8);
-
-         if (n)
-            gQuant1[i] = (int16)temp;            
-         else
-            gQuant0[i] = (int16)temp;            
-      }
-      
-      createWinogradQuant(n ? gQuant1 : gQuant0);
-
-      totalRead = 64 + 1;
-
-      if (prec)
-         totalRead += 64;
-
-      if (left < totalRead)
-         return PJPG_BAD_DQT_LENGTH;
-
-      left = (uint16)(left - totalRead);
-   }
-   
-   return 0;
-}
-//------------------------------------------------------------------------------
-static uint8 readSOFMarker(void)
-{
-   uint8 i;
-   uint16 left = getBits1(16);
-
-   if (getBits1(8) != 8)   
-      return PJPG_BAD_PRECISION;
-
-   gImageYSize = getBits1(16);
-
-   if ((!gImageYSize) || (gImageYSize > PJPG_MAX_HEIGHT))
-      return PJPG_BAD_HEIGHT;
-
-   gImageXSize = getBits1(16);
-
-   if ((!gImageXSize) || (gImageXSize > PJPG_MAX_WIDTH))
-      return PJPG_BAD_WIDTH;
-
-   gCompsInFrame = (uint8)getBits1(8);
-
-   if (gCompsInFrame > 3)
-      return PJPG_TOO_MANY_COMPONENTS;
-
-   if (left != (gCompsInFrame + gCompsInFrame + gCompsInFrame + 8))
-      return PJPG_BAD_SOF_LENGTH;
-   
-   for (i = 0; i < gCompsInFrame; i++)
-   {
-      gCompIdent[i] = (uint8)getBits1(8);
-      gCompHSamp[i] = (uint8)getBits1(4);
-      gCompVSamp[i] = (uint8)getBits1(4);
-      gCompQuant[i] = (uint8)getBits1(8);
-      
-      if (gCompQuant[i] > 1)
-         return PJPG_UNSUPPORTED_QUANT_TABLE;
-   }
-   
-   return 0;
-}
-//------------------------------------------------------------------------------
-// Used to skip unrecognized markers.
-static uint8 skipVariableMarker(void)
-{
-   uint16 left = getBits1(16);
-
-   if (left < 2)
-      return PJPG_BAD_VARIABLE_MARKER;
-
-   left -= 2;
-
-   while (left)
-   {
-      getBits1(8);
-      left--;
-   }
-   
-   return 0;
-}
-//------------------------------------------------------------------------------
-// Read a define restart interval (DRI) marker.
-static uint8 readDRIMarker(void)
-{
-   if (getBits1(16) != 4)
-      return PJPG_BAD_DRI_LENGTH;
-
-   gRestartInterval = getBits1(16);
-   
-   return 0;
-}
-//------------------------------------------------------------------------------
-// Read a start of scan (SOS) marker.
-static uint8 readSOSMarker(void)
-{
-   uint8 i;
-   uint16 left = getBits1(16);
-   uint8 spectral_start, spectral_end, successive_high, successive_low;
-
-   gCompsInScan = (uint8)getBits1(8);
-
-   left -= 3;
-
-   if ( (left != (gCompsInScan + gCompsInScan + 3)) || (gCompsInScan < 1) || (gCompsInScan > PJPG_MAXCOMPSINSCAN) )
-      return PJPG_BAD_SOS_LENGTH;
-   
-   for (i = 0; i < gCompsInScan; i++)
-   {
-      uint8 cc = (uint8)getBits1(8);
-      uint8 c = (uint8)getBits1(8);
-      uint8 ci;
-      
-      left -= 2;
-     
-      for (ci = 0; ci < gCompsInFrame; ci++)
-         if (cc == gCompIdent[ci])
-            break;
-
-      if (ci >= gCompsInFrame)
-         return PJPG_BAD_SOS_COMP_ID;
-
-      gCompList[i]    = ci;
-      gCompDCTab[ci] = (c >> 4) & 15;
-      gCompACTab[ci] = (c & 15);
-   }
-
-   spectral_start  = (uint8)getBits1(8);
-   spectral_end    = (uint8)getBits1(8);
-   successive_high = (uint8)getBits1(4);
-   successive_low  = (uint8)getBits1(4);
-
-   left -= 3;
-
-   while (left)                  
-   {
-      getBits1(8);
-      left--;
-   }
-   
-   return 0;
-}
-//------------------------------------------------------------------------------
-static uint8 nextMarker(void)
-{
-   uint8 c;
-   uint8 bytes = 0;
-
-   do
-   {
-      do
-      {
-         bytes++;
-
-         c = (uint8)getBits1(8);
-
-      } while (c != 0xFF);
-
-      do
-      {
-         c = (uint8)getBits1(8);
-
-      } while (c == 0xFF);
-
-   } while (c == 0);
-
-   // If bytes > 0 here, there where extra bytes before the marker (not good).
-
-   return c;
-}
-//------------------------------------------------------------------------------
-// Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is
-// encountered.
-static uint8 processMarkers(uint8* pMarker)
-{
-   for ( ; ; )
-   {
-      uint8 c = nextMarker();
-
-      switch (c)
-      {
-         case M_SOF0:
-         case M_SOF1:
-         case M_SOF2:
-         case M_SOF3:
-         case M_SOF5:
-         case M_SOF6:
-         case M_SOF7:
-         //      case M_JPG:
-         case M_SOF9:
-         case M_SOF10:
-         case M_SOF11:
-         case M_SOF13:
-         case M_SOF14:
-         case M_SOF15:
-         case M_SOI:
-         case M_EOI:
-         case M_SOS:
-         {
-            *pMarker = c;
-            return 0;
-         }
-         case M_DHT:
-         {
-            readDHTMarker();
-            break;
-         }
-         // Sorry, no arithmitic support at this time. Dumb patents!
-         case M_DAC:
-         {
-            return PJPG_NO_ARITHMITIC_SUPPORT;
-         }
-         case M_DQT:
-         {
-            readDQTMarker();
-            break;
-         }
-         case M_DRI:
-         {
-            readDRIMarker();
-            break;
-         }
-         //case M_APP0:  /* no need to read the JFIF marker */
-
-         case M_JPG:
-         case M_RST0:    /* no parameters */
-         case M_RST1:
-         case M_RST2:
-         case M_RST3:
-         case M_RST4:
-         case M_RST5:
-         case M_RST6:
-         case M_RST7:
-         case M_TEM:
-         {
-            return PJPG_UNEXPECTED_MARKER;
-         }
-         default:    /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */
-         {
-            skipVariableMarker();
-            break;
-         }
-      }
-   }
-//   return 0;
-}
-//------------------------------------------------------------------------------
-// Finds the start of image (SOI) marker.
-static uint8 locateSOIMarker(void)
-{
-   uint16 bytesleft;
-   
-   uint8 lastchar = (uint8)getBits1(8);
-
-   uint8 thischar = (uint8)getBits1(8);
-
-   /* ok if it's a normal JPEG file without a special header */
-
-   if ((lastchar == 0xFF) && (thischar == M_SOI))
-      return 0;
-
-   bytesleft = 4096; //512;
-
-   for ( ; ; )
-   {
-      if (--bytesleft == 0)
-         return PJPG_NOT_JPEG;
-
-      lastchar = thischar;
-
-      thischar = (uint8)getBits1(8);
-
-      if (lastchar == 0xFF) 
-      {
-         if (thischar == M_SOI)
-            break;
-         else if (thischar == M_EOI)    //getBits1 will keep returning M_EOI if we read past the end
-            return PJPG_NOT_JPEG;
-      }
-   }
-
-   /* Check the next character after marker: if it's not 0xFF, it can't
-   be the start of the next marker, so the file is bad */
-
-   thischar = (uint8)((gBitBuf >> 8) & 0xFF);
-
-   if (thischar != 0xFF)
-      return PJPG_NOT_JPEG;
-      
-   return 0;
-}
-//------------------------------------------------------------------------------
-// Find a start of frame (SOF) marker.
-static uint8 locateSOFMarker(void)
-{
-   uint8 c;
-
-   uint8 status = locateSOIMarker();
-   if (status)
-      return status;
-   
-   status = processMarkers(&c);
-   if (status)
-      return status;
-
-   switch (c)
-   {
-      case M_SOF2:
-      {
-         return PJPG_UNSUPPORTED_MODE;
-      }
-      case M_SOF0:  /* baseline DCT */
-      {
-         status = readSOFMarker();
-         if (status)
-            return status;
-            
-         break;
-      }
-      case M_SOF9:  
-      {
-         return PJPG_NO_ARITHMITIC_SUPPORT;
-      }
-      case M_SOF1:  /* extended sequential DCT */
-      default:
-      {
-         return PJPG_UNSUPPORTED_MARKER;
-      }
-   }
-   
-   return 0;
-}
-//------------------------------------------------------------------------------
-// Find a start of scan (SOS) marker.
-static uint8 locateSOSMarker(uint8* pFoundEOI)
-{
-   uint8 c;
-   uint8 status;
-
-   *pFoundEOI = 0;
-      
-   status = processMarkers(&c);
-   if (status)
-      return status;
-
-   if (c == M_EOI)
-   {
-      *pFoundEOI = 1;
-      return 0;
-   }
-   else if (c != M_SOS)
-      return PJPG_UNEXPECTED_MARKER;
-
-   return readSOSMarker();
-}
-//------------------------------------------------------------------------------
-static uint8 init(void)
-{
-   gImageXSize = 0;
-   gImageYSize = 0;
-   gCompsInFrame = 0;
-   gRestartInterval = 0;
-   gCompsInScan = 0;
-   gValidHuffTables = 0;
-   gValidQuantTables = 0;
-   gTemFlag = 0;
-   gInBufOfs = 0;
-   gInBufLeft = 0;
-   gBitBuf = 0;
-   gBitsLeft = 8;
-
-   getBits1(8);
-   getBits1(8);
-
-   return 0;
-}
-//------------------------------------------------------------------------------
-// This method throws back into the stream any bytes that where read
-// into the bit buffer during initial marker scanning.
-static void fixInBuffer(void)
-{
-   /* In case any 0xFF's where pulled into the buffer during marker scanning */
-
-   if (gBitsLeft > 0)  
-      stuffChar((uint8)gBitBuf);
-   
-   stuffChar((uint8)(gBitBuf >> 8));
-   
-   gBitsLeft = 8;
-   getBits2(8);
-   getBits2(8);
-}
-//------------------------------------------------------------------------------
-// Restart interval processing.
-static uint8 processRestart(void)
-{
-   // Let's scan a little bit to find the marker, but not _too_ far.
-   // 1536 is a "fudge factor" that determines how much to scan.
-   uint16 i;
-   uint8 c = 0;
-
-   for (i = 1536; i > 0; i--)
-      if (getChar() == 0xFF)
-         break;
-
-   if (i == 0)
-      return PJPG_BAD_RESTART_MARKER;
-   
-   for ( ; i > 0; i--)
-      if ((c = getChar()) != 0xFF)
-         break;
-
-   if (i == 0)
-      return PJPG_BAD_RESTART_MARKER;
-
-   // Is it the expected marker? If not, something bad happened.
-   if (c != (gNextRestartNum + M_RST0))
-      return PJPG_BAD_RESTART_MARKER;
-
-   // Reset each component's DC prediction values.
-   gLastDC[0] = 0;
-   gLastDC[1] = 0;
-   gLastDC[2] = 0;
-
-   gRestartsLeft = gRestartInterval;
-
-   gNextRestartNum = (gNextRestartNum + 1) & 7;
-
-   // Get the bit buffer going again...
-
-   gBitsLeft = 8;
-   getBits2(8);
-   getBits2(8);
-   
-   return 0;
-}
-//------------------------------------------------------------------------------
-static uint8 findEOI(void)
-{
-   uint8 c;
-   uint8 status;
-
-   // Prime the bit buffer
-   gBitsLeft = 8;
-   getBits1(8);
-   getBits1(8);
-
-   // The next marker _should_ be EOI
-   status = processMarkers(&c);
-   if (status)
-      return status;
-   
-   //gTotalBytesRead -= in_buf_left;
-   if (c != M_EOI)
-      return PJPG_UNEXPECTED_MARKER;
-   
-   return 0;
-}
-//------------------------------------------------------------------------------
-static uint8 checkHuffTables(void)
-{
-   uint8 i;
-
-   for (i = 0; i < gCompsInScan; i++)
-   {
-      uint8 compDCTab = gCompDCTab[gCompList[i]];
-      uint8 compACTab = gCompACTab[gCompList[i]] + 2;
-      
-      if ( ((gValidHuffTables & (1 << compDCTab)) == 0) ||
-           ((gValidHuffTables & (1 << compACTab)) == 0) )
-         return PJPG_UNDEFINED_HUFF_TABLE;           
-   }
-   
-   return 0;
-}
-//------------------------------------------------------------------------------
-static uint8 checkQuantTables(void)
-{
-   uint8 i;
-
-   for (i = 0; i < gCompsInScan; i++)
-   {
-      uint8 compQuantMask = gCompQuant[gCompList[i]] ? 2 : 1;
-      
-      if ((gValidQuantTables & compQuantMask) == 0)
-         return PJPG_UNDEFINED_QUANT_TABLE;
-   }         
-
-   return 0;         
-}
-//------------------------------------------------------------------------------
-static uint8 initScan(void)
-{
-   uint8 foundEOI;
-   uint8 status = locateSOSMarker(&foundEOI);
-   if (status)
-      return status;
-   if (foundEOI)
-      return PJPG_UNEXPECTED_MARKER;
-   
-   status = checkHuffTables();
-   if (status)
-      return status;
-
-   status = checkQuantTables();
-   if (status)
-      return status;
-
-   gLastDC[0] = 0;
-   gLastDC[1] = 0;
-   gLastDC[2] = 0;
-
-   if (gRestartInterval)
-   {
-      gRestartsLeft = gRestartInterval;
-      gNextRestartNum = 0;
-   }
-
-   fixInBuffer();
-
-   return 0;
-}
-//------------------------------------------------------------------------------
-static uint8 initFrame(void)
-{
-   if (gCompsInFrame == 1)
-   {
-      if ((gCompHSamp[0] != 1) || (gCompVSamp[0] != 1))
-         return PJPG_UNSUPPORTED_SAMP_FACTORS;
-
-      gScanType = PJPG_GRAYSCALE;
-
-      gMaxBlocksPerMCU = 1;
-      gMCUOrg[0] = 0;
-
-      gMaxMCUXSize     = 8;
-      gMaxMCUYSize     = 8;
-   }
-   else if (gCompsInFrame == 3)
-   {
-      if ( ((gCompHSamp[1] != 1) || (gCompVSamp[1] != 1)) ||
-         ((gCompHSamp[2] != 1) || (gCompVSamp[2] != 1)) )
-         return PJPG_UNSUPPORTED_SAMP_FACTORS;
-
-      if ((gCompHSamp[0] == 1) && (gCompVSamp[0] == 1))
-      {
-         gScanType = PJPG_YH1V1;
-
-         gMaxBlocksPerMCU = 3;
-         gMCUOrg[0] = 0;
-         gMCUOrg[1] = 1;
-         gMCUOrg[2] = 2;
-                  
-         gMaxMCUXSize = 8;
-         gMaxMCUYSize = 8;
-      }
-      else if ((gCompHSamp[0] == 2) && (gCompVSamp[0] == 2))
-      {
-         gScanType = PJPG_YH2V2;
-
-         gMaxBlocksPerMCU = 6;
-         gMCUOrg[0] = 0;
-         gMCUOrg[1] = 0;
-         gMCUOrg[2] = 0;
-         gMCUOrg[3] = 0;
-         gMCUOrg[4] = 1;
-         gMCUOrg[5] = 2;
-
-         gMaxMCUXSize = 16;
-         gMaxMCUYSize = 16;
-      }
-      else
-         return PJPG_UNSUPPORTED_SAMP_FACTORS;
-   }
-   else
-      return PJPG_UNSUPPORTED_COLORSPACE;
-
-   gMaxMCUSPerRow = (gImageXSize + (gMaxMCUXSize - 1)) >> ((gMaxMCUXSize == 8) ? 3 : 4);
-   gMaxMCUSPerCol = (gImageYSize + (gMaxMCUYSize - 1)) >> ((gMaxMCUYSize == 8) ? 3 : 4);
-   
-   gNumMCUSRemaining = gMaxMCUSPerRow * gMaxMCUSPerCol;
-   
-   return 0;
-}
-/*----------------------------------------------------------------------------*/
-#define DCT_SCALE_BITS   7
-
-#define DCT_SCALE       (1U << DCT_SCALE_BITS)
-
-#define DESCALE(x)   (((x) + (1U << (DCT_SCALE_BITS - 1))) >> DCT_SCALE_BITS)
-
-#define WFIX(x) ((x) * DCT_SCALE + 0.5f)
-
-#define WINOGRAD_QUANT_SCALE_BITS 10
-
-const uint8 gWinogradQuant[] = 
-{
-   128,  178,  178,  167,  246,  167,  151,  232,
-   232,  151,  128,  209,  219,  209,  128,  101,
-   178,  197,  197,  178,  101,   69,  139,  167,
-   177,  167,  139,   69,   35,   96,  131,  151,
-   151,  131,   96,   35,   49,   91,  118,  128,
-   118,   91,   49,   46,   81,  101,  101,   81,
-   46,   42,   69,   79,   69,   42,   35,   54,
-   54,   35,   28,   37,   28,   19,   19,   10,
-};   
-
-static void createWinogradQuant(int16* pQuant)
-{
-   uint8 i;
-   
-   for (i = 0; i < 64; i++) 
-   {
-      long x = pQuant[i];
-      x *= gWinogradQuant[i];
-      pQuant[i] = (int16)((x + (1 << (WINOGRAD_QUANT_SCALE_BITS - DCT_SCALE_BITS - 1))) >> (WINOGRAD_QUANT_SCALE_BITS - DCT_SCALE_BITS));
-   }
-}
-
-// 1/cos(4*pi/16)
-// 362, 256+106
-#define b1 362
-
-// 1/cos(6*pi/16)
-// 669, 256+256+157
-#define b2 669
-
-// 1/cos(4*pi/16)
-// 362, 256+106
-#define b3 362
-
-// 1/cos(2*pi/16)
-// 277, 256+21
-#define b4 277
-
-// 1/(cos(2*pi/16) + cos(6*pi/16))
-// 196, 196
-#define b5 196
-
-static int16 imul_b1_b3(int16 w)
-{
-   long x = (w * 362L);
-   x += 128L;
-   return (int16)(x >> 8);
-}
-
-static int16 imul_b2(int16 w)
-{
-   long x = (w * 669L);
-   x += 128L;
-   return (int16)(x >> 8);
-}
-
-static int16 imul_b4(int16 w)
-{
-   long x = (w * 277L);
-   x += 128L;
-   return (int16)(x >> 8);
-}
-
-static int16 imul_b5(int16 w)
-{
-   long x = (w * 196L);
-   x += 128L;
-   return (int16)(x >> 8);
-}
-
-static uint8 clamp(int16 s)
-{
-   if ((uint16)s > 255U)
-   {
-      if (s < 0) 
-         return 0; 
-      else if (s > 255) 
-         return 255;
-   }
-      
-   return (uint8)s;
-}
-
-static void idctRows(void)
-{
-   uint8 i;
-   int16* pSrc = gCoeffBuf;
-         
-   for (i = 0; i < 8; i++)
-   {
-      int16 src4 = *(pSrc+5);
-      int16 src7 = *(pSrc+3);
-      int16 x4  = src4 - src7;
-      int16 x7  = src4 + src7;
-
-      int16 src5 = *(pSrc+1);
-      int16 src6 = *(pSrc+7);
-      int16 x5  = src5 + src6;
-      int16 x6  = src5 - src6;
-
-      int16 tmp1 = imul_b5(x4 - x6);
-      int16 stg26 = imul_b4(x6) - tmp1;
-
-      int16 x24 = tmp1 - imul_b2(x4);
-
-      int16 x15 = x5 - x7;
-      int16 x17 = x5 + x7;
-
-      int16 tmp2 = stg26 - x17;
-      int16 tmp3 = imul_b1_b3(x15) - tmp2;
-      int16 x44 = tmp3 + x24;
-
-      int16 src0 = *(pSrc+0);
-      int16 src1 = *(pSrc+4);
-      int16 x30 = src0 + src1;
-      int16 x31 = src0 - src1;
-
-      int16 src2 = *(pSrc+2);
-      int16 src3 = *(pSrc+6);
-      int16 x12 = src2 - src3;
-      int16 x13 = src2 + src3;
-
-      int16 x32 = imul_b1_b3(x12) - x13;
-
-      int16 x40 = x30 + x13;
-      int16 x43 = x30 - x13;
-      int16 x41 = x31 + x32;
-      int16 x42 = x31 - x32;
-
-      *(pSrc+0) = x40 + x17;
-      *(pSrc+1) = x41 + tmp2;
-      *(pSrc+2) = x42 + tmp3;
-      *(pSrc+3) = x43 - x44;
-      *(pSrc+4) = x43 + x44;
-      *(pSrc+5) = x42 - tmp3;
-      *(pSrc+6) = x41 - tmp2;
-      *(pSrc+7) = x40 - x17;
-                  
-      pSrc += 8;
-   }      
-}
-
-static void idctCols(void)
-{
-   uint8 i;
-      
-   int16* pSrc = gCoeffBuf;
-   
-   for (i = 0; i < 8; i++)
-   {
-      int16 src4 = *(pSrc+5*8);
-      int16 src7 = *(pSrc+3*8);
-      int16 x4  = src4 - src7;
-      int16 x7  = src4 + src7;
-
-      int16 src5 = *(pSrc+1*8);
-      int16 src6 = *(pSrc+7*8);
-      int16 x5  = src5 + src6;
-      int16 x6  = src5 - src6;
-
-      int16 tmp1 = imul_b5(x4 - x6);
-      int16 stg26 = imul_b4(x6) - tmp1;
-
-      int16 x24 = tmp1 - imul_b2(x4);
-
-      int16 x15 = x5 - x7;
-      int16 x17 = x5 + x7;
-
-      int16 tmp2 = stg26 - x17;
-      int16 tmp3 = imul_b1_b3(x15) - tmp2;
-      int16 x44 = tmp3 + x24;
-
-      int16 src0 = *(pSrc+0*8);
-      int16 src1 = *(pSrc+4*8);
-      int16 x30 = src0 + src1;
-      int16 x31 = src0 - src1;
-
-      int16 src2 = *(pSrc+2*8);
-      int16 src3 = *(pSrc+6*8);
-      int16 x12 = src2 - src3;
-      int16 x13 = src2 + src3;
-
-      int16 x32 = imul_b1_b3(x12) - x13;
-
-      int16 x40 = x30 + x13;
-      int16 x43 = x30 - x13;
-      int16 x41 = x31 + x32;
-      int16 x42 = x31 - x32;
-
-      *(pSrc+0*8) = clamp(DESCALE(x40 + x17)  + 128);
-      *(pSrc+1*8) = clamp(DESCALE(x41 + tmp2) + 128);
-      *(pSrc+2*8) = clamp(DESCALE(x42 + tmp3) + 128);
-      *(pSrc+3*8) = clamp(DESCALE(x43 - x44)  + 128);
-      *(pSrc+4*8) = clamp(DESCALE(x43 + x44)  + 128);
-      *(pSrc+5*8) = clamp(DESCALE(x42 - tmp3) + 128);
-      *(pSrc+6*8) = clamp(DESCALE(x41 - tmp2) + 128);
-      *(pSrc+7*8) = clamp(DESCALE(x40 - x17)  + 128);
-
-      pSrc++;      
-   }      
-}
-
-/*----------------------------------------------------------------------------*/
-static uint8 addAndClamp(uint8 a, int16 b)
-{
-   b = a + b;
-   
-   if ((uint16)b > 255U)
-   {
-      if (b < 0)
-         return 0;
-      else if (b > 255)
-         return 255;
-   }
-      
-   return (uint8)b;
-}
-/*----------------------------------------------------------------------------*/
-static uint8 subAndClamp(uint8 a, int16 b)
-{
-   b = a - b;
-
-   if ((uint16)b > 255U)
-   {
-      if (b < 0)
-         return 0;
-      else if (b > 255)
-         return 255;
-   }
-
-   return (uint8)b;
-}
-/*----------------------------------------------------------------------------*/
-// 103/256
-//R = Y + 1.402 (Cr-128)
-
-// 88/256, 183/256
-//G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
-
-// 198/256
-//B = Y + 1.772 (Cb-128)
-/*----------------------------------------------------------------------------*/
-static void upsampleCb(uint8 srcOfs, uint8 dstOfs)
-{
-   // Cb - affects G and B
-   uint8 x, y;
-   int16* pSrc = gCoeffBuf + srcOfs;
-   uint8* pDstG = gMCUBufG + dstOfs;
-   uint8* pDstB = gMCUBufB + dstOfs;
-   for (y = 0; y < 4; y++)
-   {
-      for (x = 0; x < 4; x++)
-      {
-         uint8 cb = (uint8)*pSrc++;
-         int16 cbG, cbB;
-
-         cbG = ((cb * 88U) >> 8U) - 44U;
-         pDstG[0] = subAndClamp(pDstG[0], cbG);
-         pDstG[1] = subAndClamp(pDstG[1], cbG);
-         pDstG[8] = subAndClamp(pDstG[8], cbG);
-         pDstG[9] = subAndClamp(pDstG[9], cbG);
-
-         cbB = (cb + ((cb * 198U) >> 8U)) - 227U;
-         pDstB[0] = addAndClamp(pDstB[0], cbB);
-         pDstB[1] = addAndClamp(pDstB[1], cbB);
-         pDstB[8] = addAndClamp(pDstB[8], cbB);
-         pDstB[9] = addAndClamp(pDstB[9], cbB);
-
-         pDstG += 2;
-         pDstB += 2;
-      }
-
-      pSrc = pSrc - 4 + 8;
-      pDstG = pDstG - 8 + 16;
-      pDstB = pDstB - 8 + 16;
-   }
-}   
-/*----------------------------------------------------------------------------*/
-// 103/256
-//R = Y + 1.402 (Cr-128)
-
-// 88/256, 183/256
-//G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
-
-// 198/256
-//B = Y + 1.772 (Cb-128)
-/*----------------------------------------------------------------------------*/
-static void upsampleCr(uint8 srcOfs, uint8 dstOfs)
-{
-   // Cr - affects R and G
-   uint8 x, y;
-   int16* pSrc = gCoeffBuf + srcOfs;
-   uint8* pDstR = gMCUBufR + dstOfs;
-   uint8* pDstG = gMCUBufG + dstOfs;
-   for (y = 0; y < 4; y++)
-   {
-      for (x = 0; x < 4; x++)
-      {
-         uint8 cr = (uint8)*pSrc++;
-         int16 crR, crG;
-
-         crR = (cr + ((cr * 103U) >> 8U)) - 179;
-         pDstR[0] = addAndClamp(pDstR[0], crR);
-         pDstR[1] = addAndClamp(pDstR[1], crR);
-         pDstR[8] = addAndClamp(pDstR[8], crR);
-         pDstR[9] = addAndClamp(pDstR[9], crR);
-         
-         crG = ((cr * 183U) >> 8U) - 91;
-         pDstG[0] = subAndClamp(pDstG[0], crG);
-         pDstG[1] = subAndClamp(pDstG[1], crG);
-         pDstG[8] = subAndClamp(pDstG[8], crG);
-         pDstG[9] = subAndClamp(pDstG[9], crG);
-         
-         pDstR += 2;
-         pDstG += 2;
-      }
-
-      pSrc = pSrc - 4 + 8;
-      pDstR = pDstR - 8 + 16;
-      pDstG = pDstG - 8 + 16;
-   }
-}   
-/*----------------------------------------------------------------------------*/
-static void copyY(uint8 dstOfs)
-{
-   uint8 i;
-   uint8* pRDst = gMCUBufR + dstOfs;
-   uint8* pGDst = gMCUBufG + dstOfs;
-   uint8* pBDst = gMCUBufB + dstOfs;
-   int16* pSrc = gCoeffBuf;
-   
-   for (i = 64; i > 0; i--)
-   {
-      uint8 c = (uint8)*pSrc++;
-      
-      *pRDst++ = c;
-      *pGDst++ = c;
-      *pBDst++ = c;
-   }
-}
-/*----------------------------------------------------------------------------*/
-static void convertCb(uint8 dstOfs)
-{
-   uint8 i;
-   uint8* pDstG = gMCUBufG + dstOfs;
-   uint8* pDstB = gMCUBufB + dstOfs;
-   int16* pSrc = gCoeffBuf;
-
-   for (i = 64; i > 0; i--)
-   {
-      uint8 cb = (uint8)*pSrc++;
-      int16 cbG, cbB;
-
-      cbG = ((cb * 88U) >> 8U) - 44U;
-      *pDstG++ = subAndClamp(pDstG[0], cbG);
-
-      cbB = (cb + ((cb * 198U) >> 8U)) - 227U;
-      *pDstB++ = addAndClamp(pDstB[0], cbB);
-   }
-}
-/*----------------------------------------------------------------------------*/
-static void convertCr(uint8 dstOfs)
-{
-   uint8 i;
-   uint8* pDstR = gMCUBufR + dstOfs;
-   uint8* pDstG = gMCUBufG + dstOfs;
-   int16* pSrc = gCoeffBuf;
-
-   for (i = 64; i > 0; i--)
-   {
-      uint8 cr = (uint8)*pSrc++;
-      int16 crR, crG;
-
-      crR = (cr + ((cr * 103U) >> 8U)) - 179;
-      *pDstR++ = addAndClamp(pDstR[0], crR);
-
-      crG = ((cr * 183U) >> 8U) - 91;
-      *pDstG++ = subAndClamp(pDstG[0], crG);
-   }
-}
-/*----------------------------------------------------------------------------*/
-static void transformBlock(uint8 mcuBlock)
-{
-   idctRows();
-   idctCols();
-   
-   switch (gScanType)
-   {
-      case PJPG_GRAYSCALE:
-      {
-         copyY(0);
-         break;
-      }
-      case PJPG_YH1V1:
-      {
-         switch (mcuBlock)
-         {
-            case 0:
-            {
-               copyY(0);
-               break;
-            }
-            case 1:
-            {
-               convertCb(0);
-               break;
-            }
-            case 2:
-            {
-               convertCr(0);
-               break;
-            }
-         }
-
-         break;
-      }
-      case PJPG_YH2V2:
-      {
-         switch (mcuBlock)
-         {
-            case 0:
-            {
-               copyY(0);
-               break;
-            }
-            case 1:
-            {
-               copyY(64);
-               break;
-            }
-            case 2:
-            {
-               copyY(128);
-               break;
-            }
-            case 3:
-            {
-               copyY(192);
-               break;
-            }
-            case 4:
-            {
-               upsampleCb(0, 0);
-               upsampleCb(4, 64);
-               upsampleCb(4*8, 128);
-               upsampleCb(4+4*8, 192);
-               break;
-            }
-            case 5:
-            {
-               upsampleCr(0, 0);
-               upsampleCr(4, 64);
-               upsampleCr(4*8, 128);
-               upsampleCr(4+4*8, 192);
-               break;
-            }
-         }
-      }         
-   }      
-}
-//------------------------------------------------------------------------------
-static uint8 decodeNextMCU(void)
-{
-   uint8 status;
-   uint8 mcuBlock;   
-
-   if (gRestartInterval) 
-   {
-      if (gRestartsLeft == 0)
-      {
-         status = processRestart();
-         if (status)
-            return status;
-      }
-      gRestartsLeft--;
-   }      
-   
-   for (mcuBlock = 0; mcuBlock < gMaxBlocksPerMCU; mcuBlock++)
-   {
-      uint8 componentID = gMCUOrg[mcuBlock];
-      uint8 compQuant = gCompQuant[componentID];    
-      uint8 compDCTab = gCompDCTab[componentID];
-      uint8 numExtraBits, compACTab, k;
-      const int16* pQ = compQuant ? gQuant1 : gQuant0;
-      uint16 r, dc;
-
-      uint8 s = huffDecode(compDCTab ? &gHuffTab1 : &gHuffTab0, compDCTab ? gHuffVal1 : gHuffVal0);
-      
-      r = 0;
-      numExtraBits = s & 0xF;
-      if (numExtraBits)
-         r = getBits2(numExtraBits);
-      dc = huffExtend(r, s);
-            
-      dc = dc + gLastDC[componentID];
-      gLastDC[componentID] = dc;
-            
-      gCoeffBuf[0] = dc * pQ[0];
-
-      compACTab = gCompACTab[componentID];
-                        
-      for (k = 1; k < 64; k++)
-      {
-         uint16 extraBits;
-
-         s = huffDecode(compACTab ? &gHuffTab3 : &gHuffTab2, compACTab ? gHuffVal3 : gHuffVal2);
-
-         extraBits = 0;
-         numExtraBits = s & 0xF;
-         if (numExtraBits)
-            extraBits = getBits2(numExtraBits);
-
-         r = s >> 4;
-         s &= 15;
-
-         if (s)
-         {
-            int16 ac;
-
-            if (r)
-            {
-               if ((k + r) > 63)
-                  return PJPG_DECODE_ERROR;
-
-               while (r)
-               {
-                  gCoeffBuf[ZAG[k++]] = 0;
-                  r--;
-               }
-            }
-
-            ac = huffExtend(extraBits, s);
-            
-            gCoeffBuf[ZAG[k]] = ac * pQ[k]; 
-         }
-         else
-         {
-            if (r == 15)
-            {
-               if ((k + 16) > 64)
-                  return PJPG_DECODE_ERROR;
-               
-               for (r = 16; r > 0; r--)
-                  gCoeffBuf[ZAG[k++]] = 0;
-               
-               k--; // - 1 because the loop counter is k
-            }
-            else
-               break;
-         }
-      }
-      
-      while (k < 64)
-         gCoeffBuf[ZAG[k++]] = 0;
-
-      transformBlock(mcuBlock); 
-   }
-         
-   return 0;
-}
-//------------------------------------------------------------------------------
-unsigned char pjpeg_decode_mcu(void)
-{
-   uint8 status;
-
-   if (!gNumMCUSRemaining)
-      return PJPG_NO_MORE_BLOCKS;
-      
-   status = decodeNextMCU();
-   if (status)
-      return status;
-      
-   gNumMCUSRemaining--;
-   
-   return 0;
-}
-//------------------------------------------------------------------------------
-unsigned char pjpeg_decode_init(pjpeg_image_info_t *pInfo, pjpeg_need_bytes_callback_t pNeed_bytes_callback, void *pCallback_data)
-{
-   uint8 status;
-
-   g_pNeedBytesCallback = pNeed_bytes_callback;
-   g_pCallback_data = pCallback_data;
-    
-   status = init();
-   if (status)
-      return status;
-      
-   status = locateSOFMarker();
-   if (status)
-      return status;
-
-   status = initFrame();
-   if (status)
-      return status;
-
-   status = initScan();
-   if (status)
-      return status;
-
-   pInfo->m_width = gImageXSize;
-   pInfo->m_height = gImageYSize;
-   pInfo->m_comps = gCompsInFrame;
-   pInfo->m_scanType = gScanType;
-   pInfo->m_MCUSPerRow = gMaxMCUSPerRow;
-   pInfo->m_MCUSPerCol = gMaxMCUSPerCol;
-   pInfo->m_MCUWidth = gMaxMCUXSize;
-   pInfo->m_MCUHeight = gMaxMCUYSize;
-   pInfo->m_pMCUBufR = gMCUBufR;
-   pInfo->m_pMCUBufG = gMCUBufG;
-   pInfo->m_pMCUBufB = gMCUBufB;
-      
-   return 0;
-}