Blame lib/Xm/Jpeg.c

Packit b099d7
#include "JpegI.h"
Packit b099d7
#include <jerror.h>
Packit b099d7
#include <stdlib.h>
Packit b099d7
#include <X11/Intrinsic.h>
Packit b099d7
Packit b099d7
void
Packit b099d7
_XmJpegErrorExit(j_common_ptr cinfo)
Packit b099d7
{
Packit b099d7
    int rc;
Packit b099d7
    XmJpegErrorMgr err = (XmJpegErrorMgr) cinfo->err;
Packit b099d7
Packit b099d7
    switch (cinfo->err->msg_code) {
Packit b099d7
    case JERR_NO_SOI:
Packit b099d7
        rc = 1;
Packit b099d7
        break;
Packit b099d7
    case JERR_OUT_OF_MEMORY:
Packit b099d7
        rc = 4;
Packit b099d7
        break;
Packit b099d7
    default:
Packit b099d7
        rc = 2;
Packit b099d7
        break;
Packit b099d7
    }
Packit b099d7
    longjmp(err->setjmp_buffer, rc);
Packit b099d7
}
Packit b099d7
Packit b099d7
int
Packit b099d7
load_jpeg(FILE * infile, unsigned long *pWidth, unsigned long *pHeight,
Packit b099d7
          CTable ** image_data)
Packit b099d7
{
Packit b099d7
    CTable *buf;
Packit b099d7
    struct jpeg_decompress_struct cinfo;
Packit b099d7
    XmJpegErrorMgrRec jerr;
Packit b099d7
    JSAMPROW row_pointer[1];
Packit b099d7
    int x, y;
Packit b099d7
    int rc;
Packit b099d7
Packit b099d7
    *image_data = NULL;
Packit b099d7
    cinfo.err = jpeg_std_error((struct jpeg_error_mgr *) &jerr);
Packit b099d7
    jerr.pub.error_exit = _XmJpegErrorExit;
Packit b099d7
    if ((rc = setjmp(jerr.setjmp_buffer))) {
Packit b099d7
        jpeg_destroy_decompress(&cinfo);
Packit b099d7
        return rc;
Packit b099d7
    }
Packit b099d7
    jpeg_create_decompress(&cinfo);
Packit b099d7
    jpeg_stdio_src(&cinfo, infile);
Packit b099d7
    jpeg_read_header(&cinfo, TRUE);
Packit b099d7
    jpeg_calc_output_dimensions(&cinfo);
Packit b099d7
    jpeg_start_decompress(&cinfo);
Packit b099d7
    *pWidth = cinfo.output_width;
Packit b099d7
    *pHeight = cinfo.output_height;
Packit b099d7
    *image_data =
Packit b099d7
        malloc(cinfo.output_width * cinfo.output_height * sizeof(CTable));
Packit b099d7
    for (buf = *image_data;
Packit b099d7
         cinfo.output_scanline < cinfo.output_height;
Packit b099d7
         buf += cinfo.output_width)
Packit b099d7
        jpeg_read_scanlines(&cinfo, (JSAMPARRAY) (&buf), 1);
Packit b099d7
    if (cinfo.out_color_space == JCS_GRAYSCALE) {
Packit b099d7
        for (y = 0, buf = *image_data; y < cinfo.output_height;
Packit b099d7
             y++, buf += cinfo.output_width)
Packit b099d7
            for (x = cinfo.output_width - 1; x >= 0; x--)
Packit b099d7
                buf[x].red = buf[x].green = buf[x].blue =
Packit b099d7
                    ((JSAMPLE *) buf)[x];
Packit b099d7
    }
Packit b099d7
    jpeg_finish_decompress(&cinfo);
Packit b099d7
    jpeg_destroy_decompress(&cinfo);
Packit b099d7
    return 0;
Packit b099d7
}
Packit b099d7
Packit b099d7
Pixel
Packit b099d7
get_cval(unsigned char c, unsigned long mask)
Packit b099d7
{
Packit b099d7
    Pixel value = c, x;
Packit b099d7
    int i;
Packit b099d7
    for (i = 0, x = 1; i < 32; i++, x <<= 1)
Packit b099d7
        if (mask & x)
Packit b099d7
            break;
Packit b099d7
    for (; i < 32; i++, x <<= 1)
Packit b099d7
        if (!(mask & x))
Packit b099d7
            break;
Packit b099d7
    if (i < 8)
Packit b099d7
        value >>= 8 - i;
Packit b099d7
    else if (i > 8)
Packit b099d7
        value <<= i - 8;
Packit b099d7
    return (value & mask);
Packit b099d7
}
Packit b099d7
Packit b099d7
void
Packit b099d7
store_pixel(Screen * screen, CTable * p, int x, char *cdata)
Packit b099d7
{
Packit b099d7
    Pixel px = get_cval(p->red, screen->root_visual->red_mask)
Packit b099d7
        | get_cval(p->green, screen->root_visual->green_mask)
Packit b099d7
        | get_cval(p->blue, screen->root_visual->blue_mask);
Packit b099d7
    if (screen->root_depth <= 16) {
Packit b099d7
        if (ImageByteOrder(screen->display) == MSBFirst) {
Packit b099d7
            cdata[x * 2] = (px >> 8);
Packit b099d7
            cdata[x * 2 + 1] = (px & 0xff);
Packit b099d7
        } else {
Packit b099d7
            cdata[x * 2] = (px & 0xff);
Packit b099d7
            cdata[x * 2 + 1] = (px >> 8);
Packit b099d7
        }
Packit b099d7
    } else {
Packit b099d7
        if (ImageByteOrder(screen->display) == MSBFirst) {
Packit b099d7
            cdata[x * 4] = (px >> 24);
Packit b099d7
            cdata[x * 4 + 1] = (px >> 16);
Packit b099d7
            cdata[x * 4 + 2] = (px >> 8);
Packit b099d7
            cdata[x * 4 + 3] = (px & 0xff);
Packit b099d7
        } else {
Packit b099d7
            cdata[x * 4 + 3] = (px >> 24);
Packit b099d7
            cdata[x * 4 + 2] = (px >> 16);
Packit b099d7
            cdata[x * 4 + 1] = (px >> 8);
Packit b099d7
            cdata[x * 4] = (px & 0xff);
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
int
Packit b099d7
_XmJpegGetImage(Screen * screen, FILE * infile, XImage ** ximage)
Packit b099d7
{
Packit b099d7
    unsigned long image_width, image_height;
Packit b099d7
    unsigned char *xdata;
Packit b099d7
    int pad;
Packit b099d7
    CTable *image_data;
Packit b099d7
    int rc;
Packit b099d7
Packit b099d7
    if ((rc = load_jpeg(infile, &image_width, &image_height, &image_data)))
Packit b099d7
        return rc;
Packit b099d7
    if (screen->root_depth == 24 || screen->root_depth == 32) {
Packit b099d7
        xdata = (unsigned char *) malloc(4 * image_width * image_height);
Packit b099d7
        pad = 32;
Packit b099d7
    } else if (screen->root_depth == 16) {
Packit b099d7
        xdata = (unsigned char *) malloc(2 * image_width * image_height);
Packit b099d7
        pad = 16;
Packit b099d7
    } else {                    /* depth == 8 */
Packit b099d7
        xdata = (unsigned char *) malloc(image_width * image_height);
Packit b099d7
        pad = 8;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (!xdata) 
Packit b099d7
        return 4;
Packit b099d7
Packit b099d7
    *ximage =
Packit b099d7
        XCreateImage(screen->display, screen->root_visual,
Packit b099d7
                     screen->root_depth, ZPixmap, 0, (char *) xdata,
Packit b099d7
                     image_width, image_height, pad, 0);
Packit b099d7
    if (!*ximage) {
Packit b099d7
        free(xdata);
Packit b099d7
        return 4;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    {
Packit b099d7
        int xx, yy;
Packit b099d7
        CTable *p;
Packit b099d7
        for (yy = 0; yy < (*ximage)->height; yy++) {
Packit b099d7
            p = image_data + yy * (*ximage)->width;
Packit b099d7
            for (xx = 0; xx < (*ximage)->width; xx++, p++)
Packit b099d7
                store_pixel(screen, p, xx + yy * (*ximage)->width,
Packit b099d7
                            (*ximage)->data);
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (image_data) {
Packit b099d7
        free(image_data);
Packit b099d7
        image_data = NULL;
Packit b099d7
    }
Packit b099d7
    return 0;
Packit b099d7
}