1f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 2f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * rdrle.c 3f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 4f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Copyright (C) 1991-1996, Thomas G. Lane. 5f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This file is part of the Independent JPEG Group's software. 6f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * For conditions of distribution and use, see the accompanying README file. 7f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 8f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This file contains routines to read input images in Utah RLE format. 9f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * The Utah Raster Toolkit library is required (version 3.1 or later). 10f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 11f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * These routines may need modification for non-Unix environments or 12f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * specialized applications. As they stand, they assume input from 13f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * an ordinary stdio stream. They further assume that reading begins 14f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * at the start of the file; start_input may need work if the 15f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * user interface has already read some data (e.g., to determine that 16f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * the file is indeed RLE format). 17f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 18f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Based on code contributed by Mike Lijewski, 19f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * with updates from Robert Hutchinson. 20f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 21f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 22f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ 23f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 24f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef RLE_SUPPORTED 25f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 26f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* rle.h is provided by the Utah Raster Toolkit. */ 27f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 28f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include <rle.h> 29f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 30f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 31f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * We assume that JSAMPLE has the same representation as rle_pixel, 32f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples. 33f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 34f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 35f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#if BITS_IN_JSAMPLE != 8 36f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ 37f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 38f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 39f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 40f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * We support the following types of RLE files: 41f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 42f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * GRAYSCALE - 8 bits, no colormap 43f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * MAPPEDGRAY - 8 bits, 1 channel colomap 44f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * PSEUDOCOLOR - 8 bits, 3 channel colormap 45f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * TRUECOLOR - 24 bits, 3 channel colormap 46f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * DIRECTCOLOR - 24 bits, no colormap 47f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 48f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * For now, we ignore any alpha channel in the image. 49f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 50f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 51f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtypedef enum 52f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org { GRAYSCALE, MAPPEDGRAY, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind; 53f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 54f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 55f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 56f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Since RLE stores scanlines bottom-to-top, we have to invert the image 57f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * to conform to JPEG's top-to-bottom order. To do this, we read the 58f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * incoming image into a virtual array on the first get_pixel_rows call, 59f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * then fetch the required row from the virtual array on subsequent calls. 60f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 61f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 62f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtypedef struct _rle_source_struct * rle_source_ptr; 63f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 64f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtypedef struct _rle_source_struct { 65f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org struct cjpeg_source_struct pub; /* public fields */ 66f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 67f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_kind visual; /* actual type of input file */ 68f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org jvirt_sarray_ptr image; /* virtual array to hold the image */ 69f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JDIMENSION row; /* current row # in the virtual array */ 70f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_hdr header; /* Input file information */ 71f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_pixel** rle_row; /* holds a row returned by rle_getrow() */ 72f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 73f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} rle_source_struct; 74f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 75f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 76f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 77f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Read the file header; return image size and component count. 78f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 79f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 80f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgMETHODDEF(void) 81f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgstart_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 82f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 83f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_source_ptr source = (rle_source_ptr) sinfo; 84f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JDIMENSION width, height; 85f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef PROGRESS_REPORT 86f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; 87f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 88f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 89f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Use RLE library routine to get the header info */ 90f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->header = *rle_hdr_init(NULL); 91f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->header.rle_file = source->pub.input_file; 92f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org switch (rle_get_setup(&(source->header))) { 93f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case RLE_SUCCESS: 94f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* A-OK */ 95f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 96f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case RLE_NOT_RLE: 97f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_RLE_NOT); 98f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 99f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case RLE_NO_SPACE: 100f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_RLE_MEM); 101f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 102f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case RLE_EMPTY: 103f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_RLE_EMPTY); 104f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 105f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case RLE_EOF: 106f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_RLE_EOF); 107f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 108f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org default: 109f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_RLE_BADERROR); 110f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 111f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 112f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 113f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Figure out what we have, set private vars and return values accordingly */ 114f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 115f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org width = source->header.xmax - source->header.xmin + 1; 116f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org height = source->header.ymax - source->header.ymin + 1; 117f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->header.xmin = 0; /* realign horizontally */ 118f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->header.xmax = width-1; 119f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 120f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->image_width = width; 121f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->image_height = height; 122f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->data_precision = 8; /* we can only handle 8 bit data */ 123f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 124f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (source->header.ncolors == 1 && source->header.ncmap == 0) { 125f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->visual = GRAYSCALE; 126f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org TRACEMS2(cinfo, 1, JTRC_RLE_GRAY, width, height); 127f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } else if (source->header.ncolors == 1 && source->header.ncmap == 1) { 128f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->visual = MAPPEDGRAY; 129f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org TRACEMS3(cinfo, 1, JTRC_RLE_MAPGRAY, width, height, 130f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 1 << source->header.cmaplen); 131f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } else if (source->header.ncolors == 1 && source->header.ncmap == 3) { 132f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->visual = PSEUDOCOLOR; 133f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org TRACEMS3(cinfo, 1, JTRC_RLE_MAPPED, width, height, 134f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 1 << source->header.cmaplen); 135f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } else if (source->header.ncolors == 3 && source->header.ncmap == 3) { 136f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->visual = TRUECOLOR; 137f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org TRACEMS3(cinfo, 1, JTRC_RLE_FULLMAP, width, height, 138f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 1 << source->header.cmaplen); 139f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } else if (source->header.ncolors == 3 && source->header.ncmap == 0) { 140f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->visual = DIRECTCOLOR; 141f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org TRACEMS2(cinfo, 1, JTRC_RLE, width, height); 142f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } else 143f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_RLE_UNSUPPORTED); 144f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 145f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (source->visual == GRAYSCALE || source->visual == MAPPEDGRAY) { 146f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->in_color_space = JCS_GRAYSCALE; 147f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->input_components = 1; 148f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } else { 149f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->in_color_space = JCS_RGB; 150f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->input_components = 3; 151f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 152f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 153f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* 154f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * A place to hold each scanline while it's converted. 155f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * (GRAYSCALE scanlines don't need converting) 156f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 157f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (source->visual != GRAYSCALE) { 158f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->rle_row = (rle_pixel**) (*cinfo->mem->alloc_sarray) 159f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ((j_common_ptr) cinfo, JPOOL_IMAGE, 160f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (JDIMENSION) width, (JDIMENSION) cinfo->input_components); 161f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 162f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 163f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* request a virtual array to hold the image */ 164f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->image = (*cinfo->mem->request_virt_sarray) 165f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, 166f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (JDIMENSION) (width * source->header.ncolors), 167f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (JDIMENSION) height, (JDIMENSION) 1); 168f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 169f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef PROGRESS_REPORT 170f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (progress != NULL) { 171f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* count file input as separate pass */ 172f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->total_extra_passes++; 173f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 174f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 175f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 176f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.buffer_height = 1; 177f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 178f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 179f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 180f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 181f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Read one row of pixels. 182f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Called only after load_image has read the image into the virtual array. 183f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Used for GRAYSCALE, MAPPEDGRAY, TRUECOLOR, and DIRECTCOLOR images. 184f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 185f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 186f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgMETHODDEF(JDIMENSION) 187f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgget_rle_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 188f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 189f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_source_ptr source = (rle_source_ptr) sinfo; 190f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 191f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->row--; 192f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.buffer = (*cinfo->mem->access_virt_sarray) 193f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE); 194f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 195f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return 1; 196f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 197f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 198f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 199f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Read one row of pixels. 200f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Called only after load_image has read the image into the virtual array. 201f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Used for PSEUDOCOLOR images. 202f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 203f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 204f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgMETHODDEF(JDIMENSION) 205f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgget_pseudocolor_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 206f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 207f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_source_ptr source = (rle_source_ptr) sinfo; 208f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JSAMPROW src_row, dest_row; 209f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JDIMENSION col; 210f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_map *colormap; 211f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org int val; 212f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 213f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org colormap = source->header.cmap; 214f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org dest_row = source->pub.buffer[0]; 215f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->row--; 216f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org src_row = * (*cinfo->mem->access_virt_sarray) 217f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE); 218f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 219f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org for (col = cinfo->image_width; col > 0; col--) { 220f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org val = GETJSAMPLE(*src_row++); 221f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *dest_row++ = (JSAMPLE) (colormap[val ] >> 8); 222f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *dest_row++ = (JSAMPLE) (colormap[val + 256] >> 8); 223f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *dest_row++ = (JSAMPLE) (colormap[val + 512] >> 8); 224f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 225f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 226f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return 1; 227f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 228f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 229f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 230f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 231f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Load the image into a virtual array. We have to do this because RLE 232f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * files start at the lower left while the JPEG standard has them starting 233f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * in the upper left. This is called the first time we want to get a row 234f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * of input. What we do is load the RLE data into the array and then call 235f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * the appropriate routine to read one row from the array. Before returning, 236f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * we set source->pub.get_pixel_rows so that subsequent calls go straight to 237f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * the appropriate row-reading routine. 238f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 239f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 240f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgMETHODDEF(JDIMENSION) 241f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 242f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 243f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_source_ptr source = (rle_source_ptr) sinfo; 244f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JDIMENSION row, col; 245f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JSAMPROW scanline, red_ptr, green_ptr, blue_ptr; 246f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_pixel **rle_row; 247f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_map *colormap; 248f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org char channel; 249f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef PROGRESS_REPORT 250f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; 251f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 252f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 253f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org colormap = source->header.cmap; 254f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_row = source->rle_row; 255f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 256f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Read the RLE data into our virtual array. 257f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * We assume here that (a) rle_pixel is represented the same as JSAMPLE, 258f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * and (b) we are not on a machine where FAR pointers differ from regular. 259f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 260f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org RLE_CLR_BIT(source->header, RLE_ALPHA); /* don't read the alpha channel */ 261f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 262f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef PROGRESS_REPORT 263f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (progress != NULL) { 264f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->pub.pass_limit = cinfo->image_height; 265f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->pub.pass_counter = 0; 266f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); 267f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 268f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 269f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 270f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org switch (source->visual) { 271f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 272f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case GRAYSCALE: 273f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case PSEUDOCOLOR: 274f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org for (row = 0; row < cinfo->image_height; row++) { 275f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray) 276f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); 277f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_getrow(&source->header, rle_row); 278f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef PROGRESS_REPORT 279f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (progress != NULL) { 280f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->pub.pass_counter++; 281f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); 282f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 283f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 284f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 285f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 286f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 287f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case MAPPEDGRAY: 288f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case TRUECOLOR: 289f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org for (row = 0; row < cinfo->image_height; row++) { 290f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org scanline = * (*cinfo->mem->access_virt_sarray) 291f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); 292f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_row = source->rle_row; 293f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_getrow(&source->header, rle_row); 294f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 295f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org for (col = 0; col < cinfo->image_width; col++) { 296f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org for (channel = 0; channel < source->header.ncolors; channel++) { 297f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *scanline++ = (JSAMPLE) 298f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8); 299f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 300f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 301f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 302f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef PROGRESS_REPORT 303f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (progress != NULL) { 304f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->pub.pass_counter++; 305f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); 306f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 307f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 308f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 309f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 310f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 311f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case DIRECTCOLOR: 312f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org for (row = 0; row < cinfo->image_height; row++) { 313f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org scanline = * (*cinfo->mem->access_virt_sarray) 314f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); 315f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_getrow(&source->header, rle_row); 316f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 317f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org red_ptr = rle_row[0]; 318f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org green_ptr = rle_row[1]; 319f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org blue_ptr = rle_row[2]; 320f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 321f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org for (col = cinfo->image_width; col > 0; col--) { 322f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *scanline++ = *red_ptr++; 323f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *scanline++ = *green_ptr++; 324f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *scanline++ = *blue_ptr++; 325f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 326f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 327f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef PROGRESS_REPORT 328f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (progress != NULL) { 329f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->pub.pass_counter++; 330f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); 331f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 332f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 333f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 334f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 335f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 336f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef PROGRESS_REPORT 337f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (progress != NULL) 338f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->completed_extra_passes++; 339f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 340f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 341f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Set up to call proper row-extraction routine in future */ 342f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (source->visual == PSEUDOCOLOR) { 343f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.buffer = source->rle_row; 344f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.get_pixel_rows = get_pseudocolor_row; 345f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } else { 346f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.get_pixel_rows = get_rle_row; 347f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 348f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->row = cinfo->image_height; 349f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 350f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* And fetch the topmost (bottommost) row */ 351f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return (*source->pub.get_pixel_rows) (cinfo, sinfo); 352f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 353f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 354f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 355f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 356f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Finish up at the end of the file. 357f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 358f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 359f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgMETHODDEF(void) 360f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgfinish_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 361f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 362f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* no work */ 363f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 364f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 365f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 366f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 367f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * The module selection routine for RLE format input. 368f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 369f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 370f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(cjpeg_source_ptr) 371f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgjinit_read_rle (j_compress_ptr cinfo) 372f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 373f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rle_source_ptr source; 374f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 375f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Create module interface object */ 376f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source = (rle_source_ptr) 377f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 378f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org SIZEOF(rle_source_struct)); 379f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Fill in method ptrs */ 380f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.start_input = start_input_rle; 381f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.finish_input = finish_input_rle; 382f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.get_pixel_rows = load_image; 383f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 384f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return (cjpeg_source_ptr) source; 385f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 386f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 387f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif /* RLE_SUPPORTED */ 388