170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * rdrle.c 370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Copyright (C) 1991-1996, Thomas G. Lane. 570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file is part of the Independent JPEG Group's software. 670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * For conditions of distribution and use, see the accompanying README file. 770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file contains routines to read input images in Utah RLE format. 970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * The Utah Raster Toolkit library is required (version 3.1 or later). 1070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 1170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * These routines may need modification for non-Unix environments or 1270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * specialized applications. As they stand, they assume input from 1370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * an ordinary stdio stream. They further assume that reading begins 1470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * at the start of the file; start_input may need work if the 1570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * user interface has already read some data (e.g., to determine that 1670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * the file is indeed RLE format). 1770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 1870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Based on code contributed by Mike Lijewski, 1970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * with updates from Robert Hutchinson. 2070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 2170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ 2370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef RLE_SUPPORTED 2570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* rle.h is provided by the Utah Raster Toolkit. */ 2770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include <rle.h> 2970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 3070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 3170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * We assume that JSAMPLE has the same representation as rle_pixel, 3270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples. 3370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 3470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 3570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#if BITS_IN_JSAMPLE != 8 3670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ 3770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 3870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 3970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 4070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * We support the following types of RLE files: 4170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 4270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * GRAYSCALE - 8 bits, no colormap 4370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * MAPPEDGRAY - 8 bits, 1 channel colomap 4470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * PSEUDOCOLOR - 8 bits, 3 channel colormap 4570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * TRUECOLOR - 24 bits, 3 channel colormap 4670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * DIRECTCOLOR - 24 bits, no colormap 4770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 4870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * For now, we ignore any alpha channel in the image. 4970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 5070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 5170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef enum 5270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine { GRAYSCALE, MAPPEDGRAY, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind; 5370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 5470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 5570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 5670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Since RLE stores scanlines bottom-to-top, we have to invert the image 5770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * to conform to JPEG's top-to-bottom order. To do this, we read the 5870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * incoming image into a virtual array on the first get_pixel_rows call, 5970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * then fetch the required row from the virtual array on subsequent calls. 6070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 6170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef struct _rle_source_struct * rle_source_ptr; 6370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef struct _rle_source_struct { 6570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine struct cjpeg_source_struct pub; /* public fields */ 6670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_kind visual; /* actual type of input file */ 6870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_sarray_ptr image; /* virtual array to hold the image */ 6970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION row; /* current row # in the virtual array */ 7070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_hdr header; /* Input file information */ 7170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_pixel** rle_row; /* holds a row returned by rle_getrow() */ 7270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 7370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} rle_source_struct; 7470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 7570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 7670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 7770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Read the file header; return image size and component count. 7870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 7970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 8070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 8170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestart_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 8270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 8370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_source_ptr source = (rle_source_ptr) sinfo; 8470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION width, height; 8570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef PROGRESS_REPORT 8670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; 8770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 8870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 8970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Use RLE library routine to get the header info */ 9070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->header = *rle_hdr_init(NULL); 9170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->header.rle_file = source->pub.input_file; 9270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine switch (rle_get_setup(&(source->header))) { 9370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case RLE_SUCCESS: 9470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* A-OK */ 9570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 9670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case RLE_NOT_RLE: 9770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ERREXIT(cinfo, JERR_RLE_NOT); 9870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 9970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case RLE_NO_SPACE: 10070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ERREXIT(cinfo, JERR_RLE_MEM); 10170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 10270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case RLE_EMPTY: 10370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ERREXIT(cinfo, JERR_RLE_EMPTY); 10470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 10570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case RLE_EOF: 10670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ERREXIT(cinfo, JERR_RLE_EOF); 10770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 10870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine default: 10970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ERREXIT(cinfo, JERR_RLE_BADERROR); 11070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 11170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 11270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 11370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Figure out what we have, set private vars and return values accordingly */ 11470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 11570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine width = source->header.xmax - source->header.xmin + 1; 11670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine height = source->header.ymax - source->header.ymin + 1; 11770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->header.xmin = 0; /* realign horizontally */ 11870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->header.xmax = width-1; 11970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 12070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->image_width = width; 12170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->image_height = height; 12270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->data_precision = 8; /* we can only handle 8 bit data */ 12370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 12470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (source->header.ncolors == 1 && source->header.ncmap == 0) { 12570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->visual = GRAYSCALE; 12670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine TRACEMS2(cinfo, 1, JTRC_RLE_GRAY, width, height); 12770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else if (source->header.ncolors == 1 && source->header.ncmap == 1) { 12870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->visual = MAPPEDGRAY; 12970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine TRACEMS3(cinfo, 1, JTRC_RLE_MAPGRAY, width, height, 13070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 1 << source->header.cmaplen); 13170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else if (source->header.ncolors == 1 && source->header.ncmap == 3) { 13270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->visual = PSEUDOCOLOR; 13370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine TRACEMS3(cinfo, 1, JTRC_RLE_MAPPED, width, height, 13470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 1 << source->header.cmaplen); 13570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else if (source->header.ncolors == 3 && source->header.ncmap == 3) { 13670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->visual = TRUECOLOR; 13770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine TRACEMS3(cinfo, 1, JTRC_RLE_FULLMAP, width, height, 13870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 1 << source->header.cmaplen); 13970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else if (source->header.ncolors == 3 && source->header.ncmap == 0) { 14070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->visual = DIRECTCOLOR; 14170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine TRACEMS2(cinfo, 1, JTRC_RLE, width, height); 14270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else 14370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ERREXIT(cinfo, JERR_RLE_UNSUPPORTED); 14470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 14570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (source->visual == GRAYSCALE || source->visual == MAPPEDGRAY) { 14670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->in_color_space = JCS_GRAYSCALE; 14770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->input_components = 1; 14870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 14970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->in_color_space = JCS_RGB; 15070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->input_components = 3; 15170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 15270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 15370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* 15470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * A place to hold each scanline while it's converted. 15570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * (GRAYSCALE scanlines don't need converting) 15670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 15770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (source->visual != GRAYSCALE) { 15870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->rle_row = (rle_pixel**) (*cinfo->mem->alloc_sarray) 15970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) cinfo, JPOOL_IMAGE, 16070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) width, (JDIMENSION) cinfo->input_components); 16170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 16270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 16370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* request a virtual array to hold the image */ 16470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->image = (*cinfo->mem->request_virt_sarray) 16570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, 16670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) (width * source->header.ncolors), 16770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) height, (JDIMENSION) 1); 16870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 16970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef PROGRESS_REPORT 17070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (progress != NULL) { 17170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* count file input as separate pass */ 17270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine progress->total_extra_passes++; 17370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 17470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 17570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 17670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->pub.buffer_height = 1; 17770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 17870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 17970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 18070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 18170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Read one row of pixels. 18270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Called only after load_image has read the image into the virtual array. 18370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Used for GRAYSCALE, MAPPEDGRAY, TRUECOLOR, and DIRECTCOLOR images. 18470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 18570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 18670a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(JDIMENSION) 18770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineget_rle_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 18870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 18970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_source_ptr source = (rle_source_ptr) sinfo; 19070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 19170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->row--; 19270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->pub.buffer = (*cinfo->mem->access_virt_sarray) 19370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE); 19470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 19570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine return 1; 19670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 19770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 19870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 19970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Read one row of pixels. 20070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Called only after load_image has read the image into the virtual array. 20170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Used for PSEUDOCOLOR images. 20270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 20370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 20470a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(JDIMENSION) 20570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineget_pseudocolor_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 20670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 20770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_source_ptr source = (rle_source_ptr) sinfo; 20870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPROW src_row, dest_row; 20970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION col; 21070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_map *colormap; 21170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int val; 21270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 21370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine colormap = source->header.cmap; 21470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dest_row = source->pub.buffer[0]; 21570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->row--; 21670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_row = * (*cinfo->mem->access_virt_sarray) 21770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE); 21870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 21970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (col = cinfo->image_width; col > 0; col--) { 22070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine val = GETJSAMPLE(*src_row++); 22170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dest_row++ = (JSAMPLE) (colormap[val ] >> 8); 22270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dest_row++ = (JSAMPLE) (colormap[val + 256] >> 8); 22370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dest_row++ = (JSAMPLE) (colormap[val + 512] >> 8); 22470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 22570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 22670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine return 1; 22770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 22870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 22970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 23070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 23170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Load the image into a virtual array. We have to do this because RLE 23270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * files start at the lower left while the JPEG standard has them starting 23370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * in the upper left. This is called the first time we want to get a row 23470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * of input. What we do is load the RLE data into the array and then call 23570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * the appropriate routine to read one row from the array. Before returning, 23670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * we set source->pub.get_pixel_rows so that subsequent calls go straight to 23770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * the appropriate row-reading routine. 23870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 23970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 24070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(JDIMENSION) 24170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 24270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 24370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_source_ptr source = (rle_source_ptr) sinfo; 24470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION row, col; 24570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPROW scanline, red_ptr, green_ptr, blue_ptr; 24670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_pixel **rle_row; 24770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_map *colormap; 24870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine char channel; 24970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef PROGRESS_REPORT 25070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; 25170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 25270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 25370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine colormap = source->header.cmap; 25470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_row = source->rle_row; 25570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 25670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Read the RLE data into our virtual array. 25770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * We assume here that (a) rle_pixel is represented the same as JSAMPLE, 25870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * and (b) we are not on a machine where FAR pointers differ from regular. 25970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 26070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine RLE_CLR_BIT(source->header, RLE_ALPHA); /* don't read the alpha channel */ 26170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 26270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef PROGRESS_REPORT 26370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (progress != NULL) { 26470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine progress->pub.pass_limit = cinfo->image_height; 26570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine progress->pub.pass_counter = 0; 26670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); 26770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 26870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 26970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 27070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine switch (source->visual) { 27170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 27270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case GRAYSCALE: 27370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case PSEUDOCOLOR: 27470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (row = 0; row < cinfo->image_height; row++) { 27570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray) 27670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); 27770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_getrow(&source->header, rle_row); 27870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef PROGRESS_REPORT 27970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (progress != NULL) { 28070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine progress->pub.pass_counter++; 28170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); 28270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 28370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 28470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 28570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 28670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 28770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case MAPPEDGRAY: 28870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case TRUECOLOR: 28970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (row = 0; row < cinfo->image_height; row++) { 29070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine scanline = * (*cinfo->mem->access_virt_sarray) 29170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); 29270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_row = source->rle_row; 29370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_getrow(&source->header, rle_row); 29470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 29570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (col = 0; col < cinfo->image_width; col++) { 29670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (channel = 0; channel < source->header.ncolors; channel++) { 29770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *scanline++ = (JSAMPLE) 29870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8); 29970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 30070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 30170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 30270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef PROGRESS_REPORT 30370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (progress != NULL) { 30470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine progress->pub.pass_counter++; 30570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); 30670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 30770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 30870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 30970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 31070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 31170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case DIRECTCOLOR: 31270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (row = 0; row < cinfo->image_height; row++) { 31370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine scanline = * (*cinfo->mem->access_virt_sarray) 31470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); 31570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_getrow(&source->header, rle_row); 31670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 31770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine red_ptr = rle_row[0]; 31870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine green_ptr = rle_row[1]; 31970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine blue_ptr = rle_row[2]; 32070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 32170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (col = cinfo->image_width; col > 0; col--) { 32270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *scanline++ = *red_ptr++; 32370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *scanline++ = *green_ptr++; 32470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *scanline++ = *blue_ptr++; 32570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 32670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 32770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef PROGRESS_REPORT 32870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (progress != NULL) { 32970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine progress->pub.pass_counter++; 33070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); 33170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 33270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 33370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 33470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 33570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 33670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef PROGRESS_REPORT 33770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (progress != NULL) 33870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine progress->completed_extra_passes++; 33970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 34070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 34170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Set up to call proper row-extraction routine in future */ 34270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (source->visual == PSEUDOCOLOR) { 34370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->pub.buffer = source->rle_row; 34470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->pub.get_pixel_rows = get_pseudocolor_row; 34570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 34670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->pub.get_pixel_rows = get_rle_row; 34770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 34870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->row = cinfo->image_height; 34970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 35070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* And fetch the topmost (bottommost) row */ 35170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine return (*source->pub.get_pixel_rows) (cinfo, sinfo); 35270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 35370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 35470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 35570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 35670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Finish up at the end of the file. 35770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 35870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 35970a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 36070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinefinish_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 36170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 36270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* no work */ 36370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 36470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 36570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 36670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 36770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * The module selection routine for RLE format input. 36870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 36970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 37070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(cjpeg_source_ptr) 37170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejinit_read_rle (j_compress_ptr cinfo) 37270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 37370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine rle_source_ptr source; 37470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 37570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Create module interface object */ 37670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source = (rle_source_ptr) 37770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 37870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine SIZEOF(rle_source_struct)); 37970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Fill in method ptrs */ 38070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->pub.start_input = start_input_rle; 38170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->pub.finish_input = finish_input_rle; 38270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine source->pub.get_pixel_rows = load_image; 38370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 38470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine return (cjpeg_source_ptr) source; 38570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 38670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 38770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif /* RLE_SUPPORTED */ 388