GImage *GImageRead_Jpeg(FILE *infile) { GImage *ret; struct _GImage *base; struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; JSAMPLE *rows[1]; struct jpegState js; int ypos; cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; if (setjmp(jerr.setjmp_buffer)) { jpeg_destroy_decompress(&cinfo); return( NULL ); } jpeg_CreateDecompress(&cinfo,JPEG_LIB_VERSION,(size_t) sizeof(struct jpeg_decompress_struct)); jpeg_stdio_src(&cinfo, infile); (void) jpeg_read_header(&cinfo, TRUE); if ( cinfo.jpeg_color_space == JCS_GRAYSCALE ) cinfo.out_color_space = JCS_RGB; ret = GImageCreate(it_true,cinfo.image_width, cinfo.image_height); if ( ret==NULL ) { jpeg_destroy_decompress(&cinfo); return( NULL ); } base = ret->u.image; (void) jpeg_start_decompress(&cinfo); rows[0] = (JSAMPLE *) malloc(3*cinfo.image_width); js.cinfo = &cinfo; js.base = base; js.buffer = rows[0]; while (cinfo.output_scanline < cinfo.output_height) { ypos = cinfo.output_scanline; (void) jpeg_read_scanlines(&cinfo, rows, 1); transferBufferToImage(&js,ypos); } (void) jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); free(rows[0]); return( ret ); }
void qxe_jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize) { jpeg_CreateDecompress (cinfo, version, structsize); }
static bool image_jpeg_load (fs_file_t *f, image_t *im, int *error) { uint8_t *p, *image = NULL; int width, height; struct jpeg_decompress_struct ds; struct jpeg_error_mgr em; *error = IMAGE_ERROR_INTERNAL; ds.err = jpeg_std_error(&em); ds.err->error_exit = jpeg_error_exit; ds.err->emit_message = jpeg_emit_message; if (unlikely(0 != setjmp(jpeg_jmpbuf))) { return false; } jpeg_CreateDecompress(&ds, JPEG_LIB_VERSION, sizeof(ds)); if (unlikely(0 != setjmp(jpeg_jmpbuf))) { goto error; } jpeg_src(&ds, f); jpeg_read_header(&ds, TRUE); ds.out_color_space = jpeg_bgrx ? jpeg_bgrx : JCS_RGB; jpeg_start_decompress(&ds); width = ds.output_width; height = ds.output_height; if (!image_dimensions_valid(width, height)) { *error = IMAGE_ERROR_INVALID_SIZE; goto error; } p = image = mem_alloc(image_mem_pool, width * height * 4); if (jpeg_bgrx) { for (int h = 0; h < height; h++, p += width * 4) { JSAMPROW scanlines[1] = { (void *)p }; jpeg_read_scanlines(&ds, (void *)scanlines, 1); } } else { uint8_t *data = mem_alloc(image_mem_pool, width * 3); for (int h = 0; h < height; h++) { JSAMPROW scanlines[1] = { (void *)data }; jpeg_read_scanlines(&ds, (void *)scanlines, 1); for (int i = 0; i < width * 3; i += 3, p += 4) { p[0] = data[i + 2]; p[1] = data[i + 1]; p[2] = data[i + 0]; p[3] = 0xff; } } mem_free(data); } jpeg_finish_decompress(&ds); jpeg_destroy_decompress(&ds); im->width = width; im->height = height; im->format = IMAGE_DATA_FORMAT_BGRA; im->data = image; return true; error: jpeg_destroy_decompress(&ds); mem_free(image); return false; }
bool ossimCodecFactory::decodeJpeg( const std::vector<ossim_uint8>& in, ossimRefPtr<ossimImageData>& out ) const { bool result = false; // Note: This is public and can be called directly; hence, the signature check // Check for jpeg signature: if ( in.size() > 3 ) { if ( (in[0] == 0xff) && (in[1] == 0xd8) && (in[2] == 0xff) && (in[3] == 0xe0) ) { /* This struct contains the JPEG decompression parameters and pointers * to working space (which is allocated as needed by the JPEG library). */ jpeg_decompress_struct cinfo; /* We use our private extension JPEG error handler. * Note that this struct must live as long as the main JPEG parameter * struct, to avoid dangling-pointer problems. */ ossimJpegErrorMgr jerr; /* Step 1: allocate and initialize JPEG decompression object */ /* We set up the normal JPEG error routines, then override error_exit. */ cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = ossimJpegErrorExit; /* Establish the setjmp return context for my_error_exit to use. */ if (setjmp(jerr.setjmp_buffer) == 0) { result = true; /* Now we can initialize the JPEG decompression object. */ jpeg_CreateDecompress(&cinfo, JPEG_LIB_VERSION, sizeof(cinfo)); //--- // Step 2: specify data source. In this case we will uncompress from // memory so we will use "ossimJpegMemorySrc" in place of " jpeg_stdio_src". //--- ossimJpegMemorySrc ( &cinfo, &(in.front()), (size_t)(in.size()) ); /* Step 3: read file parameters with jpeg_read_header() */ jpeg_read_header(&cinfo, TRUE); /* Step 4: set parameters for decompression */ /* In this example, we don't need to change any of the defaults set by * jpeg_read_header(), so we do nothing here. */ /* Step 5: Start decompressor */ jpeg_start_decompress(&cinfo); #if 0 /* Please leave for debug. (drb) */ if ( traceDebug() ) { ossimNotify(ossimNotifyLevel_DEBUG) << "jpeg cinfo.output_width: " << cinfo.output_width << "\njpeg cinfo.output_height: " << cinfo.output_height << "\n"; } #endif const ossim_uint32 SAMPLES = cinfo.output_width; const ossim_uint32 LINES = cinfo.output_height; const ossim_uint32 BANDS = cinfo.output_components; if ( out.valid() ) { // This will resize tile if not correct. out->setImageRectangleAndBands( ossimIrect(0,0,(ossim_int32)SAMPLES-1,(ossim_int32)LINES-1), BANDS ); } else { out = new ossimU8ImageData( 0, BANDS, SAMPLES, LINES ); out->initialize(); } // Get pointers to the cache tile buffers. std::vector<ossim_uint8*> destinationBuffer(BANDS); for (ossim_uint32 band = 0; band < BANDS; ++band) { destinationBuffer[band] = out->getUcharBuf(band); } std::vector<ossim_uint8> lineBuffer(SAMPLES * cinfo.output_components); JSAMPROW jbuf[1]; jbuf[0] = (JSAMPROW) &(lineBuffer.front()); while (cinfo.output_scanline < LINES) { // Read a line from the jpeg file. jpeg_read_scanlines(&cinfo, jbuf, 1); //--- // Copy the line which if band interleaved by pixel the the band // separate buffers. //--- ossim_uint32 index = 0; for (ossim_uint32 sample = 0; sample < SAMPLES; ++sample) { for (ossim_uint32 band = 0; band < BANDS; ++band) { destinationBuffer[band][sample] = lineBuffer[index]; ++index; } } for (ossim_uint32 band = 0; band < BANDS; ++band) { destinationBuffer[band] += SAMPLES; } } // Set the tile status: out->validate(); // clean up... jpeg_finish_decompress(&cinfo); } // Matches: if (setjmp(jerr.setjmp_buffer) == 0) jpeg_destroy_decompress(&cinfo); } // Matches: if ( (in[0] == 0xff) ... ) } // Matches: if ( in.size() > 3 ) return result; }