home *** CD-ROM | disk | FTP | other *** search
- /*
- * xvjpeg.c - i/o routines for 'jpeg' format pictures
- *
- * LoadJFIF(fname, numcols) - loads a JPEG pic, does 24to8 code if nec.
- * WriteJFIF(fp, pic, w, h, rmap, gmap, bmap, numcols, colorstyle)
- */
-
- /*
- * LoadJFIF Author: Markus Baur, University of Karlsruhe
- * (s_baur@iravcl.ira.uka.de)
- * This software is provided "as is" without any express or implied warranty.
- */
-
- /* WriteJFIF() and JPEG dialog routines written by John Bradley */
-
- /*
- * Portions Copyright 1989, 1990, 1991, 1992 by John Bradley and
- * The University of Pennsylvania
- *
- * Permission to use, copy, and distribute for non-commercial purposes,
- * is hereby granted without fee, providing that the above copyright
- * notice appear in all copies and that both the copyright notice and this
- * permission notice appear in supporting documentation.
- *
- * The software may be modified for your own purposes, but modified versions
- * may not be distributed.
- *
- * This software is provided "as is" without any expressed or implied warranty.
- *
- * The author may be contacted via:
- * US Mail: John Bradley
- * GRASP Lab, Room 301C
- * 3401 Walnut St.
- * Philadelphia, PA 19104
- *
- * Phone: (215) 898-8813
- * EMail: bradley@cis.upenn.edu
- */
-
-
- #include "xvimage.h"
- #include "xvjinclude.h"
- #include <setjmp.h>
-
-
- /**** Stuff for JPEGDialog box ****/
-
- #define JWIDE 280
- #define JHIGH 160
- #define J_NBUTTS 2
- #define J_BOK 0
- #define J_BCANC 1
- #define BUTTH 24
-
- #ifdef __STDC__
- static void writeJPEG(void);
- #else
- static void drawJD(), doCmd(), clickJD(), writeJPEG();
- #endif
- static void jselwxv();
- static int writeJFIF();
-
-
- /* local variables */
- static char *filename;
- static int colorType;
- static byte *image8, *image24;
-
- static byte *CurImagePtr;
- static byte *pic24;
- static long filesize;
- static jmp_buf jmpState;
- static struct external_methods_struct e_methods;
-
-
- /*********************************************/
- /**** INTERFACE CODE FOR THE JPEG LIBRARY ****/
- /*********************************************/
-
-
-
- /********* JPEG DECOMPRESSION FUNCTIONS **********/
-
- /**************************************************/
- static void xv_jpeg_monitor(cinfo, loopcnt, looplimit)
- decompress_info_ptr cinfo;
- long loopcnt, looplimit;
- {
- int a,b;
- double percent;
-
- #ifdef FOO
- a = cinfo->completed_passes;
- b = cinfo->total_passes;
-
- percent = ((a + ((double) loopcnt / looplimit)) / (double) b) * 100.0;
-
- fprintf(stderr,"jpeg: %lf done. loop: %ld, %ld pass: %d, %d\n",
- percent, loopcnt, looplimit, a, b);
- #endif
- }
-
-
- /**************************************************/
- static void d_ui_method_selection(cinfo)
- decompress_info_ptr cinfo;
- {
- int i;
-
- /* select output colorspace & quantization parameters */
- if (cinfo->jpeg_color_space == CS_GRAYSCALE) {
- cinfo->out_color_space = CS_GRAYSCALE;
- cinfo->quantize_colors = FALSE;
- printf("Greyscale JPEG. (%ld bytes)\n", filesize);
- /* fill in a greyscale colormap */
- for (i=0; i<=255; i++)
- r[i] = g[i] = b[i] = i;
- }
-
- else {
- cinfo->out_color_space = CS_RGB;
-
- if (conv24 == CONV24_FAST || conv24 == CONV24_SLOW)
- cinfo->quantize_colors = TRUE;
- else cinfo->quantize_colors = FALSE;
-
- if (conv24 != CONV24_FAST) cinfo->two_pass_quantize = TRUE;
- else {
- cinfo->two_pass_quantize = FALSE;
- /* For the 1-pass quantizer it's best to use 256 colors and let */
- /* the cmap sorter pick up any slack. This produces essentially */
- /* the same results as xv's usual fast quantizer, but it reduces */
- /* swapping since no 24-bit copy of the image is needed. */
- cinfo->desired_number_of_colors = 256;
- }
- printf("Color JPEG. (%ld bytes)\n", filesize);
- }
-
- jselwxv(cinfo);
- }
-
-
- /**************************************************/
- static void output_init (cinfo)
- decompress_info_ptr cinfo;
- {
- pWIDE = cinfo->image_width;
- pHIGH = cinfo->image_height;
-
- if (cinfo->out_color_space == CS_GRAYSCALE ||
- cinfo->quantize_colors == TRUE) {
- pic = (byte *) malloc(pWIDE * pHIGH);
- if (!pic) FatalError("Not enough memory for Image");
- CurImagePtr = pic;
- }
-
- else {
- pic24 = (byte *) malloc(pWIDE * pHIGH * 3);
- if (!pic24) FatalError("Not enough memory for Image");
- CurImagePtr = pic24;
- }
- }
-
-
- /**************************************************/
- static void put_color_map (cinfo, num_colors, colormap)
- decompress_info_ptr cinfo;
- int num_colors;
- JSAMPARRAY colormap;
- {
- int i;
-
- for (i = 0; i < num_colors; i++) {
- r[i] = GETJSAMPLE(colormap[0][i]);
- g[i] = GETJSAMPLE(colormap[1][i]);
- b[i] = GETJSAMPLE(colormap[2][i]);
- }
- }
-
-
- /**************************************************/
- static void put_pixel_rows (cinfo, num_rows, pixel_data)
- decompress_info_ptr cinfo;
- int num_rows;
- JSAMPIMAGE pixel_data;
- {
- JSAMPROW ptr0, ptr1, ptr2;
- long col;
- long width = cinfo->image_width;
- int row;
- static unsigned int totrows = 0;
-
- if (cinfo->out_color_space == CS_GRAYSCALE ||
- cinfo->quantize_colors == TRUE) {
-
- for (row = 0; row < num_rows; row++) {
- ptr0 = pixel_data[0][row];
- for (col = width; col > 0; col--) {
- *CurImagePtr++ = GETJSAMPLE(*ptr0++);
- }
- totrows++;
- }
- }
-
- else {
- for (row = 0; row < num_rows; row++) {
- ptr0 = pixel_data[0][row];
- ptr1 = pixel_data[1][row];
- ptr2 = pixel_data[2][row];
- for (col = width; col > 0; col--) {
- *CurImagePtr++ = GETJSAMPLE(*ptr0++);
- *CurImagePtr++ = GETJSAMPLE(*ptr1++);
- *CurImagePtr++ = GETJSAMPLE(*ptr2++);
- }
- totrows++;
- }
- }
- }
-
-
- /**************************************************/
- static void output_term (cinfo)
- decompress_info_ptr cinfo;
- {
- /* no work required */
- }
-
-
- /**************************************************/
- static void jselwxv(cinfo)
- decompress_info_ptr cinfo;
- {
- cinfo->methods->output_init = output_init;
- cinfo->methods->put_color_map = put_color_map;
- cinfo->methods->put_pixel_rows = put_pixel_rows;
- cinfo->methods->output_term = output_term;
- }
-
-
- /**************************************************/
- static void JPEG_Message (msgtext)
- char *msgtext;
- {
- char tempstr[200];
-
- sprintf(tempstr, msgtext,
- e_methods.message_parm[0], e_methods.message_parm[1],
- e_methods.message_parm[2], e_methods.message_parm[3],
- e_methods.message_parm[4], e_methods.message_parm[5],
- e_methods.message_parm[6], e_methods.message_parm[7]);
- printf("%s\n", tempstr);
- }
-
-
- /**************************************************/
- static void JPEG_Error (msgtext)
- char *msgtext;
- {
- char tempstr[200];
-
- sprintf(tempstr, msgtext,
- e_methods.message_parm[0], e_methods.message_parm[1],
- e_methods.message_parm[2], e_methods.message_parm[3],
- e_methods.message_parm[4], e_methods.message_parm[5],
- e_methods.message_parm[6], e_methods.message_parm[7]);
- printf("%s\n", tempstr);
- longjmp(jmpState,1);
- }
-
-
- /*******************************************/
- int LoadJFIF(fname,nc)
- char *fname;
- int nc;
- /*******************************************/
- {
- int rtval;
- struct decompress_info_struct cinfo;
- struct decompress_methods_struct dc_methods;
-
- /* Set up the input file */
-
- if ((cinfo.input_file = fopen(fname, "r")) == NULL) return 1;
-
- /* figure out the file size (for Informational Purposes Only) */
- fseek(cinfo.input_file, 0L, 2);
- filesize = ftell(cinfo.input_file);
- fseek(cinfo.input_file, 0L, 0);
-
- cinfo.output_file = NULL; /* only wanna read */
-
- pic24 = (byte *) NULL;
-
- /* Set up longjmp for error recovery out of JPEG_Error */
- rtval = setjmp(jmpState);
- if (rtval) {
- fclose(cinfo.input_file); /* close input file */
- return rtval; /* no further cleanup needed */
- }
-
- /* Initialize the system-dependent method pointers. */
- cinfo.methods = &dc_methods;
- cinfo.emethods = &e_methods;
- e_methods.error_exit = JPEG_Error; /* provide my own error/message rtns */
- e_methods.trace_message = JPEG_Message;
- e_methods.trace_level = 0; /* no tracing, thank you */
- jselmemmgr(&e_methods); /* memory allocation routines */
- dc_methods.d_ui_method_selection = d_ui_method_selection;
-
- /* Set up default JPEG parameters. */
- j_d_defaults(&cinfo, TRUE);
- /* the jpeg quantizer can't handle small values of 'nc' */
- cinfo.desired_number_of_colors = (nc<16) ? 255 : nc;
-
- /* set up our progress-monitoring function */
- /* cinfo.methods->progress_monitor = xv_jpeg_monitor; */
-
- /* Set up to read a JFIF or baseline-JPEG file. */
- /* A smarter UI would inspect the first few bytes of the input file */
- /* to determine its type. */
- jselrjfif(&cinfo);
-
- /* Do it! */
- jpeg_decompress(&cinfo);
-
- if (pic24) {
- /* call XV's quantizer */
- Conv24to8(pic24, pWIDE, pHIGH, nc);
- free(pic24);
- }
-
- /* Close input file */
- fclose(cinfo.input_file);
-
- sprintf(formatStr, "%dx%d %s JPEG. ", cinfo.image_width, cinfo.image_height,
- (cinfo.out_color_space == CS_GRAYSCALE) ? "Greyscale " : "Color ");
-
- /* Got it! */
- return 0;
- }
-
-
-
-
-
-
- /********* JPEG COMPRESSION FUNCTIONS **********/
-
-
- /**************************************************/
- static void c_ui_method_selection(cinfo)
- compress_info_ptr cinfo;
- {
- /* select output colorspace */
- if (colorType == F_GREYSCALE) {
- j_monochrome_default(cinfo);
- }
- }
-
-
- /**************************************************/
- static void input_init (cinfo)
- compress_info_ptr cinfo;
- {
- int w,h;
-
- if (colorType == F_GREYSCALE) {
- cinfo->input_components = 1;
- cinfo->in_color_space = CS_GRAYSCALE;
- CurImagePtr = image8;
- }
-
- else {
- cinfo->input_components = 3;
- cinfo->in_color_space = CS_RGB;
- CurImagePtr = image24;
- }
-
- /*
- if (savenormCB.val) { w = cWIDE; h = cHIGH; }
- else { w = eWIDE; h = eHIGH; }
- */
- cinfo->image_width = w;
- cinfo->image_height = h;
- cinfo->data_precision = 8;
- }
-
-
- /**************************************************/
- static void get_input_row(cinfo, pixel_row)
- compress_info_ptr cinfo;
- JSAMPARRAY pixel_row;
- {
- JSAMPROW ptr0, ptr1, ptr2;
- long col;
- static unsigned int totrows = 0;
-
- if (cinfo->input_components == 1) {
- ptr0 = pixel_row[0];
- for (col = cinfo->image_width; col > 0; col--) {
- *ptr0++ = *CurImagePtr++;
- }
- totrows++;
- }
-
- else {
- ptr0 = pixel_row[0];
- ptr1 = pixel_row[1];
- ptr2 = pixel_row[2];
- for (col = cinfo->image_width; col > 0; col--) {
- *ptr0++ = *CurImagePtr++;
- *ptr1++ = *CurImagePtr++;
- *ptr2++ = *CurImagePtr++;
- }
- totrows++;
- }
- }
-
-
- /**************************************************/
- static void input_term (cinfo)
- compress_info_ptr cinfo;
- {
- /* no work required */
- }
-
-
- /**************************************************/
- static void jselrxv(cinfo)
- compress_info_ptr cinfo;
- {
- cinfo->methods->input_init = input_init;
- cinfo->methods->get_input_row = get_input_row;
- cinfo->methods->input_term = input_term;
- }
-
-