📄 rdtarga.c
字号:
/*
* rdtarga.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains routines to read input images in Targa format.
*
* These routines may need modification for non-Unix environments or
* specialized applications. As they stand, they assume input from
* an ordinary stdio stream. They further assume that reading begins
* at the start of the file; start_input may need work if the
* user interface has already read some data (e.g., to determine that
* the file is indeed Targa format).
*
* Based on code contributed by Lee Daniel Crocker.
*/
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#ifdef TARGA_SUPPORTED
/* Macros to deal with unsigned chars as efficiently as compiler allows */
#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char U_CHAR;
#define UCH(x) ((int) (x))
#else /* !HAVE_UNSIGNED_CHAR */
#ifdef CHAR_IS_UNSIGNED
typedef char U_CHAR;
#define UCH(x) ((int) (x))
#else
typedef char U_CHAR;
#define UCH(x) ((int) (x) & 0xFF)
#endif
#endif /* HAVE_UNSIGNED_CHAR */
#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len)))
/* Private version of data source object */
typedef struct _tga_source_struct * tga_source_ptr;
typedef struct _tga_source_struct {
struct cjpeg_source_struct pub; /* public fields */
j_compress_ptr cinfo; /* back link saves passing separate parm */
JSAMPARRAY colormap; /* Targa colormap (converted to my format) */
jvirt_sarray_ptr whole_image; /* Needed if funny input row order */
JDIMENSION current_row; /* Current logical row number to read */
/* Pointer to routine to extract next Targa pixel from input file */
JMETHOD(void, read_pixel, (tga_source_ptr sinfo));
/* Result of read_pixel is delivered here: */
U_CHAR tga_pixel[4];
int pixel_size; /* Bytes per Targa pixel (1 to 4) */
/* State info for reading RLE-coded pixels; both counts must be init to 0 */
int block_count; /* # of pixels remaining in RLE block */
int dup_pixel_count; /* # of times to duplicate previous pixel */
/* This saves the correct pixel-row-expansion method for preload_image */
JMETHOD(JDIMENSION, get_pixel_rows, (j_compress_ptr cinfo,
cjpeg_source_ptr sinfo));
} tga_source_struct;
/* For expanding 5-bit pixel values to 8-bit with best rounding */
static const UINT8 c5to8bits[32] = {
0, 8, 16, 25, 33, 41, 49, 58,
66, 74, 82, 90, 99, 107, 115, 123,
132, 140, 148, 156, 165, 173, 181, 189,
197, 206, 214, 222, 230, 239, 247, 255
};
LOCAL(int)
read_byte (tga_source_ptr sinfo)
/* Read next byte from Targa file */
{
register FILE *infile = sinfo->pub.input_file;
register int c;
if ((c = getc(infile)) == EOF)
ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
return c;
}
LOCAL(void)
read_colormap (tga_source_ptr sinfo, int cmaplen, int mapentrysize)
/* Read the colormap from a Targa file */
{
int i;
/* Presently only handles 24-bit BGR format */
if (mapentrysize != 24)
ERREXIT(sinfo->cinfo, JERR_TGA_BADCMAP);
for (i = 0; i < cmaplen; i++) {
sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo);
sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo);
sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo);
}
}
/*
* read_pixel methods: get a single pixel from Targa file into tga_pixel[]
*/
METHODDEF(void)
read_non_rle_pixel (tga_source_ptr sinfo)
/* Read one Targa pixel from the input file; no RLE expansion */
{
register FILE *infile = sinfo->pub.input_file;
register int i;
for (i = 0; i < sinfo->pixel_size; i++) {
sinfo->tga_pixel[i] = (U_CHAR) getc(infile);
}
}
METHODDEF(void)
read_rle_pixel (tga_source_ptr sinfo)
/* Read one Targa pixel from the input file, expanding RLE data as needed */
{
register FILE *infile = sinfo->pub.input_file;
register int i;
/* Duplicate previously read pixel? */
if (sinfo->dup_pixel_count > 0) {
sinfo->dup_pixel_count--;
return;
}
/* Time to read RLE block header? */
if (--sinfo->block_count < 0) { /* decrement pixels remaining in block */
i = read_byte(sinfo);
if (i & 0x80) { /* Start of duplicate-pixel block? */
sinfo->dup_pixel_count = i & 0x7F; /* number of dups after this one */
sinfo->block_count = 0; /* then read new block header */
} else {
sinfo->block_count = i & 0x7F; /* number of pixels after this one */
}
}
/* Read next pixel */
for (i = 0; i < sinfo->pixel_size; i++) {
sinfo->tga_pixel[i] = (U_CHAR) getc(infile);
}
}
/*
* Read one row of pixels.
*
* We provide several different versions depending on input file format.
*/
METHODDEF(JDIMENSION)
get_8bit_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 8-bit grayscale pixels */
{
tga_source_ptr source = (tga_source_ptr) sinfo;
register JSAMPROW ptr;
register JDIMENSION col;
ptr = source->pub.buffer[0];
for (col = cinfo->image_width; col > 0; col--) {
(*source->read_pixel) (source); /* Load next pixel into tga_pixel */
*ptr++ = (JSAMPLE) UCH(source->tga_pixel[0]);
}
return 1;
}
METHODDEF(JDIMENSION)
get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 8-bit colormap indexes */
{
tga_source_ptr source = (tga_source_ptr) sinfo;
register int t;
register JSAMPROW ptr;
register JDIMENSION col;
register JSAMPARRAY colormap = source->colormap;
ptr = source->pub.buffer[0];
for (col = cinfo->image_width; col > 0; col--) {
(*source->read_pixel) (source); /* Load next pixel into tga_pixel */
t = UCH(source->tga_pixel[0]);
*ptr++ = colormap[0][t];
*ptr++ = colormap[1][t];
*ptr++ = colormap[2][t];
}
return 1;
}
METHODDEF(JDIMENSION)
get_16bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 16-bit pixels */
{
tga_source_ptr source = (tga_source_ptr) sinfo;
register int t;
register JSAMPROW ptr;
register JDIMENSION col;
ptr = source->pub.buffer[0];
for (col = cinfo->image_width; col > 0; col--) {
(*source->read_pixel) (source); /* Load next pixel into tga_pixel */
t = UCH(source->tga_pixel[0]);
t += UCH(source->tga_pixel[1]) << 8;
/* We expand 5 bit data to 8 bit sample width.
* The format of the 16-bit (LSB first) input word is
* xRRRRRGGGGGBBBBB
*/
ptr[2] = (JSAMPLE) c5to8bits[t & 0x1F];
t >>= 5;
ptr[1] = (JSAMPLE) c5to8bits[t & 0x1F];
t >>= 5;
ptr[0] = (JSAMPLE) c5to8bits[t & 0x1F];
ptr += 3;
}
return 1;
}
METHODDEF(JDIMENSION)
get_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 24-bit pixels */
{
tga_source_ptr source = (tga_source_ptr) sinfo;
register JSAMPROW ptr;
register JDIMENSION col;
ptr = source->pub.buffer[0];
for (col = cinfo->image_width; col > 0; col--) {
(*source->read_pixel) (source); /* Load next pixel into tga_pixel */
*ptr++ = (JSAMPLE) UCH(source->tga_pixel[2]); /* change BGR to RGB order */
*ptr++ = (JSAMPLE) UCH(source->tga_pixel[1]);
*ptr++ = (JSAMPLE) UCH(source->tga_pixel[0]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -