js->rows_per_chunk = JPEG_OUTPUT_CHUNK_SIZE / img_header->widthBytes;
if(!img_header->widthBytes) return JPEG_ERROR; else js->rows_per_chunk = JPEG_OUTPUT_CHUNK_SIZE / img_header->widthBytes;
il_jpeg_write(il_container *ic, const unsigned char *buf, int32 len){	int row_stride, status;	int input_exhausted;  int error_code;	jpeg_struct *js = (jpeg_struct *)ic->ds;       /* If this js == NULL, chances are the netlib        continued to send data after the image stream was closed. */    if (!js) {#ifdef DEBUG        ILTRACE(1,("Netlib sent data after the image stream was closed\n"));#endif        return MK_IMAGE_LOSSAGE;    }	j_decompress_ptr jd = &js->jd;    il_source_mgr *src = (il_source_mgr*) js->jd.src;    NI_PixmapHeader *img_header = &ic->image->header;#ifndef M12N                    /* XXXM12N Get rid of this */    NI_PixmapHeader *src_header = ic->src_header;    NI_ColorMap *cmap = &src_header->color_space->cmap;#endif /* M12N */	/* Return here if there is a fatal error. */	if ((error_code = setjmp(js->jerr.setjmp_buffer)) != 0) {        /* Free up all the data structures */        il_jpeg_abort(ic);		return error_code;	}	/* Register new buffer contents with data source manager. */	src->netlib_buffer = (JOCTET*)buf;	src->netlib_buflen = (uint32)len;    input_exhausted = 0;	while (! input_exhausted) {		ILTRACE(5,("il:jpeg: write, state=%d, buf=0x%x, len=%d",				   js->state, buf, len));		switch (js->state) {		case JPEG_HEADER:			if (jpeg_read_header(jd, TRUE) != JPEG_SUSPENDED) {#ifndef M12N                    /* XXXM12N Get rid of this */				cmap->map = 0;				cmap->num_colors = ic->cs->default_map_size;#endif /* M12N */                ic->src_header->width = jd->image_width;                ic->src_header->height = jd->image_height;				if ((status = ic->imgdcb->ImgDCBImageSize()) != 0) {					ILTRACE(1,("il:jpeg: MEM il_size"));					return status;				}                ic->imgdcb->ImgDCBSetupColorspaceConverter(); /* XXXM12N Should check                                                       return code. */                js->rows_per_chunk =                    JPEG_OUTPUT_CHUNK_SIZE / img_header->widthBytes;				/* FIXME -- Should reset dct_method and dither mode				 * for final pass of progressive JPEG				 */				jd->dct_method = JDCT_FASTEST;				jd->dither_mode = JDITHER_ORDERED;				jd->do_fancy_upsampling = FALSE;				jd->enable_2pass_quant = FALSE;				jd->do_block_smoothing = TRUE;								/*				 * Don't allocate a giant and superfluous memory buffer				 * when the image is a sequential JPEG.				 */				jd->buffered_image = jpeg_has_multiple_scans(jd);				/* Used to set up image size so arrays can be allocated */				jpeg_calc_output_dimensions(jd);				/*				 * Make a one-row-high sample array that will go away				 * when done with image. Always make it big enough to				 * hold an RGB row.	 Since this uses the IJG memory				 * manager, it must be allocated before the call to				 * jpeg_start_compress().				 */				row_stride = jd->output_width * jd->output_components;				js->samples = (*jd->mem->alloc_sarray)((j_common_ptr) jd,													   JPOOL_IMAGE,													   row_stride, 1);				/* Allocate RGB buffer for conversion from greyscale. */				if (jd->output_components != 3) {					row_stride = jd->output_width * 3;					js->samples3 = (*jd->mem->alloc_sarray)((j_common_ptr) jd,															JPOOL_IMAGE,															row_stride, 1);				}                js->state = JPEG_START_DECOMPRESS;			} else {				ILTRACE(5,("il:jpeg: suspending header"));				input_exhausted = TRUE;			}			break;        case JPEG_START_DECOMPRESS:            if (jpeg_start_decompress(jd)) {                /* If this is a progressive JPEG ... */                if (jd->buffered_image) {                    js->state = JPEG_DECOMPRESS_PROGRESSIVE;                } else {                    js->state = JPEG_DECOMPRESS_SEQUENTIAL;                }            }                               break;        case JPEG_DECOMPRESS_SEQUENTIAL:            input_exhausted = output_jpeg_scanlines(ic, -1);			/* If we've completed image output ... */			if (jd->output_scanline == jd->output_height)                js->state = JPEG_DONE;            break;            		case JPEG_DECOMPRESS_PROGRESSIVE:            /*             * Set a timeout to trigger display of the next progressive scan.             * Any scans which arrive in the intervening time will be displayed             * instead.  Thus, the decoder adapts to the data arrival rate.             */            if (js->timeout == NULL) {                uint32 delay;                /*                 * First time around, display the scan a little                 * quicker than in subsequent scans.                 */                if (jd->input_scan_number == 1)                    delay = JPEG_TIMEOUT_INITIAL_DELAY;                else {                    delay = JPEG_TIMEOUT_DELAY;                }                                js->timeout = ic->imgdcb->ImgDCBSetTimeout(jpeg_timeout_callback, js, delay);                        }            /* Eat all the available input data in the netlib buffer. */            do {                status = jpeg_consume_input(jd);            } while (!((status == JPEG_SUSPENDED) ||                       (status == JPEG_REACHED_EOI)));            /* If we've parsed the whole input, do final display immediately. */            if (status == JPEG_REACHED_EOI) {                js->state = JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT;                break;            }                        input_exhausted = TRUE;            			break;		case JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT:            if ((jd->input_scan_number == jd->output_scan_number) &&                (js->pass_num == js->completed_output_passes + 1)) {                output_jpeg_scanlines(ic, -1);                jpeg_finish_output(jd);            } else {                /* Abort the last output scan.                 * We need to redraw the whole image.                 */                if (js->pass_num == js->completed_output_passes + 1)                    jpeg_finish_output(jd);                jpeg_start_output(jd, jd->input_scan_number);                output_jpeg_scanlines(ic, -1);                jpeg_finish_output(jd);            }            js->state = JPEG_DONE;            /* Fall through ... */        case JPEG_DONE:			status = jpeg_finish_decompress(jd);                        /* Clear any pending timeouts */            if (js->timeout) {                ic->imgdcb->ImgDCBClearTimeout(js->timeout);                js->timeout = NULL;            }			input_exhausted = TRUE;            js->state = JPEG_SINK_NON_JPEG_TRAILER;  /* Be prepared for     */                                                     /* non-JPEG data after */                                                     /* EOI marker.         */            break;        case JPEG_SINK_NON_JPEG_TRAILER: /* Ignore non-JPEG trailer, if any */            input_exhausted = TRUE;            break;		default:			PR_ASSERT(0);			break;		}	}	return 0;}