int decode_scan(void) { #ifdef _JPEG_DEBUG printf("%d MCUs in total.\n", iceenv.num_mcu_x * iceenv.num_mcu_y); printf("MCU dimension: %dx%d\n", iceenv.max_samp_x << 3, iceenv.max_samp_y << 3); #endif // if (iceenv.scan_buffer[iceenv.buf_pos] == 0xFF && iceenv.scan_buffer[iceenv.buf_pos + 1] == 0x00) // skip_stuff_byte = 1; init_idct(); for (iceenv.cur_mcu_x = iceenv.cur_mcu_y = 0;;) { //printf("Decoding MCU [%d,%d]\n", iceenv.cur_mcu_x, iceenv.cur_mcu_y); decode_mcu(); iceenv.cur_mcu_x++; if (iceenv.cur_mcu_x == iceenv.num_mcu_x) { iceenv.cur_mcu_x = 0; iceenv.cur_mcu_y++; if (iceenv.cur_mcu_y == iceenv.num_mcu_y) break; } if (!iceenv.restart_interval) continue; iceenv.rstcount--; if (!iceenv.rstcount) { int err = process_rst(); if (err != ERR_OK) return err; } } //if (iceenv.cur_byte_remaining > 0) iceenv.buf_pos++; return ERR_OK; }
int JPEGDecoder::read(void) { int y, x; uint8 *pDst_row; if(is_available == 0) return 0; if (mcu_y >= image_info.m_MCUSPerCol) { delete pImage; g_pInFile.close(); return 0; } if (reduce) { // In reduce mode, only the first pixel of each 8x8 block is valid. pDst_row = pImage; if (image_info.m_scanType == PJPG_GRAYSCALE) { *pDst_row = image_info.m_pMCUBufR[0]; } else { uint y, x; for (y = 0; y < col_blocks_per_mcu; y++) { uint src_ofs = (y * 128U); for (x = 0; x < row_blocks_per_mcu; x++) { pDst_row[0] = image_info.m_pMCUBufR[src_ofs]; pDst_row[1] = image_info.m_pMCUBufG[src_ofs]; pDst_row[2] = image_info.m_pMCUBufB[src_ofs]; pDst_row += 3; src_ofs += 64; } pDst_row += row_pitch - 3 * row_blocks_per_mcu; } } } else { // Copy MCU's pixel blocks into the destination bitmap. pDst_row = pImage; for (y = 0; y < image_info.m_MCUHeight; y += 8) { const int by_limit = min(8, image_info.m_height - (mcu_y * image_info.m_MCUHeight + y)); for (x = 0; x < image_info.m_MCUWidth; x += 8) { uint8 *pDst_block = pDst_row + x * image_info.m_comps; // Compute source byte offset of the block in the decoder's MCU buffer. uint src_ofs = (x * 8U) + (y * 16U); const uint8 *pSrcR = image_info.m_pMCUBufR + src_ofs; const uint8 *pSrcG = image_info.m_pMCUBufG + src_ofs; const uint8 *pSrcB = image_info.m_pMCUBufB + src_ofs; const int bx_limit = min(8, image_info.m_width - (mcu_x * image_info.m_MCUWidth + x)); if (image_info.m_scanType == PJPG_GRAYSCALE) { int bx, by; for (by = 0; by < by_limit; by++) { uint8 *pDst = pDst_block; for (bx = 0; bx < bx_limit; bx++) *pDst++ = *pSrcR++; pSrcR += (8 - bx_limit); pDst_block += row_pitch; } } else { int bx, by; for (by = 0; by < by_limit; by++) { uint8 *pDst = pDst_block; for (bx = 0; bx < bx_limit; bx++) { pDst[0] = *pSrcR++; pDst[1] = *pSrcG++; pDst[2] = *pSrcB++; pDst += 3; } pSrcR += (8 - bx_limit); pSrcG += (8 - bx_limit); pSrcB += (8 - bx_limit); pDst_block += row_pitch; } } } pDst_row += (row_pitch * 8); } } MCUx = mcu_x; MCUy = mcu_y; mcu_x++; if (mcu_x == image_info.m_MCUSPerRow) { mcu_x = 0; mcu_y++; } if(decode_mcu()==-1) is_available = 0 ; return 1; }
int JPEGDecoder::decode(char* pFilename, unsigned char pReduce){ if(pReduce) reduce = pReduce; g_pInFile = SD.open(pFilename, FILE_READ); if (!g_pInFile) return -1; g_nInFileOfs = 0; g_nInFileSize = g_pInFile.size(); status = pjpeg_decode_init(&image_info, pjpeg_callback, NULL, (unsigned char)reduce); if (status) { #ifdef DEBUG Serial.print("pjpeg_decode_init() failed with status "); Serial.println(status); if (status == PJPG_UNSUPPORTED_MODE) { Serial.println("Progressive JPEG files are not supported."); } #endif g_pInFile.close(); return -1; } // In reduce mode output 1 pixel per 8x8 block. decoded_width = reduce ? (image_info.m_MCUSPerRow * image_info.m_MCUWidth) / 8 : image_info.m_width; decoded_height = reduce ? (image_info.m_MCUSPerCol * image_info.m_MCUHeight) / 8 : image_info.m_height; row_pitch = image_info.m_MCUWidth * image_info.m_comps; //pImage = (uint8 *)malloc(image_info.m_MCUWidth * image_info.m_MCUHeight * image_info.m_comps); pImage = new uint8[image_info.m_MCUWidth * image_info.m_MCUHeight * image_info.m_comps]; if (!pImage) { g_pInFile.close(); #ifdef DEBUG Serial.println("Memory Allocation Failure"); #endif return -1; } memset(pImage , 0 , sizeof(pImage)); row_blocks_per_mcu = image_info.m_MCUWidth >> 3; col_blocks_per_mcu = image_info.m_MCUHeight >> 3; is_available = 1 ; width = decoded_width; height = decoded_height; comps = image_info.m_comps; MCUSPerRow = image_info.m_MCUSPerRow; MCUSPerCol = image_info.m_MCUSPerCol; scanType = image_info.m_scanType; MCUWidth = image_info.m_MCUWidth; MCUHeight = image_info.m_MCUHeight; return decode_mcu(); }
int JPEGDecoder::decode(File pInFile, unsigned char pReduce){ if(pReduce) reduce = pReduce; // g_pInFile = SD.open(pFilename, FILE_READ); g_pInFile = pInFile; if (!g_pInFile){ #ifdef DEBUG_JPEG Serial.println("failed to open jpeg file"); #endif return -1; } g_nInFileOfs = 0; g_nInFileSize = g_pInFile.size(); #ifdef DEBUG_JPEG Serial.print("file size = "); Serial.println(g_nInFileSize); #endif status = pjpeg_decode_init(&image_info, pjpeg_callback, NULL, (unsigned char)reduce); if (status) { #ifdef DEBUG_JPEG Serial.print("ERROR : pjpeg_decode_init() : "); /* switch(status & 63){ case PJPG_NO_MORE_BLOCKS: Serial.print("NO_MORE_BLOCKS"); break; case PJPG_BAD_DHT_COUNTS: Serial.print("BAD_DHT_COUNTS"); break; case PJPG_BAD_DHT_INDEX: Serial.print("BAD_DHT_INDEX"); break; case PJPG_BAD_DHT_MARKER: Serial.print("BAD_DHT_MARKER"); break; case PJPG_BAD_DQT_MARKER: Serial.print("BAD_DQT_MARKER"); break; case PJPG_BAD_DQT_TABLE: Serial.print("BAD_DQT_TABLE"); break; case PJPG_BAD_PRECISION: Serial.print("BAD_PRECISION"); break; case PJPG_BAD_HEIGHT: Serial.print("BAD_HEIGHT"); break; case PJPG_BAD_WIDTH: Serial.print("BAD_WIDTH"); break; case PJPG_TOO_MANY_COMPONENTS: Serial.print("TOO_MANY_COMPONENTS"); break; case PJPG_BAD_SOF_LENGTH: Serial.print("BAD_SOF_LENGTH"); break; case PJPG_BAD_VARIABLE_MARKER: Serial.print("BAD_VARIABLE_MARKER"); break; case PJPG_BAD_DRI_LENGTH: Serial.print("BAD_DRI_LENGTH"); break; case PJPG_BAD_SOS_LENGTH: Serial.print("BAD_SOS_LENGTH"); break; case PJPG_BAD_SOS_COMP_ID: Serial.print("BAD_SOS_COMP_ID"); break; case PJPG_W_EXTRA_BYTES_BEFORE_MARKER: Serial.print("W_EXTRA_BYTES"); break; case PJPG_NO_ARITHMITIC_SUPPORT: Serial.print("ARITHMITIC"); break; case PJPG_UNEXPECTED_MARKER: Serial.print("UNEXPECTED_MARKER"); break; case PJPG_NOT_JPEG: Serial.print("NOT_JPEG"); break; case PJPG_UNSUPPORTED_MARKER: Serial.print("UNSUPPORTED_MARKER"); break; case PJPG_BAD_DQT_LENGTH: Serial.print("BAD_DQT_LENGTH"); break; case PJPG_TOO_MANY_BLOCKS: Serial.print("TOO_MANY_BLOCKS"); break; case PJPG_UNDEFINED_QUANT_TABLE: Serial.print("QUANT_TABLE"); break; case PJPG_UNDEFINED_HUFF_TABLE: Serial.print("HUFF_TABLE"); break; case PJPG_NOT_SINGLE_SCAN: Serial.print("SINGLE_SCAN"); break; case PJPG_UNSUPPORTED_COLORSPACE: Serial.print("COLORSPACE"); break; case PJPG_UNSUPPORTED_SAMP_FACTORS: Serial.print("SAMP_FACTORS"); break; case PJPG_DECODE_ERROR: Serial.print("DECODE_ERROR"); break; case PJPG_BAD_RESTART_MARKER: Serial.print("RESTART_MARKER"); break; case PJPG_ASSERTION_ERROR: Serial.print("ASSERTION"); break; case PJPG_BAD_SOS_SPECTRAL: Serial.print("SOS_SPECTRAL"); break; case PJPG_BAD_SOS_SUCCESSIVE: Serial.print("SOS_SUCCESSIVE"); break; case PJPG_STREAM_READ_ERROR: Serial.print("STREAM_READ_ERRO"); break; case PJPG_NOTENOUGHMEM: Serial.print("NOTENOUGHMEM"); break; case PJPG_UNSUPPORTED_COMP_IDENT: Serial.print("COMP_IDENT"); break; case PJPG_UNSUPPORTED_QUANT_TABLE: Serial.print("QUANT_TABLE"); break; case PJPG_UNSUPPORTED_MODE: Serial.print("progressive JPEG"); break; default: Serial.print("Unknown"); break; } */ Serial.print(' '); Serial.print(status); Serial.print(' '); Serial.println(status,BIN); #endif g_pInFile.close(); return -1; } #ifdef DEBUG_JPEG Serial.print("Width :"); Serial.println(image_info.m_width); Serial.print("Height :"); Serial.println(image_info.m_height); Serial.print("Components:"); Serial.println(image_info.m_comps); Serial.print("MCU / row :"); Serial.println(image_info.m_MCUSPerRow); Serial.print("MCU / col :"); Serial.println(image_info.m_MCUSPerCol); Serial.print("Scan type :"); Serial.println(image_info.m_scanType); Serial.print("MCU width :"); Serial.println(image_info.m_MCUWidth); Serial.print("MCU height:"); Serial.println(image_info.m_MCUHeight); Serial.println(""); #endif // In reduce mode output 1 pixel per 8x8 block. decoded_width = reduce ? (image_info.m_MCUSPerRow * image_info.m_MCUWidth) / 8 : image_info.m_width; decoded_height = reduce ? (image_info.m_MCUSPerCol * image_info.m_MCUHeight) / 8 : image_info.m_height; row_pitch = image_info.m_MCUWidth * image_info.m_comps; //pImage = (uint8 *)malloc(image_info.m_MCUWidth * image_info.m_MCUHeight * image_info.m_comps); pImage = new uint8[image_info.m_MCUWidth * image_info.m_MCUHeight * image_info.m_comps]; if (!pImage) { g_pInFile.close(); #ifdef DEBUG_JPEG Serial.println("Memory Allocation Failure"); #endif return -1; } // memset(pImage , 0 , sizeof(pImage)); memset(pImage , 0 , image_info.m_MCUWidth * image_info.m_MCUHeight * image_info.m_comps); row_blocks_per_mcu = image_info.m_MCUWidth >> 3; col_blocks_per_mcu = image_info.m_MCUHeight >> 3; is_available = 1 ; width = decoded_width; height = decoded_height; comps = image_info.m_comps; MCUSPerRow = image_info.m_MCUSPerRow; MCUSPerCol = image_info.m_MCUSPerCol; scanType = image_info.m_scanType; MCUWidth = image_info.m_MCUWidth; MCUHeight = image_info.m_MCUHeight; return decode_mcu(); }