static BOOL OpenInput(const char* FileName) { int m; lIsITUFax = FALSE; InFile = fopen(FileName, "rb"); if (InFile == NULL) { FatalError("Cannot open '%s'", FileName); return FALSE; } // Now we can initialize the JPEG decompression object. Decompressor.err = jpeg_std_error(&ErrorHandler.pub); ErrorHandler.pub.error_exit = my_error_exit; ErrorHandler.pub.output_message = my_output_message; jpeg_create_decompress(&Decompressor); jpeg_stdio_src(&Decompressor, InFile); for (m = 0; m < 16; m++) jpeg_save_markers(&Decompressor, JPEG_APP0 + m, 0xFFFF); setup_read_icc_profile(&Decompressor); fseek(InFile, 0, SEEK_SET); jpeg_read_header(&Decompressor, TRUE); return TRUE; }
//- JPEG ----------------------------------------------------------------------- static cmsHPROFILE loadFromJpegData(const QByteArray& data) { cmsHPROFILE profile = 0; struct jpeg_decompress_struct srcinfo; JPEGErrorManager srcErrorManager; srcinfo.err = &srcErrorManager; jpeg_create_decompress(&srcinfo); if (setjmp(srcErrorManager.jmp_buffer)) { kError() << "libjpeg error in src\n"; return 0; } QBuffer buffer(const_cast<QByteArray*>(&data)); buffer.open(QIODevice::ReadOnly); IODeviceJpegSourceManager::setup(&srcinfo, &buffer); setup_read_icc_profile(&srcinfo); jpeg_read_header(&srcinfo, true); jpeg_start_decompress(&srcinfo); uchar* profile_data; uint profile_len; if (read_icc_profile(&srcinfo, &profile_data, &profile_len)) { LOG("Found a profile, length:" << profile_len); profile = cmsOpenProfileFromMem(profile_data, profile_len); } jpeg_destroy_decompress(&srcinfo); return profile; }
int dt_imageio_jpeg_read_header(const char *filename, dt_imageio_jpeg_t *jpg) { jpg->f = fopen(filename, "rb"); if(!jpg->f) return 1; struct dt_imageio_jpeg_error_mgr jerr; jpg->dinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = dt_imageio_jpeg_error_exit; if(setjmp(jerr.setjmp_buffer)) { jpeg_destroy_decompress(&(jpg->dinfo)); fclose(jpg->f); return 1; } jpeg_create_decompress(&(jpg->dinfo)); jpeg_stdio_src(&(jpg->dinfo), jpg->f); setup_read_exif(&(jpg->dinfo)); setup_read_icc_profile(&(jpg->dinfo)); // jpg->dinfo.buffered_image = TRUE; jpeg_read_header(&(jpg->dinfo), TRUE); #ifdef JCS_EXTENSIONS jpg->dinfo.out_color_space = JCS_EXT_RGBX; jpg->dinfo.out_color_components = 4; #else jpg->dinfo.out_color_space = JCS_RGB; jpg->dinfo.out_color_components = 3; #endif jpg->width = jpg->dinfo.image_width; jpg->height = jpg->dinfo.image_height; return 0; }
JPEGImageReader(JPEGImageDecoder* decoder) : m_decoder(decoder) , m_bufferLength(0) , m_bytesToSkip(0) , m_state(JPEG_HEADER) , m_samples(0) #if USE(QCMSLIB) , m_transform(0) #endif { memset(&m_info, 0, sizeof(jpeg_decompress_struct)); // We set up the normal JPEG error routines, then override error_exit. m_info.err = jpeg_std_error(&m_err.pub); m_err.pub.error_exit = error_exit; // Allocate and initialize JPEG decompression object. jpeg_create_decompress(&m_info); decoder_source_mgr* src = 0; if (!m_info.src) { src = (decoder_source_mgr*)fastZeroedMalloc(sizeof(decoder_source_mgr)); if (!src) { m_state = JPEG_ERROR; return; } } m_info.src = (jpeg_source_mgr*)src; // Set up callback functions. src->pub.init_source = init_source; src->pub.fill_input_buffer = fill_input_buffer; src->pub.skip_input_data = skip_input_data; src->pub.resync_to_restart = jpeg_resync_to_restart; src->pub.term_source = term_source; src->decoder = this; #if USE(ICCJPEG) // Retain ICC color profile markers for color management. setup_read_icc_profile(&m_info); #endif // Keep APP1 blocks, for obtaining exif data. jpeg_save_markers(&m_info, exifMarker, 0xFFFF); }
int dt_imageio_jpeg_read_header(const char *filename, dt_imageio_jpeg_t *jpg) { jpg->f = fopen(filename, "rb"); if(!jpg->f) return 1; struct dt_imageio_jpeg_error_mgr jerr; jpg->dinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = dt_imageio_jpeg_error_exit; if (setjmp(jerr.setjmp_buffer)) { jpeg_destroy_decompress(&(jpg->dinfo)); fclose(jpg->f); return 1; } jpeg_create_decompress(&(jpg->dinfo)); jpeg_stdio_src(&(jpg->dinfo), jpg->f); setup_read_icc_profile(&(jpg->dinfo)); // jpg->dinfo.buffered_image = TRUE; jpeg_read_header(&(jpg->dinfo), TRUE); jpg->width = jpg->dinfo.image_width; jpg->height = jpg->dinfo.image_height; return 0; }
int dt_imageio_jpeg_decompress_header(const void *in, size_t length, dt_imageio_jpeg_t *jpg) { jpeg_create_decompress(&(jpg->dinfo)); jpg->src.init_source = dt_imageio_jpeg_init_source; jpg->src.fill_input_buffer = dt_imageio_jpeg_fill_input_buffer; jpg->src.skip_input_data = dt_imageio_jpeg_skip_input_data; jpg->src.resync_to_restart = jpeg_resync_to_restart; jpg->src.term_source = dt_imageio_jpeg_term_source; jpg->src.next_input_byte = (JOCTET *)in; jpg->src.bytes_in_buffer = length; struct dt_imageio_jpeg_error_mgr jerr; jpg->dinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = dt_imageio_jpeg_error_exit; if(setjmp(jerr.setjmp_buffer)) { jpeg_destroy_decompress(&(jpg->dinfo)); return 1; } jpg->dinfo.src = &(jpg->src); setup_read_exif(&(jpg->dinfo)); setup_read_icc_profile(&(jpg->dinfo)); jpeg_read_header(&(jpg->dinfo), TRUE); #ifdef JCS_EXTENSIONS jpg->dinfo.out_color_space = JCS_EXT_RGBX; jpg->dinfo.out_color_components = 4; #else jpg->dinfo.out_color_space = JCS_RGB; jpg->dinfo.out_color_components = 3; #endif // jpg->dinfo.buffered_image = TRUE; jpg->width = jpg->dinfo.image_width; jpg->height = jpg->dinfo.image_height; return 0; }
static gint32 load_image (char *filename) { GPixelRgn pixel_rgn; TileDrawable *drawable; gint32 image_ID; gint32 layer_ID; struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; FILE *infile; guchar *buf; guchar **rowbuf; char *name; int image_type; int layer_type; int tile_height; int scanlines; int i, start, end; int m; int depth = 8; /* We set up the normal JPEG error routines. */ cinfo.err = jpeg_std_error (&jerr.pub); jerr.pub.error_exit = my_error_exit; if ((infile = fopen (filename, "rb")) == NULL) { g_warning ("can't open \"%s\"\n", filename); gimp_quit (); } if( strrchr(filename,'.') && strcmp( strrchr(filename, '.'), ".jp4") == 0 ) depth = 16; name = malloc (strlen (filename) + 12); sprintf (name, "%s %s:", _("Loading"), filename); gimp_progress_init (name); free (name); image_ID = -1; /* Establish the setjmp return context for my_error_exit to use. */ if (setjmp (jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object, close the input file, and return. */ jpeg_destroy_decompress (&cinfo); if (infile) fclose (infile); if (image_ID != -1) gimp_image_delete (image_ID); gimp_quit (); } /* Now we can initialize the JPEG decompression object. */ jpeg_create_decompress (&cinfo); /* Step 2: specify data source (eg, a file) */ jpeg_stdio_src (&cinfo, infile); setup_read_icc_profile(&cinfo); for (m = 0; m < 16; m++) jpeg_save_markers(&cinfo, JPEG_APP0 + m, 0xFFFF); /* Step 3: read file parameters with jpeg_read_header() */ (void) jpeg_read_header (&cinfo, TRUE); /* We can ignore the return value from jpeg_read_header since * (a) suspension is not possible with the stdio data source, and * (b) we passed TRUE to reject a tables-only JPEG file as an error. * See libjpeg.doc for more info. */ /* 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. */ prepareColour( &cinfo ); /* Step 5: Start decompressor */ jpeg_start_decompress (&cinfo); /* We may need to do some setup of our own at this point before reading * the data. After jpeg_start_decompress() we have the correct scaled * output image dimensions available, as well as the output colormap * if we asked for color quantization. * In this example, we need to make an output work buffer of the right size. */ /* temporary buffer */ tile_height = gimp_tile_height (); buf = g_new (guchar, tile_height * cinfo.output_width * cinfo.output_components); rowbuf = g_new (guchar*, tile_height); for (i = 0; i < tile_height; i++) rowbuf[i] = buf + cinfo.output_width * cinfo.output_components * i; /* Create a new image of the proper size and associate the filename with it. */ if(depth == 8) { switch (cinfo.output_components) { case 1: image_type = GRAY; layer_type = GRAY_IMAGE; break; case 3: image_type = RGB; layer_type = RGB_IMAGE; break; case 4: image_type = RGB; layer_type = RGBA_IMAGE; break; default: gimp_quit (); } } else { switch (cinfo.output_components) { case 1: image_type = U16_GRAY; layer_type = U16_GRAY_IMAGE; break; case 3: image_type = U16_RGB; layer_type = U16_RGB_IMAGE; break; case 4: image_type = U16_RGB; layer_type = U16_RGBA_IMAGE; break; default: gimp_quit (); } } image_ID = gimp_image_new (cinfo.output_width / (depth/8), cinfo.output_height, image_type); gimp_image_set_filename (image_ID, filename); layer_ID = gimp_layer_new (image_ID, _("Background"), cinfo.output_width / (depth/8), cinfo.output_height, layer_type, 100, NORMAL_MODE); gimp_image_add_layer (image_ID, layer_ID, 0); drawable = gimp_drawable_get (layer_ID); gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, TRUE, FALSE); /* Step 6: while (scan lines remain to be read) */ /* jpeg_read_scanlines(...); */ /* Here we use the library's state variable cinfo.output_scanline as the * loop counter, so that we don't have to keep track ourselves. */ while (cinfo.output_scanline < cinfo.output_height) { start = cinfo.output_scanline; end = cinfo.output_scanline + tile_height; end = MIN (end,CAST(int) cinfo.output_height); scanlines = end - start; for (i = 0; i < scanlines; i++) jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &rowbuf[i], 1); /* for (i = start; i < end; i++) gimp_pixel_rgn_set_row (&pixel_rgn, tilerow[i - start], 0, i, drawable->width); */ if(cinfo.out_color_space == JCS_CMYK) for(i = 0; i < scanlines*drawable->width*cinfo.output_components; ++i) buf[i] = 255 - buf[i]; if(depth == 16 && 0) for(i = 0; i < scanlines*drawable->width*cinfo.output_components; ++i) { unsigned char c = buf[2*i]; buf[2*i] = buf[2*i+1]; buf[2*i+1] = c; } gimp_pixel_rgn_set_rect (&pixel_rgn, buf, 0, start, drawable->width, scanlines); gimp_progress_update ((double) cinfo.output_scanline / (double) cinfo.output_height); } // Step 6a: read icc profile { LPBYTE Buffer = NULL; size_t Len = 0; cmsHPROFILE hProfile=NULL; if (read_icc_profile(&cinfo, &Buffer, &Len)) { printf ("%s:%d %s() embedded profile found\n",__FILE__,__LINE__,__func__); } else if (read_icc_profile2(&cinfo, &Buffer, &Len)) { printf ("%s:%d %s() default profile selected\n",__FILE__,__LINE__,__func__); } if(Buffer && Len) { hProfile = cmsOpenProfileFromMem(Buffer, Len); if (hProfile) { gimp_image_set_icc_profile_by_mem (image_ID, Len, Buffer, ICC_IMAGE_PROFILE); cmsCloseProfile (hProfile); free(Buffer); printf ("%s:%d %s() set profile\n",__FILE__,__LINE__,__func__); } } } /* Step 7: Finish decompression */ jpeg_finish_decompress (&cinfo); /* We can ignore the return value since suspension is not possible * with the stdio data source. */ /* Step 8: Release JPEG decompression object */ /* This is an important step since it will release a good deal of memory. */ jpeg_destroy_decompress (&cinfo); /* free up the temporary buffers */ g_free (rowbuf); g_free (buf); /* After finish_decompress, we can close the input file. * Here we postpone it until after no more JPEG errors are possible, * so as to simplify the setjmp error logic above. (Actually, I don't * think that jpeg_destroy can do an error exit, but why assume anything...) */ fclose (infile); /* At this point you may want to check to see whether any corrupt-data * warnings occurred (test whether jerr.num_warnings is nonzero). */ /* Tell the GIMP to display the image. */ gimp_drawable_flush (drawable); return image_ID; }