Sven Neumann writes: > If someone wants to try to recover some of the JPEG save settings > when loading the JPEG file, feel free. I did. Index: plug-ins/jpeg/jpeg-load.c =================================================================== --- plug-ins/jpeg/jpeg-load.c (revision 22905) +++ plug-ins/jpeg/jpeg-load.c (working copy) @@ -50,6 +50,61 @@ gint32 layer_ID_global; +static gboolean +check_table (const JQUANT_TBL *file_table, + gint quant_tbl_no, + gint *quality) +{ + int i; + gboolean all_ones = TRUE; + gint q; + struct jpeg_compress_struct cinfo; + + /* First do the simple check for quality 100, a table with all ones */ + for (i = 0; i < 64; i++) + { + if (file_table->quantval[i] != 1) + all_ones = 0; + } + + if (all_ones) + { + *quality = 100; + return TRUE; + } + + /* Then produce tables for all qualities 1..99 and compare. It's + * better to do it this way than to calculate the quality factor + * backwards from the table in the file because of rounding errors: + * We would never match all quality factors exactly. + */ + for (q = 1; q < 100; q++) + { + jpeg_create_compress (&cinfo); + + jpeg_set_quality (&cinfo, q, TRUE); + + for (i = 0; i < 64; i++) + { + if (cinfo.quant_tbl_ptrs[quant_tbl_no]->quantval[i] != file_table->quantval[i]) + break; + } + + jpeg_destroy_compress (&cinfo); + + if (i == 64) + break; + } + + if (q < 100) + { + *quality = q; + return TRUE; + } + + return FALSE; +} + gint32 load_image (const gchar *filename, GimpRunMode runmode, @@ -57,6 +112,7 @@ { GimpPixelRgn pixel_rgn; GimpDrawable *drawable; + GimpParasite *parasite; gint32 volatile image_ID; gint32 layer_ID; struct jpeg_decompress_struct cinfo; @@ -76,6 +132,8 @@ GimpParasite * volatile comment_parasite = NULL; jpeg_saved_marker_ptr marker; gboolean found_exif = FALSE; + gint q0, q1, q2; + gint quality = -1; /* We set up the normal JPEG error routines. */ cinfo.err = jpeg_std_error (&jerr.pub); @@ -153,6 +211,32 @@ (void) jpeg_read_header (&cinfo, TRUE); + /* Check if the quantization tables used are produced by libjpeg's + * jpeg_set_quality(). + */ + + if ((cinfo.jpeg_color_space == JCS_GRAYSCALE && + check_table (cinfo.quant_tbl_ptrs[cinfo.comp_info[0].quant_tbl_no], + cinfo.comp_info[0].quant_tbl_no, + &q0)) || + (cinfo.jpeg_color_space == JCS_YCbCr && + check_table (cinfo.quant_tbl_ptrs[cinfo.comp_info[0].quant_tbl_no], + cinfo.comp_info[0].quant_tbl_no, + &q0) && + check_table (cinfo.quant_tbl_ptrs[cinfo.comp_info[1].quant_tbl_no], + cinfo.comp_info[1].quant_tbl_no, + &q1) && + q0 == q1 && + (cinfo.comp_info[1].quant_tbl_no == cinfo.comp_info[2].quant_tbl_no || + (check_table (cinfo.quant_tbl_ptrs[cinfo.comp_info[2].quant_tbl_no], + cinfo.comp_info[2].quant_tbl_no, + &q2) && + q1 == q2)))) + { + /* Yes. Store the quality in a parasite below. */ + quality = q0; + } + /* 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. @@ -257,6 +341,14 @@ layer_type, 100, GIMP_NORMAL_MODE); } + if (quality > 0) + { + parasite = gimp_parasite_new ("jpeg-original-quality", + 0, sizeof (gint), &quality); + gimp_image_parasite_attach (image_ID, parasite); + gimp_parasite_free (parasite); + } + drawable_global = drawable = gimp_drawable_get (layer_ID); gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, TRUE, FALSE); Index: plug-ins/jpeg/jpeg.c =================================================================== --- plug-ins/jpeg/jpeg.c (revision 22905) +++ plug-ins/jpeg/jpeg.c (working copy) @@ -428,6 +428,23 @@ * over the JPEG encoding parameters. */ run_mode = GIMP_RUN_INTERACTIVE; + + /* If we have stored an estimate of the libjpeg quality + * factor used when creating the original image, and + * that is larger than the default quality, use it as + * default for the dialog. + */ + parasite = gimp_image_parasite_find (orig_image_ID, + "jpeg-original-quality"); + if (parasite) + { + gint quality; + memmove (&quality, gimp_parasite_data (parasite), sizeof (gint)); + gimp_parasite_free (parasite); + + if (quality > jsvals.quality) + jsvals.quality = quality; + } } break; } _______________________________________________ Gimp-developer mailing list Gimp-developer@xxxxxxxxxxxxxxxxxxxxxx https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer