fadi ladhari
/
GPS_System_with_Google_Maps
hello_world
Fork of GPS_System_with_Google_Maps by
Revision 6:8cc48b05d20e, committed 2017-01-04
- Comitter:
- fadi_lad
- Date:
- Wed Jan 04 15:52:24 2017 +0000
- Parent:
- 5:c4c66c630011
- Commit message:
- gpsSerial
Changed in this revision
diff -r c4c66c630011 -r 8cc48b05d20e DebounceIn.lib --- a/DebounceIn.lib Fri Dec 14 15:40:21 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/AjK/code/DebounceIn/#91a2e988ba9d
diff -r c4c66c630011 -r 8cc48b05d20e GPS.cpp --- a/GPS.cpp Fri Dec 14 15:40:21 2012 +0000 +++ b/GPS.cpp Wed Jan 04 15:52:24 2017 +0000 @@ -22,8 +22,9 @@ #include "GPS.h" + GPS::GPS(PinName tx, PinName rx) : _gps(tx, rx) { - _gps.baud(4800); + _gps.baud(9600); longitude = 0.0; latitude = 0.0; } @@ -35,8 +36,9 @@ //return 1; //testing by Jigar while (1) { + // pc.printf("\n\rentered the GPS.sample while loop\n\r"); getline(); - //printf("\n\rentered the GPS.sample while loop \n\r %s\n\r", msg); + // pc.printf("\n\rentered the GPS.sample while loop \n\r %s\n\r", msg); // Check if it is a GPGGA msg (matches both locked and non-locked msg) @@ -79,7 +81,7 @@ float degrees = trunc(latitude / 100.0f); float minutes = latitude - (degrees * 100.0f); latitude = degrees + minutes / 60.0f; - degrees = trunc(longitude / 100.0f ); //degrees = trunc(longitude / 100.0f * 0.01f); + degrees = trunc(longitude / 100.0f ); //degrees = trunc(longitude / 100.0f * 0.01f); minutes = longitude - (degrees * 100.0f); longitude = degrees + minutes / 60.0f; return 1; @@ -100,9 +102,10 @@ } void GPS::getline() { - + + //pc.printf("entered the getline loop\n\r"); while (_gps.getc() != '$'); // wait for the start of a line - // printf("entered the getline loop\n\r"); + // pc.printf("entered the getline loop\n\r"); for (int i=0; i<256; i++) { msg[i] = _gps.getc(); if (msg[i] == '\r') {
diff -r c4c66c630011 -r 8cc48b05d20e NokiaLCD.lib --- a/NokiaLCD.lib Fri Dec 14 15:40:21 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/Ifrah/code/NokiaLCD/#d829f93abd27
diff -r c4c66c630011 -r 8cc48b05d20e WiflyInterface.lib --- a/WiflyInterface.lib Fri Dec 14 15:40:21 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/WiflyInterface/#8e54830d0df7
diff -r c4c66c630011 -r 8cc48b05d20e main.cpp --- a/main.cpp Fri Dec 14 15:40:21 2012 +0000 +++ b/main.cpp Wed Jan 04 15:52:24 2017 +0000 @@ -1,224 +1,22 @@ #include "mbed.h" -#include "WiflyInterface.h" -#include "NokiaLCD.h" -#include "picojpeg.h" -#include "DebounceIn.h" #include "GPS.h" -#include <vector> - -#define DEFAULTZOOM 15 - -/* wifly interface: -* - p13 and p14 are for the serial communication -* - p28 is for the reset pin -* - p27 is for the connection status -* - 5th field is the ssid of the network -* - 6th field is the password -* - WPA is the security -*/ - -WiflyInterface wifly(p13, p14, p28, p27, "username", "password", WPA); -Serial pc(USBTX,USBRX); -LocalFileSystem local("local");// Create the local filesystem under the name "local" -GPS gps(p9, p10); -DebounceIn ZoomIn(p18); -DebounceIn Refresh(p19); -DebounceIn ZoomOut(p20); -FILE *jpegfile; -int jpeg_filesize = 0; -int jpeg_filepos = 0; -NokiaLCD lcd(p5, p7, p8, p11, NokiaLCD::LCD6610); -int zoom = DEFAULTZOOM; - - -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"); - if(!jpegfile) { - pc.printf("File not Found: %s\n\r",filename); - } - 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)); +Serial pc(A4, SERIAL_RX); - 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); -} - -void wiflyConnect() -{ - wifly.disconnect(); - wifly.init(); - while (!wifly.connect()) { - pc.printf("waiting\n\r"); - }// join the network -} - -void getNewImage(float latitude, float longitude, int zoom) -{ - TCPSocketConnection sock; - sock.connect("maps.googleapis.com", 80); - int ret = 0; - int total_bytes = 0; - char http_cmd[300]; - sprintf(http_cmd, "GET /maps/api/staticmap?center=%f%%2C%f&zoom=%d&size=130x130&sensor=true&format=jpg-baseline HTTP/1.0\n\n",latitude,longitude,zoom); - sock.send_all(http_cmd, sizeof(http_cmd)-1); - - sock.set_blocking(false,10000); - char buffer[300]; - FILE* pFile; - pc.printf("%s\n\r",http_cmd); - pFile = fopen ("/local/image.jpg","w"); - pc.printf("Opening File\n\r"); - bool found_start = false; - bool found_end = false; - while (true) { - ret = sock.receive(buffer, sizeof(buffer)-1); - if (ret <= 0) { - pc.printf("Ret < 0. Break. \n\r"); - //wiflyConnect(); - break; - } - buffer[ret] = '\0'; - total_bytes += ret; - pc.printf("Received %d chars from server, total %d: %s\n\r", ret,total_bytes, buffer); - if(found_start) { - for(int i=1; i<ret; i++) { - if(buffer[i-1]==0xFF && buffer[i]==0xD9) { //jpg file end at FFD9 - pc.printf("found end. \n\r"); - fwrite(buffer,1,i+1,pFile); - found_end = true; - break; - } - } - if(!found_end) - fwrite(buffer,1,ret,pFile); - else { - pc.printf("Found Start and End. Break. \n\r"); - break; - } - - } else { - for(int i=1; i<ret; i++) { - if(buffer[i-1]==0xFF && buffer[i]==0xD8) { //jpg file starts from FFD8 - pc.printf("found start.\n\r"); - fwrite(&buffer[i-1],1,ret-i+1,pFile); - found_start = true; - break; - } - } - } - } - - fclose (pFile); - pc.printf("Closing File\n\r"); - sock.close(); - lcd.cls(); - ReadJPEGFromFile("/local/IMAGE.JPG", &lcd); -} +GPS ark(PA_9, PA_10); +DigitalOut myled(LED1); int main() { - pc.printf("Hello\n\r"); - wifly.init(); //Use DHCP - while (!wifly.connect()) { - pc.printf("waiting\n\r"); - }// join the network - pc.printf("IP Address is %s\n", wifly.getIPAddress()); - - float longitude = 0.0; - float latitude = 0.0; while(1) { - if(gps.sample()) { - // pc.printf("I'm at %f, %f\n", gps.longitude, gps.latitude); - longitude = gps.longitude; - latitude = gps.latitude; + if( ark.sample() == 1) { + myled=0; + float latitude = ark.latitude; + float longitude = ark.longitude; + float utc =50000; + pc.printf("latitude: %0.2f, longitude: %0.2f, utc: %f\r\n",latitude,longitude,utc); + wait(1); } else { - pc.printf("Oh Dear! No lock :(\n"); + myled=1; } - if(Refresh) - getNewImage(latitude,longitude,zoom); - else if(ZoomIn) - getNewImage(latitude,longitude,++zoom); - else if(ZoomOut) - getNewImage(latitude,longitude,--zoom); } - wifly.disconnect(); } \ No newline at end of file
diff -r c4c66c630011 -r 8cc48b05d20e mbed.bld --- a/mbed.bld Fri Dec 14 15:40:21 2012 +0000 +++ b/mbed.bld Wed Jan 04 15:52:24 2017 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/10b9abbe79a6 \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/9baf128c2fab \ No newline at end of file
diff -r c4c66c630011 -r 8cc48b05d20e picojpeg/picojpeg.c --- a/picojpeg/picojpeg.c Fri Dec 14 15:40:21 2012 +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; -}
diff -r c4c66c630011 -r 8cc48b05d20e picojpeg/picojpeg.h --- a/picojpeg/picojpeg.h Fri Dec 14 15:40:21 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -//------------------------------------------------------------------------------ -// picojpeg v1.0 - Public domain, Rich Geldreich <richgel99@gmail.com> -//------------------------------------------------------------------------------ -#ifndef PICOJPEG_H -#define PICOJPEG_H - -#ifdef __cplusplus -extern "C" { -#endif - -// Error codes -enum -{ - PJPG_NO_MORE_BLOCKS = 1, - PJPG_BAD_DHT_COUNTS, - PJPG_BAD_DHT_INDEX, - PJPG_BAD_DHT_MARKER, - PJPG_BAD_DQT_MARKER, - PJPG_BAD_DQT_TABLE, - PJPG_BAD_PRECISION, - PJPG_BAD_HEIGHT, - PJPG_BAD_WIDTH, - PJPG_TOO_MANY_COMPONENTS, - PJPG_BAD_SOF_LENGTH, - PJPG_BAD_VARIABLE_MARKER, - PJPG_BAD_DRI_LENGTH, - PJPG_BAD_SOS_LENGTH, - PJPG_BAD_SOS_COMP_ID, - PJPG_W_EXTRA_BYTES_BEFORE_MARKER, - PJPG_NO_ARITHMITIC_SUPPORT, - PJPG_UNEXPECTED_MARKER, - PJPG_NOT_JPEG, - PJPG_UNSUPPORTED_MARKER, - PJPG_BAD_DQT_LENGTH, - PJPG_TOO_MANY_BLOCKS, - PJPG_UNDEFINED_QUANT_TABLE, - PJPG_UNDEFINED_HUFF_TABLE, - PJPG_NOT_SINGLE_SCAN, - PJPG_UNSUPPORTED_COLORSPACE, - PJPG_UNSUPPORTED_SAMP_FACTORS, - PJPG_DECODE_ERROR, - PJPG_BAD_RESTART_MARKER, - PJPG_ASSERTION_ERROR, - PJPG_BAD_SOS_SPECTRAL, - PJPG_BAD_SOS_SUCCESSIVE, - PJPG_STREAM_READ_ERROR, - PJPG_NOTENOUGHMEM, - PJPG_UNSUPPORTED_COMP_IDENT, - PJPG_UNSUPPORTED_QUANT_TABLE, - PJPG_UNSUPPORTED_MODE, -}; - -// Scan types - currently only GRAYSCALE, YH1V1, and YH2V2 are actually supported. -typedef enum -{ - PJPG_GRAYSCALE, - PJPG_YH1V1, - PJPG_YH2V1, - PJPG_YH1V2, - PJPG_YH2V2 -} pjpeg_scan_type_t; - -typedef struct -{ - // Image resolution - int m_width; - int m_height; - // Number of components (1 or 3) - int m_comps; - // Total number of minimum coded units (MCU's) per row/col. - int m_MCUSPerRow; - int m_MCUSPerCol; - // Scan type - pjpeg_scan_type_t m_scanType; - // MCU width/height in pixels - int m_MCUWidth; - int m_MCUHeight; - // Pointers to internal MCU pixel component buffers. - // These buffers Will be filled with pixels each time pjpegDecodeMCU() is called successfully. - // Each MCU consists of (m_MCUWidth/8)*(m_MCUHeight/8) blocks (currently either 1 for greyscale/no subsampling, or 4 for H2V2 sampling factors), where each block is a contiguous array of 64 (8x8) bytes. - // For greyscale images, only the values in m_pMCUBufR are valid. - unsigned char *m_pMCUBufR; - unsigned char *m_pMCUBufG; - unsigned char *m_pMCUBufB; -} pjpeg_image_info_t; - -typedef unsigned char (*pjpeg_need_bytes_callback_t)(unsigned char* pBuf, unsigned char buf_size, unsigned char *pBytes_actually_read, void *pCallback_data); - -// Initializes the decompressor. Returns 0 on success, or one of the above error codes on failure. -// pNeed_bytes_callback will be called to fill the decompressor's internal input buffer. -// Not thread safe. -unsigned char pjpeg_decode_init(pjpeg_image_info_t *pInfo, pjpeg_need_bytes_callback_t pNeed_bytes_callback, void *pCallback_data); - -// Decompresses the file's next MCU. Returns 0 on success, PJPG_NO_MORE_BLOCKS if no more blocks are available, or an error code. -// Must be called a total of m_MCUSPerRow*m_MCUSPerCol times to completely decompress the image. -unsigned char pjpeg_decode_mcu(void); - -#ifdef __cplusplus -} -#endif - -#endif // PICOJPEG_H