/* * ... FIXME: docs */ static void print_summary (struct jpeg_decompress_struct *cinfo, gint num_quant_tables) { gint quality; gint i; GSList *source_list; /* detect JPEG quality - test the formula used in the jpeg plug-in */ quality = jpeg_detect_quality (cinfo); if (quality > 0) g_print ("\tQuality: %02d (exact)\n", quality); else if (quality < 0) g_print ("\tQuality: %02d (approx)\n", -quality); else g_print ("\tQuality: unknown\n"); /* JPEG sampling factors */ g_print ("\tSampling: %dx%d", cinfo->comp_info[0].h_samp_factor, cinfo->comp_info[0].v_samp_factor); if ((cinfo->num_components > 1 && cinfo->num_components != 3) || cinfo->comp_info[1].h_samp_factor != 1 || cinfo->comp_info[1].v_samp_factor != 1 || cinfo->comp_info[2].h_samp_factor != 1 || cinfo->comp_info[2].v_samp_factor != 1) { for (i = 1; i < cinfo->num_components; i++) g_print (",%dx%d", cinfo->comp_info[i].h_samp_factor, cinfo->comp_info[i].v_samp_factor); } g_print ("\n"); /* Number of quantization tables */ g_print ("\tQ.tables: %d\n", num_quant_tables); source_list = detect_source (cinfo, num_quant_tables); if (source_list) { GSList *l; guint32 hash; guint32 hash_t; hash = hash_quant_tables (cinfo); hash_t = hash_transposed_quant_tables (cinfo); for (l = source_list; l; l = l->next) { QuantInfo *source_info = l->data; const gchar *comment = ""; if (source_info->hash == hash) comment = ""; else if (source_info->hash == hash_t) comment = " (rotated)"; else if (num_quant_tables == 1) comment = " (grayscale)"; else comment = " (FALSE MATCH)"; g_print ("\tSource: %s - %s%s\n", source_info->source_name, source_info->setting_name, comment); } g_slist_free (source_list); } else g_print ("\tSource: unknown\n"); }
/** * jpeg_detect_original_settings: * @cinfo: a pointer to a JPEG decompressor info. * @image_ID: the image to which the parasite should be attached. * * Analyze the image being decompressed (@cinfo) and extract the * sampling factors, quantization tables and overall image quality. * Store this information in a parasite and attach it to @image_ID. * * This function must be called after jpeg_read_header() so that * @cinfo contains the quantization tables and the sampling factors * for each component. * * Return Value: TRUE if a parasite has been attached to @image_ID. */ gboolean jpeg_detect_original_settings (struct jpeg_decompress_struct *cinfo, gint32 image_ID) { guint parasite_size; guchar *parasite_data; GimpParasite *parasite; guchar *dest; gint quality; gint num_quant_tables = 0; gint t; gint i; g_return_val_if_fail (cinfo != NULL, FALSE); if (cinfo->jpeg_color_space == JCS_UNKNOWN || cinfo->out_color_space == JCS_UNKNOWN) return FALSE; quality = jpeg_detect_quality (cinfo); /* no need to attach quantization tables if they are the ones from IJG */ if (quality <= 0) { for (t = 0; t < 4; t++) if (cinfo->quant_tbl_ptrs[t]) num_quant_tables++; } parasite_size = 4 + cinfo->num_components * 2 + num_quant_tables * 128; parasite_data = g_new (guchar, parasite_size); dest = parasite_data; *dest++ = CLAMP0255 (cinfo->jpeg_color_space); *dest++ = ABS (quality); *dest++ = CLAMP0255 (cinfo->num_components); *dest++ = num_quant_tables; for (i = 0; i < cinfo->num_components; i++) { *dest++ = CLAMP0255 (cinfo->comp_info[i].h_samp_factor); *dest++ = CLAMP0255 (cinfo->comp_info[i].v_samp_factor); } if (quality <= 0) { for (t = 0; t < 4; t++) if (cinfo->quant_tbl_ptrs[t]) for (i = 0; i < DCTSIZE2; i++) { guint16 c = cinfo->quant_tbl_ptrs[t]->quantval[i]; *dest++ = c / 256; *dest++ = c & 255; } } parasite = gimp_parasite_new ("jpeg-settings", GIMP_PARASITE_PERSISTENT, parasite_size, parasite_data); g_free (parasite_data); gimp_image_parasite_attach (image_ID, parasite); gimp_parasite_free (parasite); return TRUE; }
static void add_unknown_table (struct jpeg_decompress_struct *cinfo, gchar *filename) { guint32 hashval; GSList *list; QuantTableData *table_data; gint num_quant_tables; gint t; gint i; hashval = hash_quant_tables (cinfo); /* linear search - the number of unknown tables is usually very small */ for (list = found_tables; list; list = list->next) { table_data = list->data; if (table_data->hashval == hashval && table_data->subsmp_h == cinfo->comp_info[0].h_samp_factor && table_data->subsmp_v == cinfo->comp_info[0].v_samp_factor) { /* this unknown table has already been seen in previous files */ table_data->files = g_slist_prepend (table_data->files, filename); return; } } /* not found => new table */ table_data = g_new (QuantTableData, 1); table_data->hashval = hashval; table_data->subsmp_h = cinfo->comp_info[0].h_samp_factor; table_data->subsmp_v = cinfo->comp_info[0].v_samp_factor; num_quant_tables = 0; for (t = 0; t < 4; t++) if (cinfo->quant_tbl_ptrs[t]) num_quant_tables++; table_data->num_quant_tables = num_quant_tables; table_data->ijg_qual = jpeg_detect_quality (cinfo); table_data->files = g_slist_prepend (NULL, filename); if (cinfo->quant_tbl_ptrs[0]) { for (i = 0; i < DCTSIZE2; i++) table_data->luminance[i] = cinfo->quant_tbl_ptrs[0]->quantval[i]; } else { for (i = 0; i < DCTSIZE2; i++) table_data->luminance[i] = 0; } if (cinfo->quant_tbl_ptrs[1]) { for (i = 0; i < DCTSIZE2; i++) table_data->chrominance[i] = cinfo->quant_tbl_ptrs[1]->quantval[i]; } else { for (i = 0; i < DCTSIZE2; i++) table_data->chrominance[i] = 0; } found_tables = g_slist_prepend (found_tables, table_data); }