This is nxJfif.c in view mode; [Download] [Up]
/* write_jfif() converts NeXT raster bitmaps into a JPEG stream. * front end to Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. */ /* * Include file for declaring JPEG data structures. * This file also includes some system headers like <stdio.h>; * if you prefer, you can include "jconfig.h" and "jpegdata.h" instead. */ #include <c.h> #include <libc.h> #include "jinclude.h" #include <streams/streams.h> static unsigned char *ptr; static int alpha; static int delta; static void no_op(compress_info_ptr cinfo) { } static void get_input_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row) /* Read next row of pixels into pixel_row[][] */ { register JSAMPROW ptr0, ptr1, ptr2; register long col; if (cinfo->input_components == 1 && alpha == 0) { // grayscale no alpha bcopy(ptr, pixel_row[0], cinfo->image_width); ptr += cinfo->image_width + delta; return; } else if (cinfo->input_components == 3) { // color with or without alpha ptr0 = pixel_row[0]; ptr1 = pixel_row[1]; ptr2 = pixel_row[2]; for (col = 0; col < cinfo->image_width; col++) { *ptr0++ = (JSAMPLE) *ptr++; /* red */ *ptr1++ = (JSAMPLE) *ptr++; /* green */ *ptr2++ = (JSAMPLE) *ptr++; /* blue */ if (alpha) { ++ptr; } } ptr += delta; return; } else if (cinfo->input_components == 1 && alpha == 1) { // grayscale and alpha ptr0 = pixel_row[0]; for (col = 0; col < cinfo->image_width; col++) { *ptr0++ = (JSAMPLE) *ptr; ptr += 2; } ptr += delta; return; } else { fprintf(stderr, "%d is illegal number of color components.\n", cinfo->input_components); exit(-1); } } /* * This routine must determine what output JPEG file format is to be written, * and make any other compression parameter changes that are desirable. * This routine gets control after the input file header has been read * (i.e., right after input_init has been called). You could combine its * functions into input_init, or even into the main control routine, but * if you have several different input_init routines, it's a definite win * to keep this separate. You MUST supply this routine even if it's a no-op. */ static void c_ui_method_selection (compress_info_ptr cinfo) { /* If the input is gray scale, generate a monochrome JPEG file. */ if (cinfo->in_color_space == CS_GRAYSCALE) j_monochrome_default(cinfo); /* For now, always select JFIF output format. */ jselwjfif(cinfo); } /* write_jfif() is used to convert a NeXT bitmap into a JPEG stream. * It can handle bitmaps with 8 bits per sample only. bpp can be used * to specify the presence of the aplpha component and bytesPerRow can * be used specify the presence of row padding. */ void write_jfif(NXStream *stream, unsigned char *data, int width, int height, int spp, int bps, int bpp, int bytesPerRow, int quality) { /* These three structs contain JPEG parameters and working data. * They must survive for the duration of parameter setup and one * call to jpeg_compress; typically, making them local data in the * calling routine is the best strategy. */ struct compress_info_struct cinfo; struct compress_methods_struct c_methods; struct external_methods_struct e_methods; cinfo.image_width = width; /* width in pixels */ cinfo.image_height = height; /* height in pixels */ cinfo.input_components = spp; /* or 1 for grayscale */ if (spp == 3 || spp == 4) { spp = 3; cinfo.in_color_space = CS_RGB; /* or CS_GRAYSCALE for grayscale */ } else if (spp == 1 || spp == 2) { spp = 1; cinfo.in_color_space = CS_GRAYSCALE; } else { fprintf(stderr, "%d is illegal for samples/pixel.\n", spp); exit(-1); } if (bps != 8) { fprintf(stderr, "%d is illegal for bits/samples.\n", bps); } cinfo.data_precision = bps; /* bits per pixel component value */ alpha = (bpp - spp * bps) / 8; /* take care of alpha component */ delta = bytesPerRow - (bpp * width) / 8; /* take care of row fill bytes */ /* Initialize the system-dependent method pointers. */ cinfo.methods = &c_methods; /* links to method structs */ cinfo.emethods = &e_methods; /* Here we use the default JPEG error handler, which will just print * an error message on stderr and call exit(). See the second half of * this file for an example of more graceful error recovery. */ jselerror(&e_methods); /* select std error/trace message routines */ /* Here we use the standard memory manager provided with the JPEG code. * In some cases you might want to replace the memory manager, or at * least the system-dependent part of it, with your own code. */ jselmemmgr(&e_methods); /* select std memory allocation routines */ /* If the compressor requires full-image buffers (for entropy-coding * optimization or a noninterleaved JPEG file), it will create temporary * files for anything that doesn't fit within the maximum-memory setting. * (Note that temp files are NOT needed if you use the default parameters.) * You can change the default maximum-memory setting by changing * e_methods.max_memory_to_use after jselmemmgr returns. * On some systems you may also need to set up a signal handler to * ensure that temporary files are deleted if the program is interrupted. * (This is most important if you are on MS-DOS and use the jmemdos.c * memory manager back end; it will try to grab extended memory for * temp files, and that space will NOT be freed automatically.) * See jcmain.c or jdmain.c for an example signal handler. */ /* Here, set up pointers to your own routines for input data handling * and post-init parameter selection. */ c_methods.input_init = no_op; c_methods.get_input_row = get_input_row; c_methods.input_term = no_op; c_methods.c_ui_method_selection = c_ui_method_selection; /* Set up default JPEG parameters in the cinfo data structure. */ j_c_defaults(&cinfo, quality, FALSE); /* Note: 75 is the recommended default quality level; you may instead pass * a user-specified quality level. Be aware that values below 25 will cause * non-baseline JPEG files to be created (and a warning message to that * effect to be emitted on stderr). This won't bother our decoder, but some * commercial JPEG implementations may choke on non-baseline JPEG files. * If you want to force baseline compatibility, pass TRUE instead of FALSE. * (If non-baseline files are fine, but you could do without that warning * message, set e_methods.trace_level to -1.) */ /* At this point you can modify the default parameters set by j_c_defaults * as needed. For a minimal implementation, you shouldn't need to change * anything. See jcmain.c for some examples of what you might change. */ cinfo.input_file = NULL; /* if no actual input file involved */ cinfo.output_file = stream; ptr = data; jpeg_compress(&cinfo); /* Note: if you want to compress more than one image, we recommend you * repeat this whole routine. You MUST repeat the j_c_defaults()/alter * parameters/jpeg_compress() sequence, as some data structures allocated * in j_c_defaults are freed upon exit from jpeg_compress. */ }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.