+
+ if (cinfo.output_scanline < cinfo.output_height)
+ /* don't goto FAIL -- we might have viewable partial data. */
+ jpeg_abort_decompress (&cinfo);
+ else
+ jpeg_finish_decompress (&cinfo);
+
+ jpeg_destroy_decompress (&cinfo);
+ fclose (in);
+ in = 0;
+
+ return ximage;
+
+ FAIL:
+ if (in) fclose (in);
+ if (ximage && ximage->data)
+ {
+ free (ximage->data);
+ ximage->data = 0;
+ }
+ if (ximage) XDestroyImage (ximage);
+ if (scanbuf) free (scanbuf);
+ return 0;
+}
+
+
+/* Scales an XImage, modifying it in place.
+ If out of memory, returns False, and the XImage will have been
+ destroyed and freed.
+ */
+static Bool
+scale_ximage (Screen *screen, Visual *visual,
+ XImage *ximage, int new_width, int new_height)
+{
+ Display *dpy = DisplayOfScreen (screen);
+ int depth = visual_depth (screen, visual);
+ int x, y;
+ double xscale, yscale;
+
+ XImage *ximage2 = XCreateImage (dpy, visual, depth,
+ ZPixmap, 0, 0,
+ new_width, new_height, 8, 0);
+ ximage2->data = (char *) calloc (ximage2->height, ximage2->bytes_per_line);
+
+ if (!ximage2->data)
+ {
+ fprintf (stderr, "%s: out of memory scaling %dx%d image to %dx%d\n",
+ progname,
+ ximage->width, ximage->height,
+ ximage2->width, ximage2->height);
+ if (ximage->data) free (ximage->data);
+ if (ximage2->data) free (ximage2->data);
+ ximage->data = 0;
+ ximage2->data = 0;
+ XDestroyImage (ximage);
+ XDestroyImage (ximage2);
+ return False;
+ }
+
+ /* Brute force scaling... */
+ xscale = (double) ximage->width / ximage2->width;
+ yscale = (double) ximage->height / ximage2->height;
+ for (y = 0; y < ximage2->height; y++)
+ for (x = 0; x < ximage2->width; x++)
+ XPutPixel (ximage2, x, y,
+ XGetPixel (ximage, x * xscale, y * yscale));
+
+ free (ximage->data);
+ ximage->data = 0;
+
+ (*ximage) = (*ximage2);
+
+ ximage2->data = 0;
+ XDestroyImage (ximage2);
+
+ return True;
+}
+
+
+/* Reads the given image file and renders it on the Drawable, using JPEG lib.
+ Returns False if it fails.
+ */
+static Bool
+read_file_jpeglib (Screen *screen, Window window, Drawable drawable,
+ const char *filename, Bool verbose_p)
+{
+ Display *dpy = DisplayOfScreen (screen);
+ XImage *ximage;
+ Visual *visual;
+ int class, depth;
+ Colormap cmap;
+ unsigned int win_width, win_height, win_depth;
+ int srcx, srcy, destx, desty, w2, h2;
+
+ /* Find the size of the Drawable, and the Visual/Colormap of the Window. */
+ {
+ Window root;
+ int x, y;
+ unsigned int bw;
+ XWindowAttributes xgwa;
+ XGetWindowAttributes (dpy, window, &xgwa);
+ visual = xgwa.visual;
+ cmap = xgwa.colormap;
+ XGetGeometry (dpy, drawable,
+ &root, &x, &y, &win_width, &win_height, &bw, &win_depth);
+ }
+
+ /* Make sure we're not on some weirdo visual...
+ */
+ class = visual_class (screen, visual);
+ depth = visual_depth (screen, visual);
+ if ((class == PseudoColor || class == DirectColor) &&
+ (depth != 8 && depth != 12))