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.