#include #include #include #include #include #include "jpeglib.h" struct my_errmgr { struct jpeg_error_mgr pub; sigjmp_buf jmp; const char *fname; }; typedef struct my_errmgr *my_errmgr_p; METHODDEF (void) my_output_message (j_common_ptr cinfo) { my_errmgr_p err = (my_errmgr_p) cinfo->err; char buffer[JMSG_LENGTH_MAX]; (*cinfo->err->format_message) (cinfo, buffer); fprintf (stderr, "%s: %s: %s\n", program_invocation_short_name, err->fname, buffer); } METHODDEF (void) my_error_exit (j_common_ptr cinfo) { my_errmgr_p err = (my_errmgr_p) cinfo->err; my_output_message (cinfo); siglongjmp (err->jmp, 1); } #define last_element(array) (sizeof ((array)) / sizeof (*(array)) - 1) int display_file (const char *fname) { struct jpeg_decompress_struct cinfo; struct my_errmgr jerr; FILE *fp; int header; if (!(fp = fopen (fname, "rb"))) { fprintf (stderr, "%s: %s: %s\n", program_invocation_short_name, fname, strerror (errno)); return EXIT_FAILURE; } jerr.fname = fname; cinfo.err = jpeg_std_error (&jerr.pub); jerr.pub.error_exit = my_error_exit; jerr.pub.output_message = my_output_message; if (setjmp (jerr.jmp)) { jpeg_destroy_decompress (&cinfo); fclose (fp); return EXIT_FAILURE; } jpeg_create_decompress (&cinfo); jpeg_stdio_src (&cinfo, fp); header = jpeg_read_header (&cinfo, FALSE); printf ("%s:\n", fname); printf (" Datastream type: %s\n", (header == JPEG_HEADER_TABLES_ONLY) ? "abbreviated" : "image"); printf (" Image width: %u\n", (unsigned) cinfo.image_width); printf (" Image height: %u\n", (unsigned) cinfo.image_height); unsigned jpeg_color_space = cinfo.jpeg_color_space; const char *colorspace[] = { "unspecified", "monochrome", "R/G/B", "Y/Cb/Cr", "C/M/Y/K", "Y/Cb/Cr/K", "unrecognized" }; if (jpeg_color_space > last_element (colorspace)) jpeg_color_space = last_element (colorspace); printf (" Image colorspace: %d (%s)\n", cinfo.jpeg_color_space, colorspace[jpeg_color_space]); printf (" Number of color components: %d\n", cinfo.num_components); if (cinfo.saw_JFIF_marker) { unsigned density_unit = cinfo.density_unit; const char *density[] = { "", " dots/inch", " dots/cm", " units" }; if (density_unit > last_element (density)) density_unit = last_element (density); printf (" JFIF version: %u.%u\n", (unsigned) cinfo.JFIF_major_version, (unsigned) cinfo.JFIF_minor_version); printf (" X density: %u%s\n", (unsigned) cinfo.X_density, density[density_unit]); printf (" Y density: %u%s\n", (unsigned) cinfo.Y_density, density[density_unit]); } if (cinfo.saw_Adobe_marker) { printf (" Adobe_transform: %u\n", (unsigned) cinfo.Adobe_transform); } jpeg_destroy_decompress (&cinfo); fclose (fp); return EXIT_SUCCESS; } int main (int ac, const char **av) { int rc = EXIT_SUCCESS, i; for (i = 1; i < ac; ++i) rc |= display_file (av[i]); return rc; }