Dependencies:   mbed

picojpeg/jpegutil.c

Committer:
XkLi
Date:
2011-10-11
Revision:
0:c546b51ecf0b

File content as of revision 0:c546b51ecf0b:

#include "jpegutil.h"

FILE *jpegfile;
int jpeg_filesize = 0;
int jpeg_filepos = 0;

unsigned char pjpeg_need_bytes_callback(unsigned char* pBuf, unsigned char buf_size, unsigned char *pBytes_actually_read, void *pCallback_data)
{
   unsigned int n = min((unsigned int)(jpeg_filesize - jpeg_filepos), (unsigned int)buf_size);
   if (n && (fread(pBuf, 1, n, jpegfile) != n))
      return PJPG_STREAM_READ_ERROR;
   *pBytes_actually_read = (unsigned char)(n);
   jpeg_filepos += n;
   return 0;
}

void ReadJPEGFromFile(const char *filename, NokiaLCD *lcd)
{
    pjpeg_image_info_t imageInfo;
    jpegfile = fopen(filename,"rb");
    fseek(jpegfile, 0, SEEK_END);
    jpeg_filesize = ftell(jpegfile);
    jpeg_filepos = 0;
    fseek(jpegfile, 0, SEEK_SET);
    int status = pjpeg_decode_init(&imageInfo, pjpeg_need_bytes_callback, NULL);
   //const unsigned int row_pitch = imageInfo.m_width * imageInfo.m_comps;
   int mcu_x = 0;
   int mcu_y = 0;

   for ( ; ; )
   {
      status = pjpeg_decode_mcu();

      if (status)
      {
         if (status != PJPG_NO_MORE_BLOCKS)
         {
            //pc.printf("pjpeg_decode_mcu() failed with status %u\n", status);
            fclose(jpegfile);
            return;
         }

         break;
      }

      if (mcu_y >= imageInfo.m_MCUSPerCol)
      {
         fclose(jpegfile);
         return;
      }
            
      // Copy MCU's pixel blocks into the destination bitmap.

      for (int y = 0; y < imageInfo.m_MCUHeight; y += 8)
      {
         const int by_limit = min(8, imageInfo.m_height - (mcu_y * imageInfo.m_MCUHeight + y));
         for (int x = 0; x < imageInfo.m_MCUWidth; x += 8)
         {

            unsigned int src_ofs = (x * 8U) + (y * 16U);
            const unsigned char *pSrcR = imageInfo.m_pMCUBufR + src_ofs;
            const unsigned char *pSrcG = imageInfo.m_pMCUBufG + src_ofs;
            const unsigned char *pSrcB = imageInfo.m_pMCUBufB + src_ofs;

            const int bx_limit = min(8, imageInfo.m_width - (mcu_x * imageInfo.m_MCUWidth + x));
                        
            if (imageInfo.m_scanType == PJPG_GRAYSCALE)
            {
               for (int by = 0; by < by_limit; by++)
               {
                  for (int bx = 0; bx < bx_limit; bx++)
                  {
                      unsigned int color = ((*pSrcR++) << 16);   
                      (*lcd).pixel(mcu_x*imageInfo.m_MCUWidth+x+bx,mcu_y*imageInfo.m_MCUHeight+y+by,color);
                  }
                  pSrcR += (8 - bx_limit);
               }
            }
            else
            {
               for (int by = 0; by < by_limit; by++)
               {
                  for (int bx = 0; bx < bx_limit; bx++)
                  {
                     unsigned int color = ((*pSrcR++) << 16) | ((*pSrcG++) << 8) | (*pSrcB++);
                     (*lcd).pixel((130-imageInfo.m_width)/2+mcu_x*imageInfo.m_MCUWidth+x+bx,(130-imageInfo.m_height)/2+mcu_y*imageInfo.m_MCUHeight+y+by,color);
                  }

                  pSrcR += (8 - bx_limit);
                  pSrcG += (8 - bx_limit);
                  pSrcB += (8 - bx_limit);

               }
            }
         }
      }

      mcu_x++;
      if (mcu_x == imageInfo.m_MCUSPerRow)
      {
         mcu_x = 0;
         mcu_y++;
      }
   }
      
   fclose(jpegfile);
}