migrating to the latest JUCE version
This commit is contained in:
@ -1,132 +1,132 @@
|
||||
/*
|
||||
* cderror.h
|
||||
*
|
||||
* Copyright (C) 1994-1997, 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 defines the error and message codes for the cjpeg/djpeg
|
||||
* applications. These strings are not needed as part of the JPEG library
|
||||
* proper.
|
||||
* Edit this file to add new codes, or to translate the message strings to
|
||||
* some other language.
|
||||
*/
|
||||
|
||||
/*
|
||||
* To define the enum list of message codes, include this file without
|
||||
* defining macro JMESSAGE. To create a message string table, include it
|
||||
* again with a suitable JMESSAGE definition (see jerror.c for an example).
|
||||
*/
|
||||
#ifndef JMESSAGE
|
||||
#ifndef CDERROR_H
|
||||
#define CDERROR_H
|
||||
/* First time through, define the enum list */
|
||||
#define JMAKE_ENUM_LIST
|
||||
#else
|
||||
/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
|
||||
#define JMESSAGE(code,string)
|
||||
#endif /* CDERROR_H */
|
||||
#endif /* JMESSAGE */
|
||||
|
||||
#ifdef JMAKE_ENUM_LIST
|
||||
|
||||
typedef enum {
|
||||
|
||||
#define JMESSAGE(code,string) code ,
|
||||
|
||||
#endif /* JMAKE_ENUM_LIST */
|
||||
|
||||
JMESSAGE(JMSG_FIRSTADDONCODE=1000, NULL) /* Must be first entry! */
|
||||
|
||||
#ifdef BMP_SUPPORTED
|
||||
JMESSAGE(JERR_BMP_BADCMAP, "Unsupported BMP colormap format")
|
||||
JMESSAGE(JERR_BMP_BADDEPTH, "Only 8- and 24-bit BMP files are supported")
|
||||
JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length")
|
||||
JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1")
|
||||
JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB")
|
||||
JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported")
|
||||
JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM")
|
||||
JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image")
|
||||
JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image")
|
||||
JMESSAGE(JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image")
|
||||
JMESSAGE(JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image")
|
||||
#endif /* BMP_SUPPORTED */
|
||||
|
||||
#ifdef GIF_SUPPORTED
|
||||
JMESSAGE(JERR_GIF_BUG, "GIF output got confused")
|
||||
JMESSAGE(JERR_GIF_CODESIZE, "Bogus GIF codesize %d")
|
||||
JMESSAGE(JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB")
|
||||
JMESSAGE(JERR_GIF_IMAGENOTFOUND, "Too few images in GIF file")
|
||||
JMESSAGE(JERR_GIF_NOT, "Not a GIF file")
|
||||
JMESSAGE(JTRC_GIF, "%ux%ux%d GIF image")
|
||||
JMESSAGE(JTRC_GIF_BADVERSION,
|
||||
"Warning: unexpected GIF version number '%c%c%c'")
|
||||
JMESSAGE(JTRC_GIF_EXTENSION, "Ignoring GIF extension block of type 0x%02x")
|
||||
JMESSAGE(JTRC_GIF_NONSQUARE, "Caution: nonsquare pixels in input")
|
||||
JMESSAGE(JWRN_GIF_BADDATA, "Corrupt data in GIF file")
|
||||
JMESSAGE(JWRN_GIF_CHAR, "Bogus char 0x%02x in GIF file, ignoring")
|
||||
JMESSAGE(JWRN_GIF_ENDCODE, "Premature end of GIF image")
|
||||
JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits")
|
||||
#endif /* GIF_SUPPORTED */
|
||||
|
||||
#ifdef PPM_SUPPORTED
|
||||
JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
|
||||
JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
|
||||
JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")
|
||||
JMESSAGE(JTRC_PGM, "%ux%u PGM image")
|
||||
JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")
|
||||
JMESSAGE(JTRC_PPM, "%ux%u PPM image")
|
||||
JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image")
|
||||
#endif /* PPM_SUPPORTED */
|
||||
|
||||
#ifdef RLE_SUPPORTED
|
||||
JMESSAGE(JERR_RLE_BADERROR, "Bogus error code from RLE library")
|
||||
JMESSAGE(JERR_RLE_COLORSPACE, "RLE output must be grayscale or RGB")
|
||||
JMESSAGE(JERR_RLE_DIMENSIONS, "Image dimensions (%ux%u) too large for RLE")
|
||||
JMESSAGE(JERR_RLE_EMPTY, "Empty RLE file")
|
||||
JMESSAGE(JERR_RLE_EOF, "Premature EOF in RLE header")
|
||||
JMESSAGE(JERR_RLE_MEM, "Insufficient memory for RLE header")
|
||||
JMESSAGE(JERR_RLE_NOT, "Not an RLE file")
|
||||
JMESSAGE(JERR_RLE_TOOMANYCHANNELS, "Cannot handle %d output channels for RLE")
|
||||
JMESSAGE(JERR_RLE_UNSUPPORTED, "Cannot handle this RLE setup")
|
||||
JMESSAGE(JTRC_RLE, "%ux%u full-color RLE file")
|
||||
JMESSAGE(JTRC_RLE_FULLMAP, "%ux%u full-color RLE file with map of length %d")
|
||||
JMESSAGE(JTRC_RLE_GRAY, "%ux%u grayscale RLE file")
|
||||
JMESSAGE(JTRC_RLE_MAPGRAY, "%ux%u grayscale RLE file with map of length %d")
|
||||
JMESSAGE(JTRC_RLE_MAPPED, "%ux%u colormapped RLE file with map of length %d")
|
||||
#endif /* RLE_SUPPORTED */
|
||||
|
||||
#ifdef TARGA_SUPPORTED
|
||||
JMESSAGE(JERR_TGA_BADCMAP, "Unsupported Targa colormap format")
|
||||
JMESSAGE(JERR_TGA_BADPARMS, "Invalid or unsupported Targa file")
|
||||
JMESSAGE(JERR_TGA_COLORSPACE, "Targa output must be grayscale or RGB")
|
||||
JMESSAGE(JTRC_TGA, "%ux%u RGB Targa image")
|
||||
JMESSAGE(JTRC_TGA_GRAY, "%ux%u grayscale Targa image")
|
||||
JMESSAGE(JTRC_TGA_MAPPED, "%ux%u colormapped Targa image")
|
||||
#else
|
||||
JMESSAGE(JERR_TGA_NOTCOMP, "Targa support was not compiled")
|
||||
#endif /* TARGA_SUPPORTED */
|
||||
|
||||
JMESSAGE(JERR_BAD_CMAP_FILE,
|
||||
"Color map file is invalid or of unsupported format")
|
||||
JMESSAGE(JERR_TOO_MANY_COLORS,
|
||||
"Output file format cannot handle %d colormap entries")
|
||||
JMESSAGE(JERR_UNGETC_FAILED, "ungetc failed")
|
||||
#ifdef TARGA_SUPPORTED
|
||||
JMESSAGE(JERR_UNKNOWN_FORMAT,
|
||||
"Unrecognized input file format --- perhaps you need -targa")
|
||||
#else
|
||||
JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format")
|
||||
#endif
|
||||
JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format")
|
||||
|
||||
#ifdef JMAKE_ENUM_LIST
|
||||
|
||||
JMSG_LASTADDONCODE
|
||||
} ADDON_MESSAGE_CODE;
|
||||
|
||||
#undef JMAKE_ENUM_LIST
|
||||
#endif /* JMAKE_ENUM_LIST */
|
||||
|
||||
/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
|
||||
#undef JMESSAGE
|
||||
/*
|
||||
* cderror.h
|
||||
*
|
||||
* Copyright (C) 1994-1997, 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 defines the error and message codes for the cjpeg/djpeg
|
||||
* applications. These strings are not needed as part of the JPEG library
|
||||
* proper.
|
||||
* Edit this file to add new codes, or to translate the message strings to
|
||||
* some other language.
|
||||
*/
|
||||
|
||||
/*
|
||||
* To define the enum list of message codes, include this file without
|
||||
* defining macro JMESSAGE. To create a message string table, include it
|
||||
* again with a suitable JMESSAGE definition (see jerror.c for an example).
|
||||
*/
|
||||
#ifndef JMESSAGE
|
||||
#ifndef CDERROR_H
|
||||
#define CDERROR_H
|
||||
/* First time through, define the enum list */
|
||||
#define JMAKE_ENUM_LIST
|
||||
#else
|
||||
/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
|
||||
#define JMESSAGE(code,string)
|
||||
#endif /* CDERROR_H */
|
||||
#endif /* JMESSAGE */
|
||||
|
||||
#ifdef JMAKE_ENUM_LIST
|
||||
|
||||
typedef enum {
|
||||
|
||||
#define JMESSAGE(code,string) code ,
|
||||
|
||||
#endif /* JMAKE_ENUM_LIST */
|
||||
|
||||
JMESSAGE(JMSG_FIRSTADDONCODE=1000, NULL) /* Must be first entry! */
|
||||
|
||||
#ifdef BMP_SUPPORTED
|
||||
JMESSAGE(JERR_BMP_BADCMAP, "Unsupported BMP colormap format")
|
||||
JMESSAGE(JERR_BMP_BADDEPTH, "Only 8- and 24-bit BMP files are supported")
|
||||
JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length")
|
||||
JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1")
|
||||
JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB")
|
||||
JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported")
|
||||
JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM")
|
||||
JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image")
|
||||
JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image")
|
||||
JMESSAGE(JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image")
|
||||
JMESSAGE(JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image")
|
||||
#endif /* BMP_SUPPORTED */
|
||||
|
||||
#ifdef GIF_SUPPORTED
|
||||
JMESSAGE(JERR_GIF_BUG, "GIF output got confused")
|
||||
JMESSAGE(JERR_GIF_CODESIZE, "Bogus GIF codesize %d")
|
||||
JMESSAGE(JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB")
|
||||
JMESSAGE(JERR_GIF_IMAGENOTFOUND, "Too few images in GIF file")
|
||||
JMESSAGE(JERR_GIF_NOT, "Not a GIF file")
|
||||
JMESSAGE(JTRC_GIF, "%ux%ux%d GIF image")
|
||||
JMESSAGE(JTRC_GIF_BADVERSION,
|
||||
"Warning: unexpected GIF version number '%c%c%c'")
|
||||
JMESSAGE(JTRC_GIF_EXTENSION, "Ignoring GIF extension block of type 0x%02x")
|
||||
JMESSAGE(JTRC_GIF_NONSQUARE, "Caution: nonsquare pixels in input")
|
||||
JMESSAGE(JWRN_GIF_BADDATA, "Corrupt data in GIF file")
|
||||
JMESSAGE(JWRN_GIF_CHAR, "Bogus char 0x%02x in GIF file, ignoring")
|
||||
JMESSAGE(JWRN_GIF_ENDCODE, "Premature end of GIF image")
|
||||
JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits")
|
||||
#endif /* GIF_SUPPORTED */
|
||||
|
||||
#ifdef PPM_SUPPORTED
|
||||
JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
|
||||
JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
|
||||
JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")
|
||||
JMESSAGE(JTRC_PGM, "%ux%u PGM image")
|
||||
JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")
|
||||
JMESSAGE(JTRC_PPM, "%ux%u PPM image")
|
||||
JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image")
|
||||
#endif /* PPM_SUPPORTED */
|
||||
|
||||
#ifdef RLE_SUPPORTED
|
||||
JMESSAGE(JERR_RLE_BADERROR, "Bogus error code from RLE library")
|
||||
JMESSAGE(JERR_RLE_COLORSPACE, "RLE output must be grayscale or RGB")
|
||||
JMESSAGE(JERR_RLE_DIMENSIONS, "Image dimensions (%ux%u) too large for RLE")
|
||||
JMESSAGE(JERR_RLE_EMPTY, "Empty RLE file")
|
||||
JMESSAGE(JERR_RLE_EOF, "Premature EOF in RLE header")
|
||||
JMESSAGE(JERR_RLE_MEM, "Insufficient memory for RLE header")
|
||||
JMESSAGE(JERR_RLE_NOT, "Not an RLE file")
|
||||
JMESSAGE(JERR_RLE_TOOMANYCHANNELS, "Cannot handle %d output channels for RLE")
|
||||
JMESSAGE(JERR_RLE_UNSUPPORTED, "Cannot handle this RLE setup")
|
||||
JMESSAGE(JTRC_RLE, "%ux%u full-color RLE file")
|
||||
JMESSAGE(JTRC_RLE_FULLMAP, "%ux%u full-color RLE file with map of length %d")
|
||||
JMESSAGE(JTRC_RLE_GRAY, "%ux%u grayscale RLE file")
|
||||
JMESSAGE(JTRC_RLE_MAPGRAY, "%ux%u grayscale RLE file with map of length %d")
|
||||
JMESSAGE(JTRC_RLE_MAPPED, "%ux%u colormapped RLE file with map of length %d")
|
||||
#endif /* RLE_SUPPORTED */
|
||||
|
||||
#ifdef TARGA_SUPPORTED
|
||||
JMESSAGE(JERR_TGA_BADCMAP, "Unsupported Targa colormap format")
|
||||
JMESSAGE(JERR_TGA_BADPARMS, "Invalid or unsupported Targa file")
|
||||
JMESSAGE(JERR_TGA_COLORSPACE, "Targa output must be grayscale or RGB")
|
||||
JMESSAGE(JTRC_TGA, "%ux%u RGB Targa image")
|
||||
JMESSAGE(JTRC_TGA_GRAY, "%ux%u grayscale Targa image")
|
||||
JMESSAGE(JTRC_TGA_MAPPED, "%ux%u colormapped Targa image")
|
||||
#else
|
||||
JMESSAGE(JERR_TGA_NOTCOMP, "Targa support was not compiled")
|
||||
#endif /* TARGA_SUPPORTED */
|
||||
|
||||
JMESSAGE(JERR_BAD_CMAP_FILE,
|
||||
"Color map file is invalid or of unsupported format")
|
||||
JMESSAGE(JERR_TOO_MANY_COLORS,
|
||||
"Output file format cannot handle %d colormap entries")
|
||||
JMESSAGE(JERR_UNGETC_FAILED, "ungetc failed")
|
||||
#ifdef TARGA_SUPPORTED
|
||||
JMESSAGE(JERR_UNKNOWN_FORMAT,
|
||||
"Unrecognized input file format --- perhaps you need -targa")
|
||||
#else
|
||||
JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format")
|
||||
#endif
|
||||
JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format")
|
||||
|
||||
#ifdef JMAKE_ENUM_LIST
|
||||
|
||||
JMSG_LASTADDONCODE
|
||||
} ADDON_MESSAGE_CODE;
|
||||
|
||||
#undef JMAKE_ENUM_LIST
|
||||
#endif /* JMAKE_ENUM_LIST */
|
||||
|
||||
/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
|
||||
#undef JMESSAGE
|
||||
|
@ -1,280 +1,280 @@
|
||||
/*
|
||||
* jcapimin.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, 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 application interface code for the compression half
|
||||
* of the JPEG library. These are the "minimum" API routines that may be
|
||||
* needed in either the normal full-compression case or the transcoding-only
|
||||
* case.
|
||||
*
|
||||
* Most of the routines intended to be called directly by an application
|
||||
* are in this file or in jcapistd.c. But also see jcparam.c for
|
||||
* parameter-setup helper routines, jcomapi.c for routines shared by
|
||||
* compression and decompression, and jctrans.c for the transcoding case.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/*
|
||||
* Initialization of a JPEG compression object.
|
||||
* The error manager must already be set up (in case memory manager fails).
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Guard against version mismatches between library and caller. */
|
||||
cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
|
||||
if (version != JPEG_LIB_VERSION)
|
||||
ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
|
||||
if (structsize != SIZEOF(struct jpeg_compress_struct))
|
||||
ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
|
||||
(int) SIZEOF(struct jpeg_compress_struct), (int) structsize);
|
||||
|
||||
/* For debugging purposes, we zero the whole master structure.
|
||||
* But the application has already set the err pointer, and may have set
|
||||
* client_data, so we have to save and restore those fields.
|
||||
* Note: if application hasn't set client_data, tools like Purify may
|
||||
* complain here.
|
||||
*/
|
||||
{
|
||||
struct jpeg_error_mgr * err = cinfo->err;
|
||||
void * client_data = cinfo->client_data; /* ignore Purify complaint here */
|
||||
MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct));
|
||||
cinfo->err = err;
|
||||
cinfo->client_data = client_data;
|
||||
}
|
||||
cinfo->is_decompressor = FALSE;
|
||||
|
||||
/* Initialize a memory manager instance for this object */
|
||||
jinit_memory_mgr((j_common_ptr) cinfo);
|
||||
|
||||
/* Zero out pointers to permanent structures. */
|
||||
cinfo->progress = NULL;
|
||||
cinfo->dest = NULL;
|
||||
|
||||
cinfo->comp_info = NULL;
|
||||
|
||||
for (i = 0; i < NUM_QUANT_TBLS; i++)
|
||||
cinfo->quant_tbl_ptrs[i] = NULL;
|
||||
|
||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
||||
cinfo->dc_huff_tbl_ptrs[i] = NULL;
|
||||
cinfo->ac_huff_tbl_ptrs[i] = NULL;
|
||||
}
|
||||
|
||||
cinfo->script_space = NULL;
|
||||
|
||||
cinfo->input_gamma = 1.0; /* in case application forgets */
|
||||
|
||||
/* OK, I'm ready */
|
||||
cinfo->global_state = CSTATE_START;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Destruction of a JPEG compression object
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_destroy_compress (j_compress_ptr cinfo)
|
||||
{
|
||||
jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Abort processing of a JPEG compression operation,
|
||||
* but don't destroy the object itself.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_abort_compress (j_compress_ptr cinfo)
|
||||
{
|
||||
jpeg_abort((j_common_ptr) cinfo); /* use common routine */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Forcibly suppress or un-suppress all quantization and Huffman tables.
|
||||
* Marks all currently defined tables as already written (if suppress)
|
||||
* or not written (if !suppress). This will control whether they get emitted
|
||||
* by a subsequent jpeg_start_compress call.
|
||||
*
|
||||
* This routine is exported for use by applications that want to produce
|
||||
* abbreviated JPEG datastreams. It logically belongs in jcparam.c, but
|
||||
* since it is called by jpeg_start_compress, we put it here --- otherwise
|
||||
* jcparam.o would be linked whether the application used it or not.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress)
|
||||
{
|
||||
int i;
|
||||
JQUANT_TBL * qtbl;
|
||||
JHUFF_TBL * htbl;
|
||||
|
||||
for (i = 0; i < NUM_QUANT_TBLS; i++) {
|
||||
if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL)
|
||||
qtbl->sent_table = suppress;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
||||
if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL)
|
||||
htbl->sent_table = suppress;
|
||||
if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL)
|
||||
htbl->sent_table = suppress;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish JPEG compression.
|
||||
*
|
||||
* If a multipass operating mode was selected, this may do a great deal of
|
||||
* work including most of the actual output.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_finish_compress (j_compress_ptr cinfo)
|
||||
{
|
||||
JDIMENSION iMCU_row;
|
||||
|
||||
if (cinfo->global_state == CSTATE_SCANNING ||
|
||||
cinfo->global_state == CSTATE_RAW_OK) {
|
||||
/* Terminate first pass */
|
||||
if (cinfo->next_scanline < cinfo->image_height)
|
||||
ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
|
||||
(*cinfo->master->finish_pass) (cinfo);
|
||||
} else if (cinfo->global_state != CSTATE_WRCOEFS)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
/* Perform any remaining passes */
|
||||
while (! cinfo->master->is_last_pass) {
|
||||
(*cinfo->master->prepare_for_pass) (cinfo);
|
||||
for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) {
|
||||
if (cinfo->progress != NULL) {
|
||||
cinfo->progress->pass_counter = (long) iMCU_row;
|
||||
cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows;
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
}
|
||||
/* We bypass the main controller and invoke coef controller directly;
|
||||
* all work is being done from the coefficient buffer.
|
||||
*/
|
||||
if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL))
|
||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
||||
}
|
||||
(*cinfo->master->finish_pass) (cinfo);
|
||||
}
|
||||
/* Write EOI, do final cleanup */
|
||||
(*cinfo->marker->write_file_trailer) (cinfo);
|
||||
(*cinfo->dest->term_destination) (cinfo);
|
||||
/* We can use jpeg_abort to release memory and reset global_state */
|
||||
jpeg_abort((j_common_ptr) cinfo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write a special marker.
|
||||
* This is only recommended for writing COM or APPn markers.
|
||||
* Must be called after jpeg_start_compress() and before
|
||||
* first call to jpeg_write_scanlines() or jpeg_write_raw_data().
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_write_marker (j_compress_ptr cinfo, int marker,
|
||||
const JOCTET *dataptr, unsigned int datalen)
|
||||
{
|
||||
JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val));
|
||||
|
||||
if (cinfo->next_scanline != 0 ||
|
||||
(cinfo->global_state != CSTATE_SCANNING &&
|
||||
cinfo->global_state != CSTATE_RAW_OK &&
|
||||
cinfo->global_state != CSTATE_WRCOEFS))
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
(*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
|
||||
write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */
|
||||
while (datalen--) {
|
||||
(*write_marker_byte) (cinfo, *dataptr);
|
||||
dataptr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Same, but piecemeal. */
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
|
||||
{
|
||||
if (cinfo->next_scanline != 0 ||
|
||||
(cinfo->global_state != CSTATE_SCANNING &&
|
||||
cinfo->global_state != CSTATE_RAW_OK &&
|
||||
cinfo->global_state != CSTATE_WRCOEFS))
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
(*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_write_m_byte (j_compress_ptr cinfo, int val)
|
||||
{
|
||||
(*cinfo->marker->write_marker_byte) (cinfo, val);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Alternate compression function: just write an abbreviated table file.
|
||||
* Before calling this, all parameters and a data destination must be set up.
|
||||
*
|
||||
* To produce a pair of files containing abbreviated tables and abbreviated
|
||||
* image data, one would proceed as follows:
|
||||
*
|
||||
* initialize JPEG object
|
||||
* set JPEG parameters
|
||||
* set destination to table file
|
||||
* jpeg_write_tables(cinfo);
|
||||
* set destination to image file
|
||||
* jpeg_start_compress(cinfo, FALSE);
|
||||
* write data...
|
||||
* jpeg_finish_compress(cinfo);
|
||||
*
|
||||
* jpeg_write_tables has the side effect of marking all tables written
|
||||
* (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress
|
||||
* will not re-emit the tables unless it is passed write_all_tables=TRUE.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_write_tables (j_compress_ptr cinfo)
|
||||
{
|
||||
if (cinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
/* (Re)initialize error mgr and destination modules */
|
||||
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
|
||||
(*cinfo->dest->init_destination) (cinfo);
|
||||
/* Initialize the marker writer ... bit of a crock to do it here. */
|
||||
jinit_marker_writer(cinfo);
|
||||
/* Write them tables! */
|
||||
(*cinfo->marker->write_tables_only) (cinfo);
|
||||
/* And clean up. */
|
||||
(*cinfo->dest->term_destination) (cinfo);
|
||||
/*
|
||||
* In library releases up through v6a, we called jpeg_abort() here to free
|
||||
* any working memory allocated by the destination manager and marker
|
||||
* writer. Some applications had a problem with that: they allocated space
|
||||
* of their own from the library memory manager, and didn't want it to go
|
||||
* away during write_tables. So now we do nothing. This will cause a
|
||||
* memory leak if an app calls write_tables repeatedly without doing a full
|
||||
* compression cycle or otherwise resetting the JPEG object. However, that
|
||||
* seems less bad than unexpectedly freeing memory in the normal case.
|
||||
* An app that prefers the old behavior can call jpeg_abort for itself after
|
||||
* each call to jpeg_write_tables().
|
||||
*/
|
||||
}
|
||||
/*
|
||||
* jcapimin.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, 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 application interface code for the compression half
|
||||
* of the JPEG library. These are the "minimum" API routines that may be
|
||||
* needed in either the normal full-compression case or the transcoding-only
|
||||
* case.
|
||||
*
|
||||
* Most of the routines intended to be called directly by an application
|
||||
* are in this file or in jcapistd.c. But also see jcparam.c for
|
||||
* parameter-setup helper routines, jcomapi.c for routines shared by
|
||||
* compression and decompression, and jctrans.c for the transcoding case.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/*
|
||||
* Initialization of a JPEG compression object.
|
||||
* The error manager must already be set up (in case memory manager fails).
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Guard against version mismatches between library and caller. */
|
||||
cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
|
||||
if (version != JPEG_LIB_VERSION)
|
||||
ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
|
||||
if (structsize != SIZEOF(struct jpeg_compress_struct))
|
||||
ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
|
||||
(int) SIZEOF(struct jpeg_compress_struct), (int) structsize);
|
||||
|
||||
/* For debugging purposes, we zero the whole master structure.
|
||||
* But the application has already set the err pointer, and may have set
|
||||
* client_data, so we have to save and restore those fields.
|
||||
* Note: if application hasn't set client_data, tools like Purify may
|
||||
* complain here.
|
||||
*/
|
||||
{
|
||||
struct jpeg_error_mgr * err = cinfo->err;
|
||||
void * client_data = cinfo->client_data; /* ignore Purify complaint here */
|
||||
MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct));
|
||||
cinfo->err = err;
|
||||
cinfo->client_data = client_data;
|
||||
}
|
||||
cinfo->is_decompressor = FALSE;
|
||||
|
||||
/* Initialize a memory manager instance for this object */
|
||||
jinit_memory_mgr((j_common_ptr) cinfo);
|
||||
|
||||
/* Zero out pointers to permanent structures. */
|
||||
cinfo->progress = NULL;
|
||||
cinfo->dest = NULL;
|
||||
|
||||
cinfo->comp_info = NULL;
|
||||
|
||||
for (i = 0; i < NUM_QUANT_TBLS; i++)
|
||||
cinfo->quant_tbl_ptrs[i] = NULL;
|
||||
|
||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
||||
cinfo->dc_huff_tbl_ptrs[i] = NULL;
|
||||
cinfo->ac_huff_tbl_ptrs[i] = NULL;
|
||||
}
|
||||
|
||||
cinfo->script_space = NULL;
|
||||
|
||||
cinfo->input_gamma = 1.0; /* in case application forgets */
|
||||
|
||||
/* OK, I'm ready */
|
||||
cinfo->global_state = CSTATE_START;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Destruction of a JPEG compression object
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_destroy_compress (j_compress_ptr cinfo)
|
||||
{
|
||||
jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Abort processing of a JPEG compression operation,
|
||||
* but don't destroy the object itself.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_abort_compress (j_compress_ptr cinfo)
|
||||
{
|
||||
jpeg_abort((j_common_ptr) cinfo); /* use common routine */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Forcibly suppress or un-suppress all quantization and Huffman tables.
|
||||
* Marks all currently defined tables as already written (if suppress)
|
||||
* or not written (if !suppress). This will control whether they get emitted
|
||||
* by a subsequent jpeg_start_compress call.
|
||||
*
|
||||
* This routine is exported for use by applications that want to produce
|
||||
* abbreviated JPEG datastreams. It logically belongs in jcparam.c, but
|
||||
* since it is called by jpeg_start_compress, we put it here --- otherwise
|
||||
* jcparam.o would be linked whether the application used it or not.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress)
|
||||
{
|
||||
int i;
|
||||
JQUANT_TBL * qtbl;
|
||||
JHUFF_TBL * htbl;
|
||||
|
||||
for (i = 0; i < NUM_QUANT_TBLS; i++) {
|
||||
if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL)
|
||||
qtbl->sent_table = suppress;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
||||
if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL)
|
||||
htbl->sent_table = suppress;
|
||||
if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL)
|
||||
htbl->sent_table = suppress;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish JPEG compression.
|
||||
*
|
||||
* If a multipass operating mode was selected, this may do a great deal of
|
||||
* work including most of the actual output.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_finish_compress (j_compress_ptr cinfo)
|
||||
{
|
||||
JDIMENSION iMCU_row;
|
||||
|
||||
if (cinfo->global_state == CSTATE_SCANNING ||
|
||||
cinfo->global_state == CSTATE_RAW_OK) {
|
||||
/* Terminate first pass */
|
||||
if (cinfo->next_scanline < cinfo->image_height)
|
||||
ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
|
||||
(*cinfo->master->finish_pass) (cinfo);
|
||||
} else if (cinfo->global_state != CSTATE_WRCOEFS)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
/* Perform any remaining passes */
|
||||
while (! cinfo->master->is_last_pass) {
|
||||
(*cinfo->master->prepare_for_pass) (cinfo);
|
||||
for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) {
|
||||
if (cinfo->progress != NULL) {
|
||||
cinfo->progress->pass_counter = (long) iMCU_row;
|
||||
cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows;
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
}
|
||||
/* We bypass the main controller and invoke coef controller directly;
|
||||
* all work is being done from the coefficient buffer.
|
||||
*/
|
||||
if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL))
|
||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
||||
}
|
||||
(*cinfo->master->finish_pass) (cinfo);
|
||||
}
|
||||
/* Write EOI, do final cleanup */
|
||||
(*cinfo->marker->write_file_trailer) (cinfo);
|
||||
(*cinfo->dest->term_destination) (cinfo);
|
||||
/* We can use jpeg_abort to release memory and reset global_state */
|
||||
jpeg_abort((j_common_ptr) cinfo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write a special marker.
|
||||
* This is only recommended for writing COM or APPn markers.
|
||||
* Must be called after jpeg_start_compress() and before
|
||||
* first call to jpeg_write_scanlines() or jpeg_write_raw_data().
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_write_marker (j_compress_ptr cinfo, int marker,
|
||||
const JOCTET *dataptr, unsigned int datalen)
|
||||
{
|
||||
JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val));
|
||||
|
||||
if (cinfo->next_scanline != 0 ||
|
||||
(cinfo->global_state != CSTATE_SCANNING &&
|
||||
cinfo->global_state != CSTATE_RAW_OK &&
|
||||
cinfo->global_state != CSTATE_WRCOEFS))
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
(*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
|
||||
write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */
|
||||
while (datalen--) {
|
||||
(*write_marker_byte) (cinfo, *dataptr);
|
||||
dataptr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Same, but piecemeal. */
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
|
||||
{
|
||||
if (cinfo->next_scanline != 0 ||
|
||||
(cinfo->global_state != CSTATE_SCANNING &&
|
||||
cinfo->global_state != CSTATE_RAW_OK &&
|
||||
cinfo->global_state != CSTATE_WRCOEFS))
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
(*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_write_m_byte (j_compress_ptr cinfo, int val)
|
||||
{
|
||||
(*cinfo->marker->write_marker_byte) (cinfo, val);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Alternate compression function: just write an abbreviated table file.
|
||||
* Before calling this, all parameters and a data destination must be set up.
|
||||
*
|
||||
* To produce a pair of files containing abbreviated tables and abbreviated
|
||||
* image data, one would proceed as follows:
|
||||
*
|
||||
* initialize JPEG object
|
||||
* set JPEG parameters
|
||||
* set destination to table file
|
||||
* jpeg_write_tables(cinfo);
|
||||
* set destination to image file
|
||||
* jpeg_start_compress(cinfo, FALSE);
|
||||
* write data...
|
||||
* jpeg_finish_compress(cinfo);
|
||||
*
|
||||
* jpeg_write_tables has the side effect of marking all tables written
|
||||
* (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress
|
||||
* will not re-emit the tables unless it is passed write_all_tables=TRUE.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_write_tables (j_compress_ptr cinfo)
|
||||
{
|
||||
if (cinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
/* (Re)initialize error mgr and destination modules */
|
||||
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
|
||||
(*cinfo->dest->init_destination) (cinfo);
|
||||
/* Initialize the marker writer ... bit of a crock to do it here. */
|
||||
jinit_marker_writer(cinfo);
|
||||
/* Write them tables! */
|
||||
(*cinfo->marker->write_tables_only) (cinfo);
|
||||
/* And clean up. */
|
||||
(*cinfo->dest->term_destination) (cinfo);
|
||||
/*
|
||||
* In library releases up through v6a, we called jpeg_abort() here to free
|
||||
* any working memory allocated by the destination manager and marker
|
||||
* writer. Some applications had a problem with that: they allocated space
|
||||
* of their own from the library memory manager, and didn't want it to go
|
||||
* away during write_tables. So now we do nothing. This will cause a
|
||||
* memory leak if an app calls write_tables repeatedly without doing a full
|
||||
* compression cycle or otherwise resetting the JPEG object. However, that
|
||||
* seems less bad than unexpectedly freeing memory in the normal case.
|
||||
* An app that prefers the old behavior can call jpeg_abort for itself after
|
||||
* each call to jpeg_write_tables().
|
||||
*/
|
||||
}
|
||||
|
@ -1,161 +1,161 @@
|
||||
/*
|
||||
* jcapistd.c
|
||||
*
|
||||
* Copyright (C) 1994-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 application interface code for the compression half
|
||||
* of the JPEG library. These are the "standard" API routines that are
|
||||
* used in the normal full-compression case. They are not used by a
|
||||
* transcoding-only application. Note that if an application links in
|
||||
* jpeg_start_compress, it will end up linking in the entire compressor.
|
||||
* We thus must separate this file from jcapimin.c to avoid linking the
|
||||
* whole compression library into a transcoder.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/*
|
||||
* Compression initialization.
|
||||
* Before calling this, all parameters and a data destination must be set up.
|
||||
*
|
||||
* We require a write_all_tables parameter as a failsafe check when writing
|
||||
* multiple datastreams from the same compression object. Since prior runs
|
||||
* will have left all the tables marked sent_table=TRUE, a subsequent run
|
||||
* would emit an abbreviated stream (no tables) by default. This may be what
|
||||
* is wanted, but for safety's sake it should not be the default behavior:
|
||||
* programmers should have to make a deliberate choice to emit abbreviated
|
||||
* images. Therefore the documentation and examples should encourage people
|
||||
* to pass write_all_tables=TRUE; then it will take active thought to do the
|
||||
* wrong thing.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
|
||||
{
|
||||
if (cinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
if (write_all_tables)
|
||||
jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */
|
||||
|
||||
/* (Re)initialize error mgr and destination modules */
|
||||
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
|
||||
(*cinfo->dest->init_destination) (cinfo);
|
||||
/* Perform master selection of active modules */
|
||||
jinit_compress_master(cinfo);
|
||||
/* Set up for the first pass */
|
||||
(*cinfo->master->prepare_for_pass) (cinfo);
|
||||
/* Ready for application to drive first pass through jpeg_write_scanlines
|
||||
* or jpeg_write_raw_data.
|
||||
*/
|
||||
cinfo->next_scanline = 0;
|
||||
cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write some scanlines of data to the JPEG compressor.
|
||||
*
|
||||
* The return value will be the number of lines actually written.
|
||||
* This should be less than the supplied num_lines only in case that
|
||||
* the data destination module has requested suspension of the compressor,
|
||||
* or if more than image_height scanlines are passed in.
|
||||
*
|
||||
* Note: we warn about excess calls to jpeg_write_scanlines() since
|
||||
* this likely signals an application programmer error. However,
|
||||
* excess scanlines passed in the last valid call are *silently* ignored,
|
||||
* so that the application need not adjust num_lines for end-of-image
|
||||
* when using a multiple-scanline buffer.
|
||||
*/
|
||||
|
||||
GLOBAL(JDIMENSION)
|
||||
jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
|
||||
JDIMENSION num_lines)
|
||||
{
|
||||
JDIMENSION row_ctr, rows_left;
|
||||
|
||||
if (cinfo->global_state != CSTATE_SCANNING)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
if (cinfo->next_scanline >= cinfo->image_height)
|
||||
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
|
||||
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL) {
|
||||
cinfo->progress->pass_counter = (long) cinfo->next_scanline;
|
||||
cinfo->progress->pass_limit = (long) cinfo->image_height;
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
}
|
||||
|
||||
/* Give master control module another chance if this is first call to
|
||||
* jpeg_write_scanlines. This lets output of the frame/scan headers be
|
||||
* delayed so that application can write COM, etc, markers between
|
||||
* jpeg_start_compress and jpeg_write_scanlines.
|
||||
*/
|
||||
if (cinfo->master->call_pass_startup)
|
||||
(*cinfo->master->pass_startup) (cinfo);
|
||||
|
||||
/* Ignore any extra scanlines at bottom of image. */
|
||||
rows_left = cinfo->image_height - cinfo->next_scanline;
|
||||
if (num_lines > rows_left)
|
||||
num_lines = rows_left;
|
||||
|
||||
row_ctr = 0;
|
||||
(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
|
||||
cinfo->next_scanline += row_ctr;
|
||||
return row_ctr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Alternate entry point to write raw data.
|
||||
* Processes exactly one iMCU row per call, unless suspended.
|
||||
*/
|
||||
|
||||
GLOBAL(JDIMENSION)
|
||||
jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
|
||||
JDIMENSION num_lines)
|
||||
{
|
||||
JDIMENSION lines_per_iMCU_row;
|
||||
|
||||
if (cinfo->global_state != CSTATE_RAW_OK)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
if (cinfo->next_scanline >= cinfo->image_height) {
|
||||
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL) {
|
||||
cinfo->progress->pass_counter = (long) cinfo->next_scanline;
|
||||
cinfo->progress->pass_limit = (long) cinfo->image_height;
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
}
|
||||
|
||||
/* Give master control module another chance if this is first call to
|
||||
* jpeg_write_raw_data. This lets output of the frame/scan headers be
|
||||
* delayed so that application can write COM, etc, markers between
|
||||
* jpeg_start_compress and jpeg_write_raw_data.
|
||||
*/
|
||||
if (cinfo->master->call_pass_startup)
|
||||
(*cinfo->master->pass_startup) (cinfo);
|
||||
|
||||
/* Verify that at least one iMCU row has been passed. */
|
||||
lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
|
||||
if (num_lines < lines_per_iMCU_row)
|
||||
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
||||
|
||||
/* Directly compress the row. */
|
||||
if (! (*cinfo->coef->compress_data) (cinfo, data)) {
|
||||
/* If compressor did not consume the whole row, suspend processing. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* OK, we processed one iMCU row. */
|
||||
cinfo->next_scanline += lines_per_iMCU_row;
|
||||
return lines_per_iMCU_row;
|
||||
}
|
||||
/*
|
||||
* jcapistd.c
|
||||
*
|
||||
* Copyright (C) 1994-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 application interface code for the compression half
|
||||
* of the JPEG library. These are the "standard" API routines that are
|
||||
* used in the normal full-compression case. They are not used by a
|
||||
* transcoding-only application. Note that if an application links in
|
||||
* jpeg_start_compress, it will end up linking in the entire compressor.
|
||||
* We thus must separate this file from jcapimin.c to avoid linking the
|
||||
* whole compression library into a transcoder.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/*
|
||||
* Compression initialization.
|
||||
* Before calling this, all parameters and a data destination must be set up.
|
||||
*
|
||||
* We require a write_all_tables parameter as a failsafe check when writing
|
||||
* multiple datastreams from the same compression object. Since prior runs
|
||||
* will have left all the tables marked sent_table=TRUE, a subsequent run
|
||||
* would emit an abbreviated stream (no tables) by default. This may be what
|
||||
* is wanted, but for safety's sake it should not be the default behavior:
|
||||
* programmers should have to make a deliberate choice to emit abbreviated
|
||||
* images. Therefore the documentation and examples should encourage people
|
||||
* to pass write_all_tables=TRUE; then it will take active thought to do the
|
||||
* wrong thing.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
|
||||
{
|
||||
if (cinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
if (write_all_tables)
|
||||
jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */
|
||||
|
||||
/* (Re)initialize error mgr and destination modules */
|
||||
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
|
||||
(*cinfo->dest->init_destination) (cinfo);
|
||||
/* Perform master selection of active modules */
|
||||
jinit_compress_master(cinfo);
|
||||
/* Set up for the first pass */
|
||||
(*cinfo->master->prepare_for_pass) (cinfo);
|
||||
/* Ready for application to drive first pass through jpeg_write_scanlines
|
||||
* or jpeg_write_raw_data.
|
||||
*/
|
||||
cinfo->next_scanline = 0;
|
||||
cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write some scanlines of data to the JPEG compressor.
|
||||
*
|
||||
* The return value will be the number of lines actually written.
|
||||
* This should be less than the supplied num_lines only in case that
|
||||
* the data destination module has requested suspension of the compressor,
|
||||
* or if more than image_height scanlines are passed in.
|
||||
*
|
||||
* Note: we warn about excess calls to jpeg_write_scanlines() since
|
||||
* this likely signals an application programmer error. However,
|
||||
* excess scanlines passed in the last valid call are *silently* ignored,
|
||||
* so that the application need not adjust num_lines for end-of-image
|
||||
* when using a multiple-scanline buffer.
|
||||
*/
|
||||
|
||||
GLOBAL(JDIMENSION)
|
||||
jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
|
||||
JDIMENSION num_lines)
|
||||
{
|
||||
JDIMENSION row_ctr, rows_left;
|
||||
|
||||
if (cinfo->global_state != CSTATE_SCANNING)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
if (cinfo->next_scanline >= cinfo->image_height)
|
||||
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
|
||||
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL) {
|
||||
cinfo->progress->pass_counter = (long) cinfo->next_scanline;
|
||||
cinfo->progress->pass_limit = (long) cinfo->image_height;
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
}
|
||||
|
||||
/* Give master control module another chance if this is first call to
|
||||
* jpeg_write_scanlines. This lets output of the frame/scan headers be
|
||||
* delayed so that application can write COM, etc, markers between
|
||||
* jpeg_start_compress and jpeg_write_scanlines.
|
||||
*/
|
||||
if (cinfo->master->call_pass_startup)
|
||||
(*cinfo->master->pass_startup) (cinfo);
|
||||
|
||||
/* Ignore any extra scanlines at bottom of image. */
|
||||
rows_left = cinfo->image_height - cinfo->next_scanline;
|
||||
if (num_lines > rows_left)
|
||||
num_lines = rows_left;
|
||||
|
||||
row_ctr = 0;
|
||||
(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
|
||||
cinfo->next_scanline += row_ctr;
|
||||
return row_ctr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Alternate entry point to write raw data.
|
||||
* Processes exactly one iMCU row per call, unless suspended.
|
||||
*/
|
||||
|
||||
GLOBAL(JDIMENSION)
|
||||
jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
|
||||
JDIMENSION num_lines)
|
||||
{
|
||||
JDIMENSION lines_per_iMCU_row;
|
||||
|
||||
if (cinfo->global_state != CSTATE_RAW_OK)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
if (cinfo->next_scanline >= cinfo->image_height) {
|
||||
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL) {
|
||||
cinfo->progress->pass_counter = (long) cinfo->next_scanline;
|
||||
cinfo->progress->pass_limit = (long) cinfo->image_height;
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
}
|
||||
|
||||
/* Give master control module another chance if this is first call to
|
||||
* jpeg_write_raw_data. This lets output of the frame/scan headers be
|
||||
* delayed so that application can write COM, etc, markers between
|
||||
* jpeg_start_compress and jpeg_write_raw_data.
|
||||
*/
|
||||
if (cinfo->master->call_pass_startup)
|
||||
(*cinfo->master->pass_startup) (cinfo);
|
||||
|
||||
/* Verify that at least one iMCU row has been passed. */
|
||||
lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
|
||||
if (num_lines < lines_per_iMCU_row)
|
||||
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
||||
|
||||
/* Directly compress the row. */
|
||||
if (! (*cinfo->coef->compress_data) (cinfo, data)) {
|
||||
/* If compressor did not consume the whole row, suspend processing. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* OK, we processed one iMCU row. */
|
||||
cinfo->next_scanline += lines_per_iMCU_row;
|
||||
return lines_per_iMCU_row;
|
||||
}
|
||||
|
@ -1,449 +1,449 @@
|
||||
/*
|
||||
* jccoefct.c
|
||||
*
|
||||
* Copyright (C) 1994-1997, 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 the coefficient buffer controller for compression.
|
||||
* This controller is the top level of the JPEG compressor proper.
|
||||
* The coefficient buffer lies between forward-DCT and entropy encoding steps.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* We use a full-image coefficient buffer when doing Huffman optimization,
|
||||
* and also for writing multiple-scan JPEG files. In all cases, the DCT
|
||||
* step is run during the first pass, and subsequent passes need only read
|
||||
* the buffered coefficients.
|
||||
*/
|
||||
#ifdef ENTROPY_OPT_SUPPORTED
|
||||
#define FULL_COEF_BUFFER_SUPPORTED
|
||||
#else
|
||||
#ifdef C_MULTISCAN_FILES_SUPPORTED
|
||||
#define FULL_COEF_BUFFER_SUPPORTED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_c_coef_controller pub; /* public fields */
|
||||
|
||||
JDIMENSION iMCU_row_num; /* iMCU row # within image */
|
||||
JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
|
||||
int MCU_vert_offset; /* counts MCU rows within iMCU row */
|
||||
int MCU_rows_per_iMCU_row; /* number of such rows needed */
|
||||
|
||||
/* For single-pass compression, it's sufficient to buffer just one MCU
|
||||
* (although this may prove a bit slow in practice). We allocate a
|
||||
* workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each
|
||||
* MCU constructed and sent. (On 80x86, the workspace is FAR even though
|
||||
* it's not really very big; this is to keep the module interfaces unchanged
|
||||
* when a large coefficient buffer is necessary.)
|
||||
* In multi-pass modes, this array points to the current MCU's blocks
|
||||
* within the virtual arrays.
|
||||
*/
|
||||
JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
|
||||
|
||||
/* In multi-pass modes, we need a virtual block array for each component. */
|
||||
jvirt_barray_ptr whole_image[MAX_COMPONENTS];
|
||||
} my_coef_controller;
|
||||
|
||||
typedef my_coef_controller * my_coef_ptr;
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(boolean) compress_data
|
||||
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
|
||||
#ifdef FULL_COEF_BUFFER_SUPPORTED
|
||||
METHODDEF(boolean) compress_first_pass
|
||||
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
|
||||
METHODDEF(boolean) compress_output
|
||||
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
|
||||
#endif
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
start_iMCU_row (j_compress_ptr cinfo)
|
||||
/* Reset within-iMCU-row counters for a new row */
|
||||
{
|
||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
||||
|
||||
/* In an interleaved scan, an MCU row is the same as an iMCU row.
|
||||
* In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
|
||||
* But at the bottom of the image, process only what's left.
|
||||
*/
|
||||
if (cinfo->comps_in_scan > 1) {
|
||||
coef->MCU_rows_per_iMCU_row = 1;
|
||||
} else {
|
||||
if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
|
||||
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
|
||||
else
|
||||
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
|
||||
}
|
||||
|
||||
coef->mcu_ctr = 0;
|
||||
coef->MCU_vert_offset = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
||||
{
|
||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
||||
|
||||
coef->iMCU_row_num = 0;
|
||||
start_iMCU_row(cinfo);
|
||||
|
||||
switch (pass_mode) {
|
||||
case JBUF_PASS_THRU:
|
||||
if (coef->whole_image[0] != NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
coef->pub.compress_data = compress_data;
|
||||
break;
|
||||
#ifdef FULL_COEF_BUFFER_SUPPORTED
|
||||
case JBUF_SAVE_AND_PASS:
|
||||
if (coef->whole_image[0] == NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
coef->pub.compress_data = compress_first_pass;
|
||||
break;
|
||||
case JBUF_CRANK_DEST:
|
||||
if (coef->whole_image[0] == NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
coef->pub.compress_data = compress_output;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data in the single-pass case.
|
||||
* We process the equivalent of one fully interleaved MCU row ("iMCU" row)
|
||||
* per call, ie, v_samp_factor block rows for each component in the image.
|
||||
* Returns TRUE if the iMCU row is completed, FALSE if suspended.
|
||||
*
|
||||
* NB: input_buf contains a plane for each component in image,
|
||||
* which we index according to the component's SOF position.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
||||
{
|
||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
||||
JDIMENSION MCU_col_num; /* index of current MCU within row */
|
||||
JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
|
||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
||||
int blkn, bi, ci, yindex, yoffset, blockcnt;
|
||||
JDIMENSION ypos, xpos;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Loop to write as much as one whole iMCU row */
|
||||
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
|
||||
yoffset++) {
|
||||
for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
|
||||
MCU_col_num++) {
|
||||
/* Determine where data comes from in input_buf and do the DCT thing.
|
||||
* Each call on forward_DCT processes a horizontal row of DCT blocks
|
||||
* as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks
|
||||
* sequentially. Dummy blocks at the right or bottom edge are filled in
|
||||
* specially. The data in them does not matter for image reconstruction,
|
||||
* so we fill them with values that will encode to the smallest amount of
|
||||
* data, viz: all zeroes in the AC entries, DC entries equal to previous
|
||||
* block's DC value. (Thanks to Thomas Kinsman for this idea.)
|
||||
*/
|
||||
blkn = 0;
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
|
||||
: compptr->last_col_width;
|
||||
xpos = MCU_col_num * compptr->MCU_sample_width;
|
||||
ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */
|
||||
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
|
||||
if (coef->iMCU_row_num < last_iMCU_row ||
|
||||
yoffset+yindex < compptr->last_row_height) {
|
||||
(*cinfo->fdct->forward_DCT) (cinfo, compptr,
|
||||
input_buf[compptr->component_index],
|
||||
coef->MCU_buffer[blkn],
|
||||
ypos, xpos, (JDIMENSION) blockcnt);
|
||||
if (blockcnt < compptr->MCU_width) {
|
||||
/* Create some dummy blocks at the right edge of the image. */
|
||||
jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
|
||||
(compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
|
||||
for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
|
||||
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Create a row of dummy blocks at the bottom of the image. */
|
||||
jzero_far((void FAR *) coef->MCU_buffer[blkn],
|
||||
compptr->MCU_width * SIZEOF(JBLOCK));
|
||||
for (bi = 0; bi < compptr->MCU_width; bi++) {
|
||||
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
|
||||
}
|
||||
}
|
||||
blkn += compptr->MCU_width;
|
||||
ypos += DCTSIZE;
|
||||
}
|
||||
}
|
||||
/* Try to write the MCU. In event of a suspension failure, we will
|
||||
* re-DCT the MCU on restart (a bit inefficient, could be fixed...)
|
||||
*/
|
||||
if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
|
||||
/* Suspension forced; update state counters and exit */
|
||||
coef->MCU_vert_offset = yoffset;
|
||||
coef->mcu_ctr = MCU_col_num;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* Completed an MCU row, but perhaps not an iMCU row */
|
||||
coef->mcu_ctr = 0;
|
||||
}
|
||||
/* Completed the iMCU row, advance counters for next one */
|
||||
coef->iMCU_row_num++;
|
||||
start_iMCU_row(cinfo);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef FULL_COEF_BUFFER_SUPPORTED
|
||||
|
||||
/*
|
||||
* Process some data in the first pass of a multi-pass case.
|
||||
* We process the equivalent of one fully interleaved MCU row ("iMCU" row)
|
||||
* per call, ie, v_samp_factor block rows for each component in the image.
|
||||
* This amount of data is read from the source buffer, DCT'd and quantized,
|
||||
* and saved into the virtual arrays. We also generate suitable dummy blocks
|
||||
* as needed at the right and lower edges. (The dummy blocks are constructed
|
||||
* in the virtual arrays, which have been padded appropriately.) This makes
|
||||
* it possible for subsequent passes not to worry about real vs. dummy blocks.
|
||||
*
|
||||
* We must also emit the data to the entropy encoder. This is conveniently
|
||||
* done by calling compress_output() after we've loaded the current strip
|
||||
* of the virtual arrays.
|
||||
*
|
||||
* NB: input_buf contains a plane for each component in image. All
|
||||
* components are DCT'd and loaded into the virtual arrays in this pass.
|
||||
* However, it may be that only a subset of the components are emitted to
|
||||
* the entropy encoder during this first pass; be careful about looking
|
||||
* at the scan-dependent variables (MCU dimensions, etc).
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
||||
{
|
||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
||||
JDIMENSION blocks_across, MCUs_across, MCUindex;
|
||||
int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
|
||||
JCOEF lastDC;
|
||||
jpeg_component_info *compptr;
|
||||
JBLOCKARRAY buffer;
|
||||
JBLOCKROW thisblockrow, lastblockrow;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Align the virtual buffer for this component. */
|
||||
buffer = (*cinfo->mem->access_virt_barray)
|
||||
((j_common_ptr) cinfo, coef->whole_image[ci],
|
||||
coef->iMCU_row_num * compptr->v_samp_factor,
|
||||
(JDIMENSION) compptr->v_samp_factor, TRUE);
|
||||
/* Count non-dummy DCT block rows in this iMCU row. */
|
||||
if (coef->iMCU_row_num < last_iMCU_row)
|
||||
block_rows = compptr->v_samp_factor;
|
||||
else {
|
||||
/* NB: can't use last_row_height here, since may not be set! */
|
||||
block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
|
||||
if (block_rows == 0) block_rows = compptr->v_samp_factor;
|
||||
}
|
||||
blocks_across = compptr->width_in_blocks;
|
||||
h_samp_factor = compptr->h_samp_factor;
|
||||
/* Count number of dummy blocks to be added at the right margin. */
|
||||
ndummy = (int) (blocks_across % h_samp_factor);
|
||||
if (ndummy > 0)
|
||||
ndummy = h_samp_factor - ndummy;
|
||||
/* Perform DCT for all non-dummy blocks in this iMCU row. Each call
|
||||
* on forward_DCT processes a complete horizontal row of DCT blocks.
|
||||
*/
|
||||
for (block_row = 0; block_row < block_rows; block_row++) {
|
||||
thisblockrow = buffer[block_row];
|
||||
(*cinfo->fdct->forward_DCT) (cinfo, compptr,
|
||||
input_buf[ci], thisblockrow,
|
||||
(JDIMENSION) (block_row * DCTSIZE),
|
||||
(JDIMENSION) 0, blocks_across);
|
||||
if (ndummy > 0) {
|
||||
/* Create dummy blocks at the right edge of the image. */
|
||||
thisblockrow += blocks_across; /* => first dummy block */
|
||||
jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
|
||||
lastDC = thisblockrow[-1][0];
|
||||
for (bi = 0; bi < ndummy; bi++) {
|
||||
thisblockrow[bi][0] = lastDC;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If at end of image, create dummy block rows as needed.
|
||||
* The tricky part here is that within each MCU, we want the DC values
|
||||
* of the dummy blocks to match the last real block's DC value.
|
||||
* This squeezes a few more bytes out of the resulting file...
|
||||
*/
|
||||
if (coef->iMCU_row_num == last_iMCU_row) {
|
||||
blocks_across += ndummy; /* include lower right corner */
|
||||
MCUs_across = blocks_across / h_samp_factor;
|
||||
for (block_row = block_rows; block_row < compptr->v_samp_factor;
|
||||
block_row++) {
|
||||
thisblockrow = buffer[block_row];
|
||||
lastblockrow = buffer[block_row-1];
|
||||
jzero_far((void FAR *) thisblockrow,
|
||||
(size_t) (blocks_across * SIZEOF(JBLOCK)));
|
||||
for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
|
||||
lastDC = lastblockrow[h_samp_factor-1][0];
|
||||
for (bi = 0; bi < h_samp_factor; bi++) {
|
||||
thisblockrow[bi][0] = lastDC;
|
||||
}
|
||||
thisblockrow += h_samp_factor; /* advance to next MCU in row */
|
||||
lastblockrow += h_samp_factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* NB: compress_output will increment iMCU_row_num if successful.
|
||||
* A suspension return will result in redoing all the work above next time.
|
||||
*/
|
||||
|
||||
/* Emit data to the entropy encoder, sharing code with subsequent passes */
|
||||
return compress_output(cinfo, input_buf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data in subsequent passes of a multi-pass case.
|
||||
* We process the equivalent of one fully interleaved MCU row ("iMCU" row)
|
||||
* per call, ie, v_samp_factor block rows for each component in the scan.
|
||||
* The data is obtained from the virtual arrays and fed to the entropy coder.
|
||||
* Returns TRUE if the iMCU row is completed, FALSE if suspended.
|
||||
*
|
||||
* NB: input_buf is ignored; it is likely to be a NULL pointer.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
compress_output (j_compress_ptr cinfo, JSAMPIMAGE)
|
||||
{
|
||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
||||
JDIMENSION MCU_col_num; /* index of current MCU within row */
|
||||
int blkn, ci, xindex, yindex, yoffset;
|
||||
JDIMENSION start_col;
|
||||
JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
|
||||
JBLOCKROW buffer_ptr;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Align the virtual buffers for the components used in this scan.
|
||||
* NB: during first pass, this is safe only because the buffers will
|
||||
* already be aligned properly, so jmemmgr.c won't need to do any I/O.
|
||||
*/
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
buffer[ci] = (*cinfo->mem->access_virt_barray)
|
||||
((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
|
||||
coef->iMCU_row_num * compptr->v_samp_factor,
|
||||
(JDIMENSION) compptr->v_samp_factor, FALSE);
|
||||
}
|
||||
|
||||
/* Loop to process one whole iMCU row */
|
||||
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
|
||||
yoffset++) {
|
||||
for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
|
||||
MCU_col_num++) {
|
||||
/* Construct list of pointers to DCT blocks belonging to this MCU */
|
||||
blkn = 0; /* index of current DCT block within MCU */
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
start_col = MCU_col_num * compptr->MCU_width;
|
||||
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
|
||||
buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
|
||||
for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
|
||||
coef->MCU_buffer[blkn++] = buffer_ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Try to write the MCU. */
|
||||
if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
|
||||
/* Suspension forced; update state counters and exit */
|
||||
coef->MCU_vert_offset = yoffset;
|
||||
coef->mcu_ctr = MCU_col_num;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* Completed an MCU row, but perhaps not an iMCU row */
|
||||
coef->mcu_ctr = 0;
|
||||
}
|
||||
/* Completed the iMCU row, advance counters for next one */
|
||||
coef->iMCU_row_num++;
|
||||
start_iMCU_row(cinfo);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* FULL_COEF_BUFFER_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize coefficient buffer controller.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_coef_ptr coef;
|
||||
|
||||
coef = (my_coef_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_coef_controller));
|
||||
cinfo->coef = (struct jpeg_c_coef_controller *) coef;
|
||||
coef->pub.start_pass = start_pass_coef;
|
||||
|
||||
/* Create the coefficient buffer. */
|
||||
if (need_full_buffer) {
|
||||
#ifdef FULL_COEF_BUFFER_SUPPORTED
|
||||
/* Allocate a full-image virtual array for each component, */
|
||||
/* padded to a multiple of samp_factor DCT blocks in each direction. */
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
|
||||
(JDIMENSION) jround_up((long) compptr->width_in_blocks,
|
||||
(long) compptr->h_samp_factor),
|
||||
(JDIMENSION) jround_up((long) compptr->height_in_blocks,
|
||||
(long) compptr->v_samp_factor),
|
||||
(JDIMENSION) compptr->v_samp_factor);
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
#endif
|
||||
} else {
|
||||
/* We only need a single-MCU buffer. */
|
||||
JBLOCKROW buffer;
|
||||
int i;
|
||||
|
||||
buffer = (JBLOCKROW)
|
||||
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
|
||||
for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
|
||||
coef->MCU_buffer[i] = buffer + i;
|
||||
}
|
||||
coef->whole_image[0] = NULL; /* flag for no virtual arrays */
|
||||
}
|
||||
}
|
||||
/*
|
||||
* jccoefct.c
|
||||
*
|
||||
* Copyright (C) 1994-1997, 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 the coefficient buffer controller for compression.
|
||||
* This controller is the top level of the JPEG compressor proper.
|
||||
* The coefficient buffer lies between forward-DCT and entropy encoding steps.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* We use a full-image coefficient buffer when doing Huffman optimization,
|
||||
* and also for writing multiple-scan JPEG files. In all cases, the DCT
|
||||
* step is run during the first pass, and subsequent passes need only read
|
||||
* the buffered coefficients.
|
||||
*/
|
||||
#ifdef ENTROPY_OPT_SUPPORTED
|
||||
#define FULL_COEF_BUFFER_SUPPORTED
|
||||
#else
|
||||
#ifdef C_MULTISCAN_FILES_SUPPORTED
|
||||
#define FULL_COEF_BUFFER_SUPPORTED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_c_coef_controller pub; /* public fields */
|
||||
|
||||
JDIMENSION iMCU_row_num; /* iMCU row # within image */
|
||||
JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
|
||||
int MCU_vert_offset; /* counts MCU rows within iMCU row */
|
||||
int MCU_rows_per_iMCU_row; /* number of such rows needed */
|
||||
|
||||
/* For single-pass compression, it's sufficient to buffer just one MCU
|
||||
* (although this may prove a bit slow in practice). We allocate a
|
||||
* workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each
|
||||
* MCU constructed and sent. (On 80x86, the workspace is FAR even though
|
||||
* it's not really very big; this is to keep the module interfaces unchanged
|
||||
* when a large coefficient buffer is necessary.)
|
||||
* In multi-pass modes, this array points to the current MCU's blocks
|
||||
* within the virtual arrays.
|
||||
*/
|
||||
JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
|
||||
|
||||
/* In multi-pass modes, we need a virtual block array for each component. */
|
||||
jvirt_barray_ptr whole_image[MAX_COMPONENTS];
|
||||
} my_coef_controller;
|
||||
|
||||
typedef my_coef_controller * my_coef_ptr;
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(boolean) compress_data
|
||||
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
|
||||
#ifdef FULL_COEF_BUFFER_SUPPORTED
|
||||
METHODDEF(boolean) compress_first_pass
|
||||
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
|
||||
METHODDEF(boolean) compress_output
|
||||
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
|
||||
#endif
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
start_iMCU_row (j_compress_ptr cinfo)
|
||||
/* Reset within-iMCU-row counters for a new row */
|
||||
{
|
||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
||||
|
||||
/* In an interleaved scan, an MCU row is the same as an iMCU row.
|
||||
* In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
|
||||
* But at the bottom of the image, process only what's left.
|
||||
*/
|
||||
if (cinfo->comps_in_scan > 1) {
|
||||
coef->MCU_rows_per_iMCU_row = 1;
|
||||
} else {
|
||||
if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
|
||||
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
|
||||
else
|
||||
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
|
||||
}
|
||||
|
||||
coef->mcu_ctr = 0;
|
||||
coef->MCU_vert_offset = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
||||
{
|
||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
||||
|
||||
coef->iMCU_row_num = 0;
|
||||
start_iMCU_row(cinfo);
|
||||
|
||||
switch (pass_mode) {
|
||||
case JBUF_PASS_THRU:
|
||||
if (coef->whole_image[0] != NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
coef->pub.compress_data = compress_data;
|
||||
break;
|
||||
#ifdef FULL_COEF_BUFFER_SUPPORTED
|
||||
case JBUF_SAVE_AND_PASS:
|
||||
if (coef->whole_image[0] == NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
coef->pub.compress_data = compress_first_pass;
|
||||
break;
|
||||
case JBUF_CRANK_DEST:
|
||||
if (coef->whole_image[0] == NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
coef->pub.compress_data = compress_output;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data in the single-pass case.
|
||||
* We process the equivalent of one fully interleaved MCU row ("iMCU" row)
|
||||
* per call, ie, v_samp_factor block rows for each component in the image.
|
||||
* Returns TRUE if the iMCU row is completed, FALSE if suspended.
|
||||
*
|
||||
* NB: input_buf contains a plane for each component in image,
|
||||
* which we index according to the component's SOF position.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
||||
{
|
||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
||||
JDIMENSION MCU_col_num; /* index of current MCU within row */
|
||||
JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
|
||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
||||
int blkn, bi, ci, yindex, yoffset, blockcnt;
|
||||
JDIMENSION ypos, xpos;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Loop to write as much as one whole iMCU row */
|
||||
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
|
||||
yoffset++) {
|
||||
for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
|
||||
MCU_col_num++) {
|
||||
/* Determine where data comes from in input_buf and do the DCT thing.
|
||||
* Each call on forward_DCT processes a horizontal row of DCT blocks
|
||||
* as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks
|
||||
* sequentially. Dummy blocks at the right or bottom edge are filled in
|
||||
* specially. The data in them does not matter for image reconstruction,
|
||||
* so we fill them with values that will encode to the smallest amount of
|
||||
* data, viz: all zeroes in the AC entries, DC entries equal to previous
|
||||
* block's DC value. (Thanks to Thomas Kinsman for this idea.)
|
||||
*/
|
||||
blkn = 0;
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
|
||||
: compptr->last_col_width;
|
||||
xpos = MCU_col_num * compptr->MCU_sample_width;
|
||||
ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */
|
||||
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
|
||||
if (coef->iMCU_row_num < last_iMCU_row ||
|
||||
yoffset+yindex < compptr->last_row_height) {
|
||||
(*cinfo->fdct->forward_DCT) (cinfo, compptr,
|
||||
input_buf[compptr->component_index],
|
||||
coef->MCU_buffer[blkn],
|
||||
ypos, xpos, (JDIMENSION) blockcnt);
|
||||
if (blockcnt < compptr->MCU_width) {
|
||||
/* Create some dummy blocks at the right edge of the image. */
|
||||
jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
|
||||
(compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
|
||||
for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
|
||||
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Create a row of dummy blocks at the bottom of the image. */
|
||||
jzero_far((void FAR *) coef->MCU_buffer[blkn],
|
||||
compptr->MCU_width * SIZEOF(JBLOCK));
|
||||
for (bi = 0; bi < compptr->MCU_width; bi++) {
|
||||
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
|
||||
}
|
||||
}
|
||||
blkn += compptr->MCU_width;
|
||||
ypos += DCTSIZE;
|
||||
}
|
||||
}
|
||||
/* Try to write the MCU. In event of a suspension failure, we will
|
||||
* re-DCT the MCU on restart (a bit inefficient, could be fixed...)
|
||||
*/
|
||||
if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
|
||||
/* Suspension forced; update state counters and exit */
|
||||
coef->MCU_vert_offset = yoffset;
|
||||
coef->mcu_ctr = MCU_col_num;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* Completed an MCU row, but perhaps not an iMCU row */
|
||||
coef->mcu_ctr = 0;
|
||||
}
|
||||
/* Completed the iMCU row, advance counters for next one */
|
||||
coef->iMCU_row_num++;
|
||||
start_iMCU_row(cinfo);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef FULL_COEF_BUFFER_SUPPORTED
|
||||
|
||||
/*
|
||||
* Process some data in the first pass of a multi-pass case.
|
||||
* We process the equivalent of one fully interleaved MCU row ("iMCU" row)
|
||||
* per call, ie, v_samp_factor block rows for each component in the image.
|
||||
* This amount of data is read from the source buffer, DCT'd and quantized,
|
||||
* and saved into the virtual arrays. We also generate suitable dummy blocks
|
||||
* as needed at the right and lower edges. (The dummy blocks are constructed
|
||||
* in the virtual arrays, which have been padded appropriately.) This makes
|
||||
* it possible for subsequent passes not to worry about real vs. dummy blocks.
|
||||
*
|
||||
* We must also emit the data to the entropy encoder. This is conveniently
|
||||
* done by calling compress_output() after we've loaded the current strip
|
||||
* of the virtual arrays.
|
||||
*
|
||||
* NB: input_buf contains a plane for each component in image. All
|
||||
* components are DCT'd and loaded into the virtual arrays in this pass.
|
||||
* However, it may be that only a subset of the components are emitted to
|
||||
* the entropy encoder during this first pass; be careful about looking
|
||||
* at the scan-dependent variables (MCU dimensions, etc).
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
||||
{
|
||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
||||
JDIMENSION blocks_across, MCUs_across, MCUindex;
|
||||
int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
|
||||
JCOEF lastDC;
|
||||
jpeg_component_info *compptr;
|
||||
JBLOCKARRAY buffer;
|
||||
JBLOCKROW thisblockrow, lastblockrow;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Align the virtual buffer for this component. */
|
||||
buffer = (*cinfo->mem->access_virt_barray)
|
||||
((j_common_ptr) cinfo, coef->whole_image[ci],
|
||||
coef->iMCU_row_num * compptr->v_samp_factor,
|
||||
(JDIMENSION) compptr->v_samp_factor, TRUE);
|
||||
/* Count non-dummy DCT block rows in this iMCU row. */
|
||||
if (coef->iMCU_row_num < last_iMCU_row)
|
||||
block_rows = compptr->v_samp_factor;
|
||||
else {
|
||||
/* NB: can't use last_row_height here, since may not be set! */
|
||||
block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
|
||||
if (block_rows == 0) block_rows = compptr->v_samp_factor;
|
||||
}
|
||||
blocks_across = compptr->width_in_blocks;
|
||||
h_samp_factor = compptr->h_samp_factor;
|
||||
/* Count number of dummy blocks to be added at the right margin. */
|
||||
ndummy = (int) (blocks_across % h_samp_factor);
|
||||
if (ndummy > 0)
|
||||
ndummy = h_samp_factor - ndummy;
|
||||
/* Perform DCT for all non-dummy blocks in this iMCU row. Each call
|
||||
* on forward_DCT processes a complete horizontal row of DCT blocks.
|
||||
*/
|
||||
for (block_row = 0; block_row < block_rows; block_row++) {
|
||||
thisblockrow = buffer[block_row];
|
||||
(*cinfo->fdct->forward_DCT) (cinfo, compptr,
|
||||
input_buf[ci], thisblockrow,
|
||||
(JDIMENSION) (block_row * DCTSIZE),
|
||||
(JDIMENSION) 0, blocks_across);
|
||||
if (ndummy > 0) {
|
||||
/* Create dummy blocks at the right edge of the image. */
|
||||
thisblockrow += blocks_across; /* => first dummy block */
|
||||
jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
|
||||
lastDC = thisblockrow[-1][0];
|
||||
for (bi = 0; bi < ndummy; bi++) {
|
||||
thisblockrow[bi][0] = lastDC;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If at end of image, create dummy block rows as needed.
|
||||
* The tricky part here is that within each MCU, we want the DC values
|
||||
* of the dummy blocks to match the last real block's DC value.
|
||||
* This squeezes a few more bytes out of the resulting file...
|
||||
*/
|
||||
if (coef->iMCU_row_num == last_iMCU_row) {
|
||||
blocks_across += ndummy; /* include lower right corner */
|
||||
MCUs_across = blocks_across / h_samp_factor;
|
||||
for (block_row = block_rows; block_row < compptr->v_samp_factor;
|
||||
block_row++) {
|
||||
thisblockrow = buffer[block_row];
|
||||
lastblockrow = buffer[block_row-1];
|
||||
jzero_far((void FAR *) thisblockrow,
|
||||
(size_t) (blocks_across * SIZEOF(JBLOCK)));
|
||||
for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
|
||||
lastDC = lastblockrow[h_samp_factor-1][0];
|
||||
for (bi = 0; bi < h_samp_factor; bi++) {
|
||||
thisblockrow[bi][0] = lastDC;
|
||||
}
|
||||
thisblockrow += h_samp_factor; /* advance to next MCU in row */
|
||||
lastblockrow += h_samp_factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* NB: compress_output will increment iMCU_row_num if successful.
|
||||
* A suspension return will result in redoing all the work above next time.
|
||||
*/
|
||||
|
||||
/* Emit data to the entropy encoder, sharing code with subsequent passes */
|
||||
return compress_output(cinfo, input_buf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data in subsequent passes of a multi-pass case.
|
||||
* We process the equivalent of one fully interleaved MCU row ("iMCU" row)
|
||||
* per call, ie, v_samp_factor block rows for each component in the scan.
|
||||
* The data is obtained from the virtual arrays and fed to the entropy coder.
|
||||
* Returns TRUE if the iMCU row is completed, FALSE if suspended.
|
||||
*
|
||||
* NB: input_buf is ignored; it is likely to be a NULL pointer.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
compress_output (j_compress_ptr cinfo, JSAMPIMAGE)
|
||||
{
|
||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
||||
JDIMENSION MCU_col_num; /* index of current MCU within row */
|
||||
int blkn, ci, xindex, yindex, yoffset;
|
||||
JDIMENSION start_col;
|
||||
JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
|
||||
JBLOCKROW buffer_ptr;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Align the virtual buffers for the components used in this scan.
|
||||
* NB: during first pass, this is safe only because the buffers will
|
||||
* already be aligned properly, so jmemmgr.c won't need to do any I/O.
|
||||
*/
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
buffer[ci] = (*cinfo->mem->access_virt_barray)
|
||||
((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
|
||||
coef->iMCU_row_num * compptr->v_samp_factor,
|
||||
(JDIMENSION) compptr->v_samp_factor, FALSE);
|
||||
}
|
||||
|
||||
/* Loop to process one whole iMCU row */
|
||||
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
|
||||
yoffset++) {
|
||||
for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
|
||||
MCU_col_num++) {
|
||||
/* Construct list of pointers to DCT blocks belonging to this MCU */
|
||||
blkn = 0; /* index of current DCT block within MCU */
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
start_col = MCU_col_num * compptr->MCU_width;
|
||||
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
|
||||
buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
|
||||
for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
|
||||
coef->MCU_buffer[blkn++] = buffer_ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Try to write the MCU. */
|
||||
if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
|
||||
/* Suspension forced; update state counters and exit */
|
||||
coef->MCU_vert_offset = yoffset;
|
||||
coef->mcu_ctr = MCU_col_num;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* Completed an MCU row, but perhaps not an iMCU row */
|
||||
coef->mcu_ctr = 0;
|
||||
}
|
||||
/* Completed the iMCU row, advance counters for next one */
|
||||
coef->iMCU_row_num++;
|
||||
start_iMCU_row(cinfo);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* FULL_COEF_BUFFER_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize coefficient buffer controller.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_coef_ptr coef;
|
||||
|
||||
coef = (my_coef_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_coef_controller));
|
||||
cinfo->coef = (struct jpeg_c_coef_controller *) coef;
|
||||
coef->pub.start_pass = start_pass_coef;
|
||||
|
||||
/* Create the coefficient buffer. */
|
||||
if (need_full_buffer) {
|
||||
#ifdef FULL_COEF_BUFFER_SUPPORTED
|
||||
/* Allocate a full-image virtual array for each component, */
|
||||
/* padded to a multiple of samp_factor DCT blocks in each direction. */
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
|
||||
(JDIMENSION) jround_up((long) compptr->width_in_blocks,
|
||||
(long) compptr->h_samp_factor),
|
||||
(JDIMENSION) jround_up((long) compptr->height_in_blocks,
|
||||
(long) compptr->v_samp_factor),
|
||||
(JDIMENSION) compptr->v_samp_factor);
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
#endif
|
||||
} else {
|
||||
/* We only need a single-MCU buffer. */
|
||||
JBLOCKROW buffer;
|
||||
int i;
|
||||
|
||||
buffer = (JBLOCKROW)
|
||||
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
|
||||
for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
|
||||
coef->MCU_buffer[i] = buffer + i;
|
||||
}
|
||||
coef->whole_image[0] = NULL; /* flag for no virtual arrays */
|
||||
}
|
||||
}
|
||||
|
@ -1,459 +1,459 @@
|
||||
/*
|
||||
* jccolor.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 input colorspace conversion routines.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Private subobject */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_color_converter pub; /* public fields */
|
||||
|
||||
/* Private state for RGB->YCC conversion */
|
||||
INT32 * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */
|
||||
} my_color_converter;
|
||||
|
||||
typedef my_color_converter * my_cconvert_ptr;
|
||||
|
||||
|
||||
/**************** RGB -> YCbCr conversion: most common case **************/
|
||||
|
||||
/*
|
||||
* YCbCr is defined per CCIR 601-1, except that Cb and Cr are
|
||||
* normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
|
||||
* The conversion equations to be implemented are therefore
|
||||
* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
|
||||
* Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
|
||||
* Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
|
||||
* (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
|
||||
* Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
|
||||
* rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and
|
||||
* negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
|
||||
* were not represented exactly. Now we sacrifice exact representation of
|
||||
* maximum red and maximum blue in order to get exact grayscales.
|
||||
*
|
||||
* To avoid floating-point arithmetic, we represent the fractional constants
|
||||
* as integers scaled up by 2^16 (about 4 digits precision); we have to divide
|
||||
* the products by 2^16, with appropriate rounding, to get the correct answer.
|
||||
*
|
||||
* For even more speed, we avoid doing any multiplications in the inner loop
|
||||
* by precalculating the constants times R,G,B for all possible values.
|
||||
* For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
|
||||
* for 12-bit samples it is still acceptable. It's not very reasonable for
|
||||
* 16-bit samples, but if you want lossless storage you shouldn't be changing
|
||||
* colorspace anyway.
|
||||
* The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
|
||||
* in the tables to save adding them separately in the inner loop.
|
||||
*/
|
||||
|
||||
#define SCALEBITS 16 /* speediest right-shift on some machines */
|
||||
#define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS)
|
||||
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
|
||||
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
|
||||
|
||||
/* We allocate one big table and divide it up into eight parts, instead of
|
||||
* doing eight alloc_small requests. This lets us use a single table base
|
||||
* address, which can be held in a register in the inner loops on many
|
||||
* machines (more than can hold all eight addresses, anyway).
|
||||
*/
|
||||
|
||||
#define R_Y_OFF 0 /* offset to R => Y section */
|
||||
#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */
|
||||
#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */
|
||||
#define R_CB_OFF (3*(MAXJSAMPLE+1))
|
||||
#define G_CB_OFF (4*(MAXJSAMPLE+1))
|
||||
#define B_CB_OFF (5*(MAXJSAMPLE+1))
|
||||
#define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */
|
||||
#define G_CR_OFF (6*(MAXJSAMPLE+1))
|
||||
#define B_CR_OFF (7*(MAXJSAMPLE+1))
|
||||
#define TABLE_SIZE (8*(MAXJSAMPLE+1))
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for RGB->YCC colorspace conversion.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
rgb_ycc_start (j_compress_ptr cinfo)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
INT32 * rgb_ycc_tab;
|
||||
INT32 i;
|
||||
|
||||
/* Allocate and fill in the conversion tables. */
|
||||
cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(TABLE_SIZE * SIZEOF(INT32)));
|
||||
|
||||
for (i = 0; i <= MAXJSAMPLE; i++) {
|
||||
rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
|
||||
rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
|
||||
rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
|
||||
rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
|
||||
rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
|
||||
/* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
|
||||
* This ensures that the maximum output will round to MAXJSAMPLE
|
||||
* not MAXJSAMPLE+1, and thus that we don't have to range-limit.
|
||||
*/
|
||||
rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
|
||||
/* B=>Cb and R=>Cr tables are the same
|
||||
rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
|
||||
*/
|
||||
rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
|
||||
rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the JPEG colorspace.
|
||||
*
|
||||
* Note that we change from the application's interleaved-pixel format
|
||||
* to our internal noninterleaved, one-plane-per-component format.
|
||||
* The input buffer is therefore three times as wide as the output buffer.
|
||||
*
|
||||
* A starting row offset is provided only for the output buffer. The caller
|
||||
* can easily adjust the passed input_buf value to accommodate any row
|
||||
* offset required on that side.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
rgb_ycc_convert (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
int r, g, b;
|
||||
INT32 * ctab = cconvert->rgb_ycc_tab;
|
||||
JSAMPROW inptr;
|
||||
JSAMPROW outptr0, outptr1, outptr2;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = *input_buf++;
|
||||
outptr0 = output_buf[0][output_row];
|
||||
outptr1 = output_buf[1][output_row];
|
||||
outptr2 = output_buf[2][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
r = GETJSAMPLE(inptr[RGB_RED]);
|
||||
g = GETJSAMPLE(inptr[RGB_GREEN]);
|
||||
b = GETJSAMPLE(inptr[RGB_BLUE]);
|
||||
inptr += RGB_PIXELSIZE;
|
||||
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
|
||||
* must be too; we do not need an explicit range-limiting operation.
|
||||
* Hence the value being shifted is never negative, and we don't
|
||||
* need the general RIGHT_SHIFT macro.
|
||||
*/
|
||||
/* Y */
|
||||
outptr0[col] = (JSAMPLE)
|
||||
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
|
||||
>> SCALEBITS);
|
||||
/* Cb */
|
||||
outptr1[col] = (JSAMPLE)
|
||||
((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
|
||||
>> SCALEBITS);
|
||||
/* Cr */
|
||||
outptr2[col] = (JSAMPLE)
|
||||
((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
|
||||
>> SCALEBITS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************** Cases other than RGB -> YCbCr **************/
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the JPEG colorspace.
|
||||
* This version handles RGB->grayscale conversion, which is the same
|
||||
* as the RGB->Y portion of RGB->YCbCr.
|
||||
* We assume rgb_ycc_start has been called (we only use the Y tables).
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
rgb_gray_convert (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
int r, g, b;
|
||||
INT32 * ctab = cconvert->rgb_ycc_tab;
|
||||
JSAMPROW inptr;
|
||||
JSAMPROW outptr;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = *input_buf++;
|
||||
outptr = output_buf[0][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
r = GETJSAMPLE(inptr[RGB_RED]);
|
||||
g = GETJSAMPLE(inptr[RGB_GREEN]);
|
||||
b = GETJSAMPLE(inptr[RGB_BLUE]);
|
||||
inptr += RGB_PIXELSIZE;
|
||||
/* Y */
|
||||
outptr[col] = (JSAMPLE)
|
||||
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
|
||||
>> SCALEBITS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the JPEG colorspace.
|
||||
* This version handles Adobe-style CMYK->YCCK conversion,
|
||||
* where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
|
||||
* conversion as above, while passing K (black) unchanged.
|
||||
* We assume rgb_ycc_start has been called.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
cmyk_ycck_convert (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
int r, g, b;
|
||||
INT32 * ctab = cconvert->rgb_ycc_tab;
|
||||
JSAMPROW inptr;
|
||||
JSAMPROW outptr0, outptr1, outptr2, outptr3;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = *input_buf++;
|
||||
outptr0 = output_buf[0][output_row];
|
||||
outptr1 = output_buf[1][output_row];
|
||||
outptr2 = output_buf[2][output_row];
|
||||
outptr3 = output_buf[3][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
|
||||
g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
|
||||
b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
|
||||
/* K passes through as-is */
|
||||
outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
|
||||
inptr += 4;
|
||||
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
|
||||
* must be too; we do not need an explicit range-limiting operation.
|
||||
* Hence the value being shifted is never negative, and we don't
|
||||
* need the general RIGHT_SHIFT macro.
|
||||
*/
|
||||
/* Y */
|
||||
outptr0[col] = (JSAMPLE)
|
||||
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
|
||||
>> SCALEBITS);
|
||||
/* Cb */
|
||||
outptr1[col] = (JSAMPLE)
|
||||
((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
|
||||
>> SCALEBITS);
|
||||
/* Cr */
|
||||
outptr2[col] = (JSAMPLE)
|
||||
((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
|
||||
>> SCALEBITS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the JPEG colorspace.
|
||||
* This version handles grayscale output with no conversion.
|
||||
* The source can be either plain grayscale or YCbCr (since Y == gray).
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
grayscale_convert (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
JSAMPROW inptr;
|
||||
JSAMPROW outptr;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
int instride = cinfo->input_components;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = *input_buf++;
|
||||
outptr = output_buf[0][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
|
||||
inptr += instride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the JPEG colorspace.
|
||||
* This version handles multi-component colorspaces without conversion.
|
||||
* We assume input_components == num_components.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
null_convert (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
JSAMPROW inptr;
|
||||
JSAMPROW outptr;
|
||||
JDIMENSION col;
|
||||
int ci;
|
||||
int nc = cinfo->num_components;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
/* It seems fastest to make a separate pass for each component. */
|
||||
for (ci = 0; ci < nc; ci++) {
|
||||
inptr = *input_buf;
|
||||
outptr = output_buf[ci][output_row];
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
|
||||
inptr += nc;
|
||||
}
|
||||
}
|
||||
input_buf++;
|
||||
output_row++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Empty method for start_pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
null_method (j_compress_ptr)
|
||||
{
|
||||
/* no work needed */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for input colorspace conversion.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_color_converter (j_compress_ptr cinfo)
|
||||
{
|
||||
my_cconvert_ptr cconvert;
|
||||
|
||||
cconvert = (my_cconvert_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_color_converter));
|
||||
cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
|
||||
/* set start_pass to null method until we find out differently */
|
||||
cconvert->pub.start_pass = null_method;
|
||||
|
||||
/* Make sure input_components agrees with in_color_space */
|
||||
switch (cinfo->in_color_space) {
|
||||
case JCS_GRAYSCALE:
|
||||
if (cinfo->input_components != 1)
|
||||
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
|
||||
break;
|
||||
|
||||
case JCS_RGB:
|
||||
#if RGB_PIXELSIZE != 3
|
||||
if (cinfo->input_components != RGB_PIXELSIZE)
|
||||
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
|
||||
break;
|
||||
#endif /* else share code with YCbCr */
|
||||
|
||||
case JCS_YCbCr:
|
||||
if (cinfo->input_components != 3)
|
||||
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
case JCS_YCCK:
|
||||
if (cinfo->input_components != 4)
|
||||
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
|
||||
break;
|
||||
|
||||
default: /* JCS_UNKNOWN can be anything */
|
||||
if (cinfo->input_components < 1)
|
||||
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check num_components, set conversion method based on requested space */
|
||||
switch (cinfo->jpeg_color_space) {
|
||||
case JCS_GRAYSCALE:
|
||||
if (cinfo->num_components != 1)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_GRAYSCALE)
|
||||
cconvert->pub.color_convert = grayscale_convert;
|
||||
else if (cinfo->in_color_space == JCS_RGB) {
|
||||
cconvert->pub.start_pass = rgb_ycc_start;
|
||||
cconvert->pub.color_convert = rgb_gray_convert;
|
||||
} else if (cinfo->in_color_space == JCS_YCbCr)
|
||||
cconvert->pub.color_convert = grayscale_convert;
|
||||
else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_RGB:
|
||||
if (cinfo->num_components != 3)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_YCbCr:
|
||||
if (cinfo->num_components != 3)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_RGB) {
|
||||
cconvert->pub.start_pass = rgb_ycc_start;
|
||||
cconvert->pub.color_convert = rgb_ycc_convert;
|
||||
} else if (cinfo->in_color_space == JCS_YCbCr)
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
if (cinfo->num_components != 4)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_CMYK)
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_YCCK:
|
||||
if (cinfo->num_components != 4)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_CMYK) {
|
||||
cconvert->pub.start_pass = rgb_ycc_start;
|
||||
cconvert->pub.color_convert = cmyk_ycck_convert;
|
||||
} else if (cinfo->in_color_space == JCS_YCCK)
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
default: /* allow null conversion of JCS_UNKNOWN */
|
||||
if (cinfo->jpeg_color_space != cinfo->in_color_space ||
|
||||
cinfo->num_components != cinfo->input_components)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* jccolor.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 input colorspace conversion routines.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Private subobject */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_color_converter pub; /* public fields */
|
||||
|
||||
/* Private state for RGB->YCC conversion */
|
||||
INT32 * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */
|
||||
} my_color_converter;
|
||||
|
||||
typedef my_color_converter * my_cconvert_ptr;
|
||||
|
||||
|
||||
/**************** RGB -> YCbCr conversion: most common case **************/
|
||||
|
||||
/*
|
||||
* YCbCr is defined per CCIR 601-1, except that Cb and Cr are
|
||||
* normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
|
||||
* The conversion equations to be implemented are therefore
|
||||
* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
|
||||
* Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
|
||||
* Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
|
||||
* (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
|
||||
* Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
|
||||
* rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and
|
||||
* negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
|
||||
* were not represented exactly. Now we sacrifice exact representation of
|
||||
* maximum red and maximum blue in order to get exact grayscales.
|
||||
*
|
||||
* To avoid floating-point arithmetic, we represent the fractional constants
|
||||
* as integers scaled up by 2^16 (about 4 digits precision); we have to divide
|
||||
* the products by 2^16, with appropriate rounding, to get the correct answer.
|
||||
*
|
||||
* For even more speed, we avoid doing any multiplications in the inner loop
|
||||
* by precalculating the constants times R,G,B for all possible values.
|
||||
* For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
|
||||
* for 12-bit samples it is still acceptable. It's not very reasonable for
|
||||
* 16-bit samples, but if you want lossless storage you shouldn't be changing
|
||||
* colorspace anyway.
|
||||
* The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
|
||||
* in the tables to save adding them separately in the inner loop.
|
||||
*/
|
||||
|
||||
#define SCALEBITS 16 /* speediest right-shift on some machines */
|
||||
#define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS)
|
||||
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
|
||||
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
|
||||
|
||||
/* We allocate one big table and divide it up into eight parts, instead of
|
||||
* doing eight alloc_small requests. This lets us use a single table base
|
||||
* address, which can be held in a register in the inner loops on many
|
||||
* machines (more than can hold all eight addresses, anyway).
|
||||
*/
|
||||
|
||||
#define R_Y_OFF 0 /* offset to R => Y section */
|
||||
#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */
|
||||
#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */
|
||||
#define R_CB_OFF (3*(MAXJSAMPLE+1))
|
||||
#define G_CB_OFF (4*(MAXJSAMPLE+1))
|
||||
#define B_CB_OFF (5*(MAXJSAMPLE+1))
|
||||
#define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */
|
||||
#define G_CR_OFF (6*(MAXJSAMPLE+1))
|
||||
#define B_CR_OFF (7*(MAXJSAMPLE+1))
|
||||
#define TABLE_SIZE (8*(MAXJSAMPLE+1))
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for RGB->YCC colorspace conversion.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
rgb_ycc_start (j_compress_ptr cinfo)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
INT32 * rgb_ycc_tab;
|
||||
INT32 i;
|
||||
|
||||
/* Allocate and fill in the conversion tables. */
|
||||
cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(TABLE_SIZE * SIZEOF(INT32)));
|
||||
|
||||
for (i = 0; i <= MAXJSAMPLE; i++) {
|
||||
rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
|
||||
rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
|
||||
rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
|
||||
rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
|
||||
rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
|
||||
/* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
|
||||
* This ensures that the maximum output will round to MAXJSAMPLE
|
||||
* not MAXJSAMPLE+1, and thus that we don't have to range-limit.
|
||||
*/
|
||||
rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
|
||||
/* B=>Cb and R=>Cr tables are the same
|
||||
rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
|
||||
*/
|
||||
rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
|
||||
rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the JPEG colorspace.
|
||||
*
|
||||
* Note that we change from the application's interleaved-pixel format
|
||||
* to our internal noninterleaved, one-plane-per-component format.
|
||||
* The input buffer is therefore three times as wide as the output buffer.
|
||||
*
|
||||
* A starting row offset is provided only for the output buffer. The caller
|
||||
* can easily adjust the passed input_buf value to accommodate any row
|
||||
* offset required on that side.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
rgb_ycc_convert (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
int r, g, b;
|
||||
INT32 * ctab = cconvert->rgb_ycc_tab;
|
||||
JSAMPROW inptr;
|
||||
JSAMPROW outptr0, outptr1, outptr2;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = *input_buf++;
|
||||
outptr0 = output_buf[0][output_row];
|
||||
outptr1 = output_buf[1][output_row];
|
||||
outptr2 = output_buf[2][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
r = GETJSAMPLE(inptr[RGB_RED]);
|
||||
g = GETJSAMPLE(inptr[RGB_GREEN]);
|
||||
b = GETJSAMPLE(inptr[RGB_BLUE]);
|
||||
inptr += RGB_PIXELSIZE;
|
||||
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
|
||||
* must be too; we do not need an explicit range-limiting operation.
|
||||
* Hence the value being shifted is never negative, and we don't
|
||||
* need the general RIGHT_SHIFT macro.
|
||||
*/
|
||||
/* Y */
|
||||
outptr0[col] = (JSAMPLE)
|
||||
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
|
||||
>> SCALEBITS);
|
||||
/* Cb */
|
||||
outptr1[col] = (JSAMPLE)
|
||||
((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
|
||||
>> SCALEBITS);
|
||||
/* Cr */
|
||||
outptr2[col] = (JSAMPLE)
|
||||
((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
|
||||
>> SCALEBITS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************** Cases other than RGB -> YCbCr **************/
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the JPEG colorspace.
|
||||
* This version handles RGB->grayscale conversion, which is the same
|
||||
* as the RGB->Y portion of RGB->YCbCr.
|
||||
* We assume rgb_ycc_start has been called (we only use the Y tables).
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
rgb_gray_convert (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
int r, g, b;
|
||||
INT32 * ctab = cconvert->rgb_ycc_tab;
|
||||
JSAMPROW inptr;
|
||||
JSAMPROW outptr;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = *input_buf++;
|
||||
outptr = output_buf[0][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
r = GETJSAMPLE(inptr[RGB_RED]);
|
||||
g = GETJSAMPLE(inptr[RGB_GREEN]);
|
||||
b = GETJSAMPLE(inptr[RGB_BLUE]);
|
||||
inptr += RGB_PIXELSIZE;
|
||||
/* Y */
|
||||
outptr[col] = (JSAMPLE)
|
||||
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
|
||||
>> SCALEBITS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the JPEG colorspace.
|
||||
* This version handles Adobe-style CMYK->YCCK conversion,
|
||||
* where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
|
||||
* conversion as above, while passing K (black) unchanged.
|
||||
* We assume rgb_ycc_start has been called.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
cmyk_ycck_convert (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
int r, g, b;
|
||||
INT32 * ctab = cconvert->rgb_ycc_tab;
|
||||
JSAMPROW inptr;
|
||||
JSAMPROW outptr0, outptr1, outptr2, outptr3;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = *input_buf++;
|
||||
outptr0 = output_buf[0][output_row];
|
||||
outptr1 = output_buf[1][output_row];
|
||||
outptr2 = output_buf[2][output_row];
|
||||
outptr3 = output_buf[3][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
|
||||
g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
|
||||
b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
|
||||
/* K passes through as-is */
|
||||
outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
|
||||
inptr += 4;
|
||||
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
|
||||
* must be too; we do not need an explicit range-limiting operation.
|
||||
* Hence the value being shifted is never negative, and we don't
|
||||
* need the general RIGHT_SHIFT macro.
|
||||
*/
|
||||
/* Y */
|
||||
outptr0[col] = (JSAMPLE)
|
||||
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
|
||||
>> SCALEBITS);
|
||||
/* Cb */
|
||||
outptr1[col] = (JSAMPLE)
|
||||
((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
|
||||
>> SCALEBITS);
|
||||
/* Cr */
|
||||
outptr2[col] = (JSAMPLE)
|
||||
((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
|
||||
>> SCALEBITS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the JPEG colorspace.
|
||||
* This version handles grayscale output with no conversion.
|
||||
* The source can be either plain grayscale or YCbCr (since Y == gray).
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
grayscale_convert (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
JSAMPROW inptr;
|
||||
JSAMPROW outptr;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
int instride = cinfo->input_components;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = *input_buf++;
|
||||
outptr = output_buf[0][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
|
||||
inptr += instride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the JPEG colorspace.
|
||||
* This version handles multi-component colorspaces without conversion.
|
||||
* We assume input_components == num_components.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
null_convert (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
JSAMPROW inptr;
|
||||
JSAMPROW outptr;
|
||||
JDIMENSION col;
|
||||
int ci;
|
||||
int nc = cinfo->num_components;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
/* It seems fastest to make a separate pass for each component. */
|
||||
for (ci = 0; ci < nc; ci++) {
|
||||
inptr = *input_buf;
|
||||
outptr = output_buf[ci][output_row];
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
|
||||
inptr += nc;
|
||||
}
|
||||
}
|
||||
input_buf++;
|
||||
output_row++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Empty method for start_pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
null_method (j_compress_ptr)
|
||||
{
|
||||
/* no work needed */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for input colorspace conversion.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_color_converter (j_compress_ptr cinfo)
|
||||
{
|
||||
my_cconvert_ptr cconvert;
|
||||
|
||||
cconvert = (my_cconvert_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_color_converter));
|
||||
cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
|
||||
/* set start_pass to null method until we find out differently */
|
||||
cconvert->pub.start_pass = null_method;
|
||||
|
||||
/* Make sure input_components agrees with in_color_space */
|
||||
switch (cinfo->in_color_space) {
|
||||
case JCS_GRAYSCALE:
|
||||
if (cinfo->input_components != 1)
|
||||
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
|
||||
break;
|
||||
|
||||
case JCS_RGB:
|
||||
#if RGB_PIXELSIZE != 3
|
||||
if (cinfo->input_components != RGB_PIXELSIZE)
|
||||
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
|
||||
break;
|
||||
#endif /* else share code with YCbCr */
|
||||
|
||||
case JCS_YCbCr:
|
||||
if (cinfo->input_components != 3)
|
||||
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
case JCS_YCCK:
|
||||
if (cinfo->input_components != 4)
|
||||
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
|
||||
break;
|
||||
|
||||
default: /* JCS_UNKNOWN can be anything */
|
||||
if (cinfo->input_components < 1)
|
||||
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check num_components, set conversion method based on requested space */
|
||||
switch (cinfo->jpeg_color_space) {
|
||||
case JCS_GRAYSCALE:
|
||||
if (cinfo->num_components != 1)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_GRAYSCALE)
|
||||
cconvert->pub.color_convert = grayscale_convert;
|
||||
else if (cinfo->in_color_space == JCS_RGB) {
|
||||
cconvert->pub.start_pass = rgb_ycc_start;
|
||||
cconvert->pub.color_convert = rgb_gray_convert;
|
||||
} else if (cinfo->in_color_space == JCS_YCbCr)
|
||||
cconvert->pub.color_convert = grayscale_convert;
|
||||
else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_RGB:
|
||||
if (cinfo->num_components != 3)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_YCbCr:
|
||||
if (cinfo->num_components != 3)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_RGB) {
|
||||
cconvert->pub.start_pass = rgb_ycc_start;
|
||||
cconvert->pub.color_convert = rgb_ycc_convert;
|
||||
} else if (cinfo->in_color_space == JCS_YCbCr)
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
if (cinfo->num_components != 4)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_CMYK)
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_YCCK:
|
||||
if (cinfo->num_components != 4)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_CMYK) {
|
||||
cconvert->pub.start_pass = rgb_ycc_start;
|
||||
cconvert->pub.color_convert = cmyk_ycck_convert;
|
||||
} else if (cinfo->in_color_space == JCS_YCCK)
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
default: /* allow null conversion of JCS_UNKNOWN */
|
||||
if (cinfo->jpeg_color_space != cinfo->in_color_space ||
|
||||
cinfo->num_components != cinfo->input_components)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,387 +1,387 @@
|
||||
/*
|
||||
* jcdctmgr.c
|
||||
*
|
||||
* Copyright (C) 1994-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 the forward-DCT management logic.
|
||||
* This code selects a particular DCT implementation to be used,
|
||||
* and it performs related housekeeping chores including coefficient
|
||||
* quantization.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
|
||||
/* Private subobject for this module */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_forward_dct pub; /* public fields */
|
||||
|
||||
/* Pointer to the DCT routine actually in use */
|
||||
forward_DCT_method_ptr do_dct;
|
||||
|
||||
/* The actual post-DCT divisors --- not identical to the quant table
|
||||
* entries, because of scaling (especially for an unnormalized DCT).
|
||||
* Each table is given in normal array order.
|
||||
*/
|
||||
DCTELEM * divisors[NUM_QUANT_TBLS];
|
||||
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
/* Same as above for the floating-point case. */
|
||||
float_DCT_method_ptr do_float_dct;
|
||||
FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
|
||||
#endif
|
||||
} my_fdct_controller;
|
||||
|
||||
typedef my_fdct_controller * my_fdct_ptr;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
* Verify that all referenced Q-tables are present, and set up
|
||||
* the divisor table for each one.
|
||||
* In the current implementation, DCT of all components is done during
|
||||
* the first pass, even if only some components will be output in the
|
||||
* first scan. Hence all components should be examined here.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_fdctmgr (j_compress_ptr cinfo)
|
||||
{
|
||||
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
|
||||
int ci, qtblno, i;
|
||||
jpeg_component_info *compptr;
|
||||
JQUANT_TBL * qtbl;
|
||||
DCTELEM * dtbl;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
qtblno = compptr->quant_tbl_no;
|
||||
/* Make sure specified quantization table is present */
|
||||
if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
|
||||
cinfo->quant_tbl_ptrs[qtblno] == NULL)
|
||||
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
|
||||
qtbl = cinfo->quant_tbl_ptrs[qtblno];
|
||||
/* Compute divisors for this quant table */
|
||||
/* We may do this more than once for same table, but it's not a big deal */
|
||||
switch (cinfo->dct_method) {
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
case JDCT_ISLOW:
|
||||
/* For LL&M IDCT method, divisors are equal to raw quantization
|
||||
* coefficients multiplied by 8 (to counteract scaling).
|
||||
*/
|
||||
if (fdct->divisors[qtblno] == NULL) {
|
||||
fdct->divisors[qtblno] = (DCTELEM *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
DCTSIZE2 * SIZEOF(DCTELEM));
|
||||
}
|
||||
dtbl = fdct->divisors[qtblno];
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
{
|
||||
/* For AA&N IDCT method, divisors are equal to quantization
|
||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
||||
* scalefactor[0] = 1
|
||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
||||
* We apply a further scale factor of 8.
|
||||
*/
|
||||
#define CONST_BITS 14
|
||||
static const INT16 aanscales[DCTSIZE2] = {
|
||||
/* precomputed values scaled up by 14 bits */
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
|
||||
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
|
||||
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
|
||||
8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
|
||||
4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
|
||||
};
|
||||
SHIFT_TEMPS
|
||||
|
||||
if (fdct->divisors[qtblno] == NULL) {
|
||||
fdct->divisors[qtblno] = (DCTELEM *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
DCTSIZE2 * SIZEOF(DCTELEM));
|
||||
}
|
||||
dtbl = fdct->divisors[qtblno];
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
dtbl[i] = (DCTELEM)
|
||||
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
|
||||
(INT32) aanscales[i]),
|
||||
CONST_BITS-3);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
{
|
||||
/* For float AA&N IDCT method, divisors are equal to quantization
|
||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
||||
* scalefactor[0] = 1
|
||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
||||
* We apply a further scale factor of 8.
|
||||
* What's actually stored is 1/divisor so that the inner loop can
|
||||
* use a multiplication rather than a division.
|
||||
*/
|
||||
FAST_FLOAT * fdtbl;
|
||||
int row, col;
|
||||
static const double aanscalefactor[DCTSIZE] = {
|
||||
1.0, 1.387039845, 1.306562965, 1.175875602,
|
||||
1.0, 0.785694958, 0.541196100, 0.275899379
|
||||
};
|
||||
|
||||
if (fdct->float_divisors[qtblno] == NULL) {
|
||||
fdct->float_divisors[qtblno] = (FAST_FLOAT *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
DCTSIZE2 * SIZEOF(FAST_FLOAT));
|
||||
}
|
||||
fdtbl = fdct->float_divisors[qtblno];
|
||||
i = 0;
|
||||
for (row = 0; row < DCTSIZE; row++) {
|
||||
for (col = 0; col < DCTSIZE; col++) {
|
||||
fdtbl[i] = (FAST_FLOAT)
|
||||
(1.0 / (((double) qtbl->quantval[i] *
|
||||
aanscalefactor[row] * aanscalefactor[col] * 8.0)));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform forward DCT on one or more blocks of a component.
|
||||
*
|
||||
* The input samples are taken from the sample_data[] array starting at
|
||||
* position start_row/start_col, and moving to the right for any additional
|
||||
* blocks. The quantized coefficients are returned in coef_blocks[].
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks)
|
||||
/* This version is used for integer DCT implementations. */
|
||||
{
|
||||
/* This routine is heavily used, so it's worth coding it tightly. */
|
||||
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
|
||||
forward_DCT_method_ptr do_dct = fdct->do_dct;
|
||||
DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
|
||||
DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */
|
||||
JDIMENSION bi;
|
||||
|
||||
sample_data += start_row; /* fold in the vertical offset once */
|
||||
|
||||
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
|
||||
/* Load data into workspace, applying unsigned->signed conversion */
|
||||
{ DCTELEM *workspaceptr;
|
||||
JSAMPROW elemptr;
|
||||
int elemr;
|
||||
|
||||
workspaceptr = workspace;
|
||||
for (elemr = 0; elemr < DCTSIZE; elemr++) {
|
||||
elemptr = sample_data[elemr] + start_col;
|
||||
#if DCTSIZE == 8 /* unroll the inner loop */
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
#else
|
||||
{ int elemc;
|
||||
for (elemc = DCTSIZE; elemc > 0; elemc--) {
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform the DCT */
|
||||
(*do_dct) (workspace);
|
||||
|
||||
/* Quantize/descale the coefficients, and store into coef_blocks[] */
|
||||
{ DCTELEM temp, qval;
|
||||
int i;
|
||||
JCOEFPTR output_ptr = coef_blocks[bi];
|
||||
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
qval = divisors[i];
|
||||
temp = workspace[i];
|
||||
/* Divide the coefficient value by qval, ensuring proper rounding.
|
||||
* Since C does not specify the direction of rounding for negative
|
||||
* quotients, we have to force the dividend positive for portability.
|
||||
*
|
||||
* In most files, at least half of the output values will be zero
|
||||
* (at default quantization settings, more like three-quarters...)
|
||||
* so we should ensure that this case is fast. On many machines,
|
||||
* a comparison is enough cheaper than a divide to make a special test
|
||||
* a win. Since both inputs will be nonnegative, we need only test
|
||||
* for a < b to discover whether a/b is 0.
|
||||
* If your machine's division is fast enough, define FAST_DIVIDE.
|
||||
*/
|
||||
#ifdef FAST_DIVIDE
|
||||
#define DIVIDE_BY(a,b) a /= b
|
||||
#else
|
||||
#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0
|
||||
#endif
|
||||
if (temp < 0) {
|
||||
temp = -temp;
|
||||
temp += qval>>1; /* for rounding */
|
||||
DIVIDE_BY(temp, qval);
|
||||
temp = -temp;
|
||||
} else {
|
||||
temp += qval>>1; /* for rounding */
|
||||
DIVIDE_BY(temp, qval);
|
||||
}
|
||||
output_ptr[i] = (JCOEF) temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
|
||||
METHODDEF(void)
|
||||
forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks)
|
||||
/* This version is used for floating-point DCT implementations. */
|
||||
{
|
||||
/* This routine is heavily used, so it's worth coding it tightly. */
|
||||
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
|
||||
float_DCT_method_ptr do_dct = fdct->do_float_dct;
|
||||
FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
|
||||
FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
|
||||
JDIMENSION bi;
|
||||
|
||||
sample_data += start_row; /* fold in the vertical offset once */
|
||||
|
||||
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
|
||||
/* Load data into workspace, applying unsigned->signed conversion */
|
||||
{ FAST_FLOAT *workspaceptr;
|
||||
JSAMPROW elemptr;
|
||||
int elemr;
|
||||
|
||||
workspaceptr = workspace;
|
||||
for (elemr = 0; elemr < DCTSIZE; elemr++) {
|
||||
elemptr = sample_data[elemr] + start_col;
|
||||
#if DCTSIZE == 8 /* unroll the inner loop */
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
#else
|
||||
{ int elemc;
|
||||
for (elemc = DCTSIZE; elemc > 0; elemc--) {
|
||||
*workspaceptr++ = (FAST_FLOAT)
|
||||
(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform the DCT */
|
||||
(*do_dct) (workspace);
|
||||
|
||||
/* Quantize/descale the coefficients, and store into coef_blocks[] */
|
||||
{ FAST_FLOAT temp;
|
||||
int i;
|
||||
JCOEFPTR output_ptr = coef_blocks[bi];
|
||||
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
/* Apply the quantization and scaling factor */
|
||||
temp = workspace[i] * divisors[i];
|
||||
/* Round to nearest integer.
|
||||
* Since C does not specify the direction of rounding for negative
|
||||
* quotients, we have to force the dividend positive for portability.
|
||||
* The maximum coefficient size is +-16K (for 12-bit data), so this
|
||||
* code should work for either 16-bit or 32-bit ints.
|
||||
*/
|
||||
output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_FLOAT_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize FDCT manager.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_forward_dct (j_compress_ptr cinfo)
|
||||
{
|
||||
my_fdct_ptr fdct;
|
||||
int i;
|
||||
|
||||
fdct = (my_fdct_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_fdct_controller));
|
||||
cinfo->fdct = (struct jpeg_forward_dct *) fdct;
|
||||
fdct->pub.start_pass = start_pass_fdctmgr;
|
||||
|
||||
switch (cinfo->dct_method) {
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
case JDCT_ISLOW:
|
||||
fdct->pub.forward_DCT = forward_DCT;
|
||||
fdct->do_dct = jpeg_fdct_islow;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
fdct->pub.forward_DCT = forward_DCT;
|
||||
fdct->do_dct = jpeg_fdct_ifast;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
fdct->pub.forward_DCT = forward_DCT_float;
|
||||
fdct->do_float_dct = jpeg_fdct_float;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Mark divisor tables unallocated */
|
||||
for (i = 0; i < NUM_QUANT_TBLS; i++) {
|
||||
fdct->divisors[i] = NULL;
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
fdct->float_divisors[i] = NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*
|
||||
* jcdctmgr.c
|
||||
*
|
||||
* Copyright (C) 1994-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 the forward-DCT management logic.
|
||||
* This code selects a particular DCT implementation to be used,
|
||||
* and it performs related housekeeping chores including coefficient
|
||||
* quantization.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
|
||||
/* Private subobject for this module */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_forward_dct pub; /* public fields */
|
||||
|
||||
/* Pointer to the DCT routine actually in use */
|
||||
forward_DCT_method_ptr do_dct;
|
||||
|
||||
/* The actual post-DCT divisors --- not identical to the quant table
|
||||
* entries, because of scaling (especially for an unnormalized DCT).
|
||||
* Each table is given in normal array order.
|
||||
*/
|
||||
DCTELEM * divisors[NUM_QUANT_TBLS];
|
||||
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
/* Same as above for the floating-point case. */
|
||||
float_DCT_method_ptr do_float_dct;
|
||||
FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
|
||||
#endif
|
||||
} my_fdct_controller;
|
||||
|
||||
typedef my_fdct_controller * my_fdct_ptr;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
* Verify that all referenced Q-tables are present, and set up
|
||||
* the divisor table for each one.
|
||||
* In the current implementation, DCT of all components is done during
|
||||
* the first pass, even if only some components will be output in the
|
||||
* first scan. Hence all components should be examined here.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_fdctmgr (j_compress_ptr cinfo)
|
||||
{
|
||||
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
|
||||
int ci, qtblno, i;
|
||||
jpeg_component_info *compptr;
|
||||
JQUANT_TBL * qtbl;
|
||||
DCTELEM * dtbl;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
qtblno = compptr->quant_tbl_no;
|
||||
/* Make sure specified quantization table is present */
|
||||
if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
|
||||
cinfo->quant_tbl_ptrs[qtblno] == NULL)
|
||||
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
|
||||
qtbl = cinfo->quant_tbl_ptrs[qtblno];
|
||||
/* Compute divisors for this quant table */
|
||||
/* We may do this more than once for same table, but it's not a big deal */
|
||||
switch (cinfo->dct_method) {
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
case JDCT_ISLOW:
|
||||
/* For LL&M IDCT method, divisors are equal to raw quantization
|
||||
* coefficients multiplied by 8 (to counteract scaling).
|
||||
*/
|
||||
if (fdct->divisors[qtblno] == NULL) {
|
||||
fdct->divisors[qtblno] = (DCTELEM *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
DCTSIZE2 * SIZEOF(DCTELEM));
|
||||
}
|
||||
dtbl = fdct->divisors[qtblno];
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
{
|
||||
/* For AA&N IDCT method, divisors are equal to quantization
|
||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
||||
* scalefactor[0] = 1
|
||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
||||
* We apply a further scale factor of 8.
|
||||
*/
|
||||
#define CONST_BITS 14
|
||||
static const INT16 aanscales[DCTSIZE2] = {
|
||||
/* precomputed values scaled up by 14 bits */
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
|
||||
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
|
||||
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
|
||||
8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
|
||||
4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
|
||||
};
|
||||
SHIFT_TEMPS
|
||||
|
||||
if (fdct->divisors[qtblno] == NULL) {
|
||||
fdct->divisors[qtblno] = (DCTELEM *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
DCTSIZE2 * SIZEOF(DCTELEM));
|
||||
}
|
||||
dtbl = fdct->divisors[qtblno];
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
dtbl[i] = (DCTELEM)
|
||||
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
|
||||
(INT32) aanscales[i]),
|
||||
CONST_BITS-3);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
{
|
||||
/* For float AA&N IDCT method, divisors are equal to quantization
|
||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
||||
* scalefactor[0] = 1
|
||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
||||
* We apply a further scale factor of 8.
|
||||
* What's actually stored is 1/divisor so that the inner loop can
|
||||
* use a multiplication rather than a division.
|
||||
*/
|
||||
FAST_FLOAT * fdtbl;
|
||||
int row, col;
|
||||
static const double aanscalefactor[DCTSIZE] = {
|
||||
1.0, 1.387039845, 1.306562965, 1.175875602,
|
||||
1.0, 0.785694958, 0.541196100, 0.275899379
|
||||
};
|
||||
|
||||
if (fdct->float_divisors[qtblno] == NULL) {
|
||||
fdct->float_divisors[qtblno] = (FAST_FLOAT *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
DCTSIZE2 * SIZEOF(FAST_FLOAT));
|
||||
}
|
||||
fdtbl = fdct->float_divisors[qtblno];
|
||||
i = 0;
|
||||
for (row = 0; row < DCTSIZE; row++) {
|
||||
for (col = 0; col < DCTSIZE; col++) {
|
||||
fdtbl[i] = (FAST_FLOAT)
|
||||
(1.0 / (((double) qtbl->quantval[i] *
|
||||
aanscalefactor[row] * aanscalefactor[col] * 8.0)));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform forward DCT on one or more blocks of a component.
|
||||
*
|
||||
* The input samples are taken from the sample_data[] array starting at
|
||||
* position start_row/start_col, and moving to the right for any additional
|
||||
* blocks. The quantized coefficients are returned in coef_blocks[].
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks)
|
||||
/* This version is used for integer DCT implementations. */
|
||||
{
|
||||
/* This routine is heavily used, so it's worth coding it tightly. */
|
||||
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
|
||||
forward_DCT_method_ptr do_dct = fdct->do_dct;
|
||||
DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
|
||||
DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */
|
||||
JDIMENSION bi;
|
||||
|
||||
sample_data += start_row; /* fold in the vertical offset once */
|
||||
|
||||
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
|
||||
/* Load data into workspace, applying unsigned->signed conversion */
|
||||
{ DCTELEM *workspaceptr;
|
||||
JSAMPROW elemptr;
|
||||
int elemr;
|
||||
|
||||
workspaceptr = workspace;
|
||||
for (elemr = 0; elemr < DCTSIZE; elemr++) {
|
||||
elemptr = sample_data[elemr] + start_col;
|
||||
#if DCTSIZE == 8 /* unroll the inner loop */
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
#else
|
||||
{ int elemc;
|
||||
for (elemc = DCTSIZE; elemc > 0; elemc--) {
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform the DCT */
|
||||
(*do_dct) (workspace);
|
||||
|
||||
/* Quantize/descale the coefficients, and store into coef_blocks[] */
|
||||
{ DCTELEM temp, qval;
|
||||
int i;
|
||||
JCOEFPTR output_ptr = coef_blocks[bi];
|
||||
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
qval = divisors[i];
|
||||
temp = workspace[i];
|
||||
/* Divide the coefficient value by qval, ensuring proper rounding.
|
||||
* Since C does not specify the direction of rounding for negative
|
||||
* quotients, we have to force the dividend positive for portability.
|
||||
*
|
||||
* In most files, at least half of the output values will be zero
|
||||
* (at default quantization settings, more like three-quarters...)
|
||||
* so we should ensure that this case is fast. On many machines,
|
||||
* a comparison is enough cheaper than a divide to make a special test
|
||||
* a win. Since both inputs will be nonnegative, we need only test
|
||||
* for a < b to discover whether a/b is 0.
|
||||
* If your machine's division is fast enough, define FAST_DIVIDE.
|
||||
*/
|
||||
#ifdef FAST_DIVIDE
|
||||
#define DIVIDE_BY(a,b) a /= b
|
||||
#else
|
||||
#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0
|
||||
#endif
|
||||
if (temp < 0) {
|
||||
temp = -temp;
|
||||
temp += qval>>1; /* for rounding */
|
||||
DIVIDE_BY(temp, qval);
|
||||
temp = -temp;
|
||||
} else {
|
||||
temp += qval>>1; /* for rounding */
|
||||
DIVIDE_BY(temp, qval);
|
||||
}
|
||||
output_ptr[i] = (JCOEF) temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
|
||||
METHODDEF(void)
|
||||
forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks)
|
||||
/* This version is used for floating-point DCT implementations. */
|
||||
{
|
||||
/* This routine is heavily used, so it's worth coding it tightly. */
|
||||
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
|
||||
float_DCT_method_ptr do_dct = fdct->do_float_dct;
|
||||
FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
|
||||
FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
|
||||
JDIMENSION bi;
|
||||
|
||||
sample_data += start_row; /* fold in the vertical offset once */
|
||||
|
||||
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
|
||||
/* Load data into workspace, applying unsigned->signed conversion */
|
||||
{ FAST_FLOAT *workspaceptr;
|
||||
JSAMPROW elemptr;
|
||||
int elemr;
|
||||
|
||||
workspaceptr = workspace;
|
||||
for (elemr = 0; elemr < DCTSIZE; elemr++) {
|
||||
elemptr = sample_data[elemr] + start_col;
|
||||
#if DCTSIZE == 8 /* unroll the inner loop */
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
#else
|
||||
{ int elemc;
|
||||
for (elemc = DCTSIZE; elemc > 0; elemc--) {
|
||||
*workspaceptr++ = (FAST_FLOAT)
|
||||
(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform the DCT */
|
||||
(*do_dct) (workspace);
|
||||
|
||||
/* Quantize/descale the coefficients, and store into coef_blocks[] */
|
||||
{ FAST_FLOAT temp;
|
||||
int i;
|
||||
JCOEFPTR output_ptr = coef_blocks[bi];
|
||||
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
/* Apply the quantization and scaling factor */
|
||||
temp = workspace[i] * divisors[i];
|
||||
/* Round to nearest integer.
|
||||
* Since C does not specify the direction of rounding for negative
|
||||
* quotients, we have to force the dividend positive for portability.
|
||||
* The maximum coefficient size is +-16K (for 12-bit data), so this
|
||||
* code should work for either 16-bit or 32-bit ints.
|
||||
*/
|
||||
output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_FLOAT_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize FDCT manager.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_forward_dct (j_compress_ptr cinfo)
|
||||
{
|
||||
my_fdct_ptr fdct;
|
||||
int i;
|
||||
|
||||
fdct = (my_fdct_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_fdct_controller));
|
||||
cinfo->fdct = (struct jpeg_forward_dct *) fdct;
|
||||
fdct->pub.start_pass = start_pass_fdctmgr;
|
||||
|
||||
switch (cinfo->dct_method) {
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
case JDCT_ISLOW:
|
||||
fdct->pub.forward_DCT = forward_DCT;
|
||||
fdct->do_dct = jpeg_fdct_islow;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
fdct->pub.forward_DCT = forward_DCT;
|
||||
fdct->do_dct = jpeg_fdct_ifast;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
fdct->pub.forward_DCT = forward_DCT_float;
|
||||
fdct->do_float_dct = jpeg_fdct_float;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Mark divisor tables unallocated */
|
||||
for (i = 0; i < NUM_QUANT_TBLS; i++) {
|
||||
fdct->divisors[i] = NULL;
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
fdct->float_divisors[i] = NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,52 +1,52 @@
|
||||
/*
|
||||
* jchuff.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 declarations for Huffman entropy encoding routines
|
||||
* that are shared between the sequential encoder (jchuff.c) and the
|
||||
* progressive encoder (jcphuff.c). No other modules need to see these.
|
||||
*/
|
||||
|
||||
/* The legal range of a DCT coefficient is
|
||||
* -1024 .. +1023 for 8-bit data;
|
||||
* -16384 .. +16383 for 12-bit data.
|
||||
* Hence the magnitude should always fit in 10 or 14 bits respectively.
|
||||
*/
|
||||
|
||||
#ifndef _jchuff_h_
|
||||
#define _jchuff_h_
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define MAX_COEF_BITS 10
|
||||
#else
|
||||
#define MAX_COEF_BITS 14
|
||||
#endif
|
||||
|
||||
/* Derived data constructed for each Huffman table */
|
||||
|
||||
typedef struct {
|
||||
unsigned int ehufco[256]; /* code for each symbol */
|
||||
char ehufsi[256]; /* length of code for each symbol */
|
||||
/* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */
|
||||
} c_derived_tbl;
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jpeg_make_c_derived_tbl jMkCDerived
|
||||
#define jpeg_gen_optimal_table jGenOptTbl
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
/* Expand a Huffman table definition into the derived format */
|
||||
EXTERN(void) jpeg_make_c_derived_tbl
|
||||
JPP((j_compress_ptr cinfo, boolean isDC, int tblno,
|
||||
c_derived_tbl ** pdtbl));
|
||||
|
||||
/* Generate an optimal table definition given the specified counts */
|
||||
EXTERN(void) jpeg_gen_optimal_table
|
||||
JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]));
|
||||
|
||||
#endif
|
||||
/*
|
||||
* jchuff.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 declarations for Huffman entropy encoding routines
|
||||
* that are shared between the sequential encoder (jchuff.c) and the
|
||||
* progressive encoder (jcphuff.c). No other modules need to see these.
|
||||
*/
|
||||
|
||||
/* The legal range of a DCT coefficient is
|
||||
* -1024 .. +1023 for 8-bit data;
|
||||
* -16384 .. +16383 for 12-bit data.
|
||||
* Hence the magnitude should always fit in 10 or 14 bits respectively.
|
||||
*/
|
||||
|
||||
#ifndef _jchuff_h_
|
||||
#define _jchuff_h_
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define MAX_COEF_BITS 10
|
||||
#else
|
||||
#define MAX_COEF_BITS 14
|
||||
#endif
|
||||
|
||||
/* Derived data constructed for each Huffman table */
|
||||
|
||||
typedef struct {
|
||||
unsigned int ehufco[256]; /* code for each symbol */
|
||||
char ehufsi[256]; /* length of code for each symbol */
|
||||
/* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */
|
||||
} c_derived_tbl;
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jpeg_make_c_derived_tbl jMkCDerived
|
||||
#define jpeg_gen_optimal_table jGenOptTbl
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
/* Expand a Huffman table definition into the derived format */
|
||||
EXTERN(void) jpeg_make_c_derived_tbl
|
||||
JPP((j_compress_ptr cinfo, boolean isDC, int tblno,
|
||||
c_derived_tbl ** pdtbl));
|
||||
|
||||
/* Generate an optimal table definition given the specified counts */
|
||||
EXTERN(void) jpeg_gen_optimal_table
|
||||
JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]));
|
||||
|
||||
#endif
|
||||
|
@ -1,72 +1,72 @@
|
||||
/*
|
||||
* jcinit.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 initialization logic for the JPEG compressor.
|
||||
* This routine is in charge of selecting the modules to be executed and
|
||||
* making an initialization call to each one.
|
||||
*
|
||||
* Logically, this code belongs in jcmaster.c. It's split out because
|
||||
* linking this routine implies linking the entire compression library.
|
||||
* For a transcoding-only application, we want to be able to use jcmaster.c
|
||||
* without linking in the whole library.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/*
|
||||
* Master selection of compression modules.
|
||||
* This is done once at the start of processing an image. We determine
|
||||
* which modules will be used and give them appropriate initialization calls.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_compress_master (j_compress_ptr cinfo)
|
||||
{
|
||||
/* Initialize master control (includes parameter checking/processing) */
|
||||
jinit_c_master_control(cinfo, FALSE /* full compression */);
|
||||
|
||||
/* Preprocessing */
|
||||
if (! cinfo->raw_data_in) {
|
||||
jinit_color_converter(cinfo);
|
||||
jinit_downsampler(cinfo);
|
||||
jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */);
|
||||
}
|
||||
/* Forward DCT */
|
||||
jinit_forward_dct(cinfo);
|
||||
/* Entropy encoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
} else {
|
||||
if (cinfo->progressive_mode) {
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
jinit_phuff_encoder(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else
|
||||
jinit_huff_encoder(cinfo);
|
||||
}
|
||||
|
||||
/* Need a full-image coefficient buffer in any multi-pass mode. */
|
||||
jinit_c_coef_controller(cinfo,
|
||||
(boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding));
|
||||
jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
|
||||
|
||||
jinit_marker_writer(cinfo);
|
||||
|
||||
/* We can now tell the memory manager to allocate virtual arrays. */
|
||||
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
|
||||
|
||||
/* Write the datastream header (SOI) immediately.
|
||||
* Frame and scan headers are postponed till later.
|
||||
* This lets application insert special markers after the SOI.
|
||||
*/
|
||||
(*cinfo->marker->write_file_header) (cinfo);
|
||||
}
|
||||
/*
|
||||
* jcinit.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 initialization logic for the JPEG compressor.
|
||||
* This routine is in charge of selecting the modules to be executed and
|
||||
* making an initialization call to each one.
|
||||
*
|
||||
* Logically, this code belongs in jcmaster.c. It's split out because
|
||||
* linking this routine implies linking the entire compression library.
|
||||
* For a transcoding-only application, we want to be able to use jcmaster.c
|
||||
* without linking in the whole library.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/*
|
||||
* Master selection of compression modules.
|
||||
* This is done once at the start of processing an image. We determine
|
||||
* which modules will be used and give them appropriate initialization calls.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_compress_master (j_compress_ptr cinfo)
|
||||
{
|
||||
/* Initialize master control (includes parameter checking/processing) */
|
||||
jinit_c_master_control(cinfo, FALSE /* full compression */);
|
||||
|
||||
/* Preprocessing */
|
||||
if (! cinfo->raw_data_in) {
|
||||
jinit_color_converter(cinfo);
|
||||
jinit_downsampler(cinfo);
|
||||
jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */);
|
||||
}
|
||||
/* Forward DCT */
|
||||
jinit_forward_dct(cinfo);
|
||||
/* Entropy encoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
} else {
|
||||
if (cinfo->progressive_mode) {
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
jinit_phuff_encoder(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else
|
||||
jinit_huff_encoder(cinfo);
|
||||
}
|
||||
|
||||
/* Need a full-image coefficient buffer in any multi-pass mode. */
|
||||
jinit_c_coef_controller(cinfo,
|
||||
(boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding));
|
||||
jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
|
||||
|
||||
jinit_marker_writer(cinfo);
|
||||
|
||||
/* We can now tell the memory manager to allocate virtual arrays. */
|
||||
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
|
||||
|
||||
/* Write the datastream header (SOI) immediately.
|
||||
* Frame and scan headers are postponed till later.
|
||||
* This lets application insert special markers after the SOI.
|
||||
*/
|
||||
(*cinfo->marker->write_file_header) (cinfo);
|
||||
}
|
||||
|
@ -1,293 +1,293 @@
|
||||
/*
|
||||
* jcmainct.c
|
||||
*
|
||||
* Copyright (C) 1994-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 the main buffer controller for compression.
|
||||
* The main buffer lies between the pre-processor and the JPEG
|
||||
* compressor proper; it holds downsampled data in the JPEG colorspace.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Note: currently, there is no operating mode in which a full-image buffer
|
||||
* is needed at this step. If there were, that mode could not be used with
|
||||
* "raw data" input, since this module is bypassed in that case. However,
|
||||
* we've left the code here for possible use in special applications.
|
||||
*/
|
||||
#undef FULL_MAIN_BUFFER_SUPPORTED
|
||||
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_c_main_controller pub; /* public fields */
|
||||
|
||||
JDIMENSION cur_iMCU_row; /* number of current iMCU row */
|
||||
JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */
|
||||
boolean suspended; /* remember if we suspended output */
|
||||
J_BUF_MODE pass_mode; /* current operating mode */
|
||||
|
||||
/* If using just a strip buffer, this points to the entire set of buffers
|
||||
* (we allocate one for each component). In the full-image case, this
|
||||
* points to the currently accessible strips of the virtual arrays.
|
||||
*/
|
||||
JSAMPARRAY buffer[MAX_COMPONENTS];
|
||||
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
/* If using full-image storage, this array holds pointers to virtual-array
|
||||
* control blocks for each component. Unused if not full-image storage.
|
||||
*/
|
||||
jvirt_sarray_ptr whole_image[MAX_COMPONENTS];
|
||||
#endif
|
||||
} my_main_controller;
|
||||
|
||||
typedef my_main_controller * my_main_ptr;
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(void) process_data_simple_main
|
||||
JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
METHODDEF(void) process_data_buffer_main
|
||||
JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
||||
{
|
||||
my_main_ptr main_ = (my_main_ptr) cinfo->main;
|
||||
|
||||
/* Do nothing in raw-data mode. */
|
||||
if (cinfo->raw_data_in)
|
||||
return;
|
||||
|
||||
main_->cur_iMCU_row = 0; /* initialize counters */
|
||||
main_->rowgroup_ctr = 0;
|
||||
main_->suspended = FALSE;
|
||||
main_->pass_mode = pass_mode; /* save mode for use by process_data */
|
||||
|
||||
switch (pass_mode) {
|
||||
case JBUF_PASS_THRU:
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
if (main_->whole_image[0] != NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
#endif
|
||||
main_->pub.process_data = process_data_simple_main;
|
||||
break;
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
case JBUF_SAVE_SOURCE:
|
||||
case JBUF_CRANK_DEST:
|
||||
case JBUF_SAVE_AND_PASS:
|
||||
if (main_->whole_image[0] == NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
main_->pub.process_data = process_data_buffer_main;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data.
|
||||
* This routine handles the simple pass-through mode,
|
||||
* where we have only a strip buffer.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
process_data_simple_main (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail)
|
||||
{
|
||||
my_main_ptr main_ = (my_main_ptr) cinfo->main;
|
||||
|
||||
while (main_->cur_iMCU_row < cinfo->total_iMCU_rows) {
|
||||
/* Read input data if we haven't filled the main buffer yet */
|
||||
if (main_->rowgroup_ctr < DCTSIZE)
|
||||
(*cinfo->prep->pre_process_data) (cinfo,
|
||||
input_buf, in_row_ctr, in_rows_avail,
|
||||
main_->buffer, &main_->rowgroup_ctr,
|
||||
(JDIMENSION) DCTSIZE);
|
||||
|
||||
/* If we don't have a full iMCU row buffered, return to application for
|
||||
* more data. Note that preprocessor will always pad to fill the iMCU row
|
||||
* at the bottom of the image.
|
||||
*/
|
||||
if (main_->rowgroup_ctr != DCTSIZE)
|
||||
return;
|
||||
|
||||
/* Send the completed row to the compressor */
|
||||
if (! (*cinfo->coef->compress_data) (cinfo, main_->buffer)) {
|
||||
/* If compressor did not consume the whole row, then we must need to
|
||||
* suspend processing and return to the application. In this situation
|
||||
* we pretend we didn't yet consume the last input row; otherwise, if
|
||||
* it happened to be the last row of the image, the application would
|
||||
* think we were done.
|
||||
*/
|
||||
if (! main_->suspended) {
|
||||
(*in_row_ctr)--;
|
||||
main_->suspended = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* We did finish the row. Undo our little suspension hack if a previous
|
||||
* call suspended; then mark the main buffer empty.
|
||||
*/
|
||||
if (main_->suspended) {
|
||||
(*in_row_ctr)++;
|
||||
main_->suspended = FALSE;
|
||||
}
|
||||
main_->rowgroup_ctr = 0;
|
||||
main_->cur_iMCU_row++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
|
||||
/*
|
||||
* Process some data.
|
||||
* This routine handles all of the modes that use a full-size buffer.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
process_data_buffer_main (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail)
|
||||
{
|
||||
my_main_ptr main = (my_main_ptr) cinfo->main;
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
boolean writing = (main->pass_mode != JBUF_CRANK_DEST);
|
||||
|
||||
while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
|
||||
/* Realign the virtual buffers if at the start of an iMCU row. */
|
||||
if (main->rowgroup_ctr == 0) {
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
main->buffer[ci] = (*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr) cinfo, main->whole_image[ci],
|
||||
main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
|
||||
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing);
|
||||
}
|
||||
/* In a read pass, pretend we just read some source data. */
|
||||
if (! writing) {
|
||||
*in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE;
|
||||
main->rowgroup_ctr = DCTSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If a write pass, read input data until the current iMCU row is full. */
|
||||
/* Note: preprocessor will pad if necessary to fill the last iMCU row. */
|
||||
if (writing) {
|
||||
(*cinfo->prep->pre_process_data) (cinfo,
|
||||
input_buf, in_row_ctr, in_rows_avail,
|
||||
main->buffer, &main->rowgroup_ctr,
|
||||
(JDIMENSION) DCTSIZE);
|
||||
/* Return to application if we need more data to fill the iMCU row. */
|
||||
if (main->rowgroup_ctr < DCTSIZE)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Emit data, unless this is a sink-only pass. */
|
||||
if (main->pass_mode != JBUF_SAVE_SOURCE) {
|
||||
if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) {
|
||||
/* If compressor did not consume the whole row, then we must need to
|
||||
* suspend processing and return to the application. In this situation
|
||||
* we pretend we didn't yet consume the last input row; otherwise, if
|
||||
* it happened to be the last row of the image, the application would
|
||||
* think we were done.
|
||||
*/
|
||||
if (! main->suspended) {
|
||||
(*in_row_ctr)--;
|
||||
main->suspended = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* We did finish the row. Undo our little suspension hack if a previous
|
||||
* call suspended; then mark the main buffer empty.
|
||||
*/
|
||||
if (main->suspended) {
|
||||
(*in_row_ctr)++;
|
||||
main->suspended = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If get here, we are done with this iMCU row. Mark buffer empty. */
|
||||
main->rowgroup_ctr = 0;
|
||||
main->cur_iMCU_row++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FULL_MAIN_BUFFER_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize main buffer controller.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_main_ptr main_;
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
main_ = (my_main_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_main_controller));
|
||||
cinfo->main = (struct jpeg_c_main_controller *) main_;
|
||||
main_->pub.start_pass = start_pass_main;
|
||||
|
||||
/* We don't need to create a buffer in raw-data mode. */
|
||||
if (cinfo->raw_data_in)
|
||||
return;
|
||||
|
||||
/* Create the buffer. It holds downsampled data, so each component
|
||||
* may be of a different size.
|
||||
*/
|
||||
if (need_full_buffer) {
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
/* Allocate a full-image virtual array for each component */
|
||||
/* Note we pad the bottom to a multiple of the iMCU height */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
main->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
|
||||
compptr->width_in_blocks * DCTSIZE,
|
||||
(JDIMENSION) jround_up((long) compptr->height_in_blocks,
|
||||
(long) compptr->v_samp_factor) * DCTSIZE,
|
||||
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
main_->whole_image[0] = NULL; /* flag for no virtual arrays */
|
||||
#endif
|
||||
/* Allocate a strip buffer for each component */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
main_->buffer[ci] = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
compptr->width_in_blocks * DCTSIZE,
|
||||
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* jcmainct.c
|
||||
*
|
||||
* Copyright (C) 1994-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 the main buffer controller for compression.
|
||||
* The main buffer lies between the pre-processor and the JPEG
|
||||
* compressor proper; it holds downsampled data in the JPEG colorspace.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Note: currently, there is no operating mode in which a full-image buffer
|
||||
* is needed at this step. If there were, that mode could not be used with
|
||||
* "raw data" input, since this module is bypassed in that case. However,
|
||||
* we've left the code here for possible use in special applications.
|
||||
*/
|
||||
#undef FULL_MAIN_BUFFER_SUPPORTED
|
||||
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_c_main_controller pub; /* public fields */
|
||||
|
||||
JDIMENSION cur_iMCU_row; /* number of current iMCU row */
|
||||
JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */
|
||||
boolean suspended; /* remember if we suspended output */
|
||||
J_BUF_MODE pass_mode; /* current operating mode */
|
||||
|
||||
/* If using just a strip buffer, this points to the entire set of buffers
|
||||
* (we allocate one for each component). In the full-image case, this
|
||||
* points to the currently accessible strips of the virtual arrays.
|
||||
*/
|
||||
JSAMPARRAY buffer[MAX_COMPONENTS];
|
||||
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
/* If using full-image storage, this array holds pointers to virtual-array
|
||||
* control blocks for each component. Unused if not full-image storage.
|
||||
*/
|
||||
jvirt_sarray_ptr whole_image[MAX_COMPONENTS];
|
||||
#endif
|
||||
} my_main_controller;
|
||||
|
||||
typedef my_main_controller * my_main_ptr;
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(void) process_data_simple_main
|
||||
JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
METHODDEF(void) process_data_buffer_main
|
||||
JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
||||
{
|
||||
my_main_ptr main_ = (my_main_ptr) cinfo->main;
|
||||
|
||||
/* Do nothing in raw-data mode. */
|
||||
if (cinfo->raw_data_in)
|
||||
return;
|
||||
|
||||
main_->cur_iMCU_row = 0; /* initialize counters */
|
||||
main_->rowgroup_ctr = 0;
|
||||
main_->suspended = FALSE;
|
||||
main_->pass_mode = pass_mode; /* save mode for use by process_data */
|
||||
|
||||
switch (pass_mode) {
|
||||
case JBUF_PASS_THRU:
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
if (main_->whole_image[0] != NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
#endif
|
||||
main_->pub.process_data = process_data_simple_main;
|
||||
break;
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
case JBUF_SAVE_SOURCE:
|
||||
case JBUF_CRANK_DEST:
|
||||
case JBUF_SAVE_AND_PASS:
|
||||
if (main_->whole_image[0] == NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
main_->pub.process_data = process_data_buffer_main;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data.
|
||||
* This routine handles the simple pass-through mode,
|
||||
* where we have only a strip buffer.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
process_data_simple_main (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail)
|
||||
{
|
||||
my_main_ptr main_ = (my_main_ptr) cinfo->main;
|
||||
|
||||
while (main_->cur_iMCU_row < cinfo->total_iMCU_rows) {
|
||||
/* Read input data if we haven't filled the main buffer yet */
|
||||
if (main_->rowgroup_ctr < DCTSIZE)
|
||||
(*cinfo->prep->pre_process_data) (cinfo,
|
||||
input_buf, in_row_ctr, in_rows_avail,
|
||||
main_->buffer, &main_->rowgroup_ctr,
|
||||
(JDIMENSION) DCTSIZE);
|
||||
|
||||
/* If we don't have a full iMCU row buffered, return to application for
|
||||
* more data. Note that preprocessor will always pad to fill the iMCU row
|
||||
* at the bottom of the image.
|
||||
*/
|
||||
if (main_->rowgroup_ctr != DCTSIZE)
|
||||
return;
|
||||
|
||||
/* Send the completed row to the compressor */
|
||||
if (! (*cinfo->coef->compress_data) (cinfo, main_->buffer)) {
|
||||
/* If compressor did not consume the whole row, then we must need to
|
||||
* suspend processing and return to the application. In this situation
|
||||
* we pretend we didn't yet consume the last input row; otherwise, if
|
||||
* it happened to be the last row of the image, the application would
|
||||
* think we were done.
|
||||
*/
|
||||
if (! main_->suspended) {
|
||||
(*in_row_ctr)--;
|
||||
main_->suspended = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* We did finish the row. Undo our little suspension hack if a previous
|
||||
* call suspended; then mark the main buffer empty.
|
||||
*/
|
||||
if (main_->suspended) {
|
||||
(*in_row_ctr)++;
|
||||
main_->suspended = FALSE;
|
||||
}
|
||||
main_->rowgroup_ctr = 0;
|
||||
main_->cur_iMCU_row++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
|
||||
/*
|
||||
* Process some data.
|
||||
* This routine handles all of the modes that use a full-size buffer.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
process_data_buffer_main (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail)
|
||||
{
|
||||
my_main_ptr main = (my_main_ptr) cinfo->main;
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
boolean writing = (main->pass_mode != JBUF_CRANK_DEST);
|
||||
|
||||
while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
|
||||
/* Realign the virtual buffers if at the start of an iMCU row. */
|
||||
if (main->rowgroup_ctr == 0) {
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
main->buffer[ci] = (*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr) cinfo, main->whole_image[ci],
|
||||
main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
|
||||
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing);
|
||||
}
|
||||
/* In a read pass, pretend we just read some source data. */
|
||||
if (! writing) {
|
||||
*in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE;
|
||||
main->rowgroup_ctr = DCTSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If a write pass, read input data until the current iMCU row is full. */
|
||||
/* Note: preprocessor will pad if necessary to fill the last iMCU row. */
|
||||
if (writing) {
|
||||
(*cinfo->prep->pre_process_data) (cinfo,
|
||||
input_buf, in_row_ctr, in_rows_avail,
|
||||
main->buffer, &main->rowgroup_ctr,
|
||||
(JDIMENSION) DCTSIZE);
|
||||
/* Return to application if we need more data to fill the iMCU row. */
|
||||
if (main->rowgroup_ctr < DCTSIZE)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Emit data, unless this is a sink-only pass. */
|
||||
if (main->pass_mode != JBUF_SAVE_SOURCE) {
|
||||
if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) {
|
||||
/* If compressor did not consume the whole row, then we must need to
|
||||
* suspend processing and return to the application. In this situation
|
||||
* we pretend we didn't yet consume the last input row; otherwise, if
|
||||
* it happened to be the last row of the image, the application would
|
||||
* think we were done.
|
||||
*/
|
||||
if (! main->suspended) {
|
||||
(*in_row_ctr)--;
|
||||
main->suspended = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* We did finish the row. Undo our little suspension hack if a previous
|
||||
* call suspended; then mark the main buffer empty.
|
||||
*/
|
||||
if (main->suspended) {
|
||||
(*in_row_ctr)++;
|
||||
main->suspended = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If get here, we are done with this iMCU row. Mark buffer empty. */
|
||||
main->rowgroup_ctr = 0;
|
||||
main->cur_iMCU_row++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FULL_MAIN_BUFFER_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize main buffer controller.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_main_ptr main_;
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
main_ = (my_main_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_main_controller));
|
||||
cinfo->main = (struct jpeg_c_main_controller *) main_;
|
||||
main_->pub.start_pass = start_pass_main;
|
||||
|
||||
/* We don't need to create a buffer in raw-data mode. */
|
||||
if (cinfo->raw_data_in)
|
||||
return;
|
||||
|
||||
/* Create the buffer. It holds downsampled data, so each component
|
||||
* may be of a different size.
|
||||
*/
|
||||
if (need_full_buffer) {
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
/* Allocate a full-image virtual array for each component */
|
||||
/* Note we pad the bottom to a multiple of the iMCU height */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
main->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
|
||||
compptr->width_in_blocks * DCTSIZE,
|
||||
(JDIMENSION) jround_up((long) compptr->height_in_blocks,
|
||||
(long) compptr->v_samp_factor) * DCTSIZE,
|
||||
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef FULL_MAIN_BUFFER_SUPPORTED
|
||||
main_->whole_image[0] = NULL; /* flag for no virtual arrays */
|
||||
#endif
|
||||
/* Allocate a strip buffer for each component */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
main_->buffer[ci] = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
compptr->width_in_blocks * DCTSIZE,
|
||||
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,106 +1,106 @@
|
||||
/*
|
||||
* jcomapi.c
|
||||
*
|
||||
* Copyright (C) 1994-1997, 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 application interface routines that are used for both
|
||||
* compression and decompression.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/*
|
||||
* Abort processing of a JPEG compression or decompression operation,
|
||||
* but don't destroy the object itself.
|
||||
*
|
||||
* For this, we merely clean up all the nonpermanent memory pools.
|
||||
* Note that temp files (virtual arrays) are not allowed to belong to
|
||||
* the permanent pool, so we will be able to close all temp files here.
|
||||
* Closing a data source or destination, if necessary, is the application's
|
||||
* responsibility.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_abort (j_common_ptr cinfo)
|
||||
{
|
||||
int pool;
|
||||
|
||||
/* Do nothing if called on a not-initialized or destroyed JPEG object. */
|
||||
if (cinfo->mem == NULL)
|
||||
return;
|
||||
|
||||
/* Releasing pools in reverse order might help avoid fragmentation
|
||||
* with some (brain-damaged) malloc libraries.
|
||||
*/
|
||||
for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) {
|
||||
(*cinfo->mem->free_pool) (cinfo, pool);
|
||||
}
|
||||
|
||||
/* Reset overall state for possible reuse of object */
|
||||
if (cinfo->is_decompressor) {
|
||||
cinfo->global_state = DSTATE_START;
|
||||
/* Try to keep application from accessing now-deleted marker list.
|
||||
* A bit kludgy to do it here, but this is the most central place.
|
||||
*/
|
||||
((j_decompress_ptr) cinfo)->marker_list = NULL;
|
||||
} else {
|
||||
cinfo->global_state = CSTATE_START;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Destruction of a JPEG object.
|
||||
*
|
||||
* Everything gets deallocated except the master jpeg_compress_struct itself
|
||||
* and the error manager struct. Both of these are supplied by the application
|
||||
* and must be freed, if necessary, by the application. (Often they are on
|
||||
* the stack and so don't need to be freed anyway.)
|
||||
* Closing a data source or destination, if necessary, is the application's
|
||||
* responsibility.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_destroy (j_common_ptr cinfo)
|
||||
{
|
||||
/* We need only tell the memory manager to release everything. */
|
||||
/* NB: mem pointer is NULL if memory mgr failed to initialize. */
|
||||
if (cinfo->mem != NULL)
|
||||
(*cinfo->mem->self_destruct) (cinfo);
|
||||
cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */
|
||||
cinfo->global_state = 0; /* mark it destroyed */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convenience routines for allocating quantization and Huffman tables.
|
||||
* (Would jutils.c be a more reasonable place to put these?)
|
||||
*/
|
||||
|
||||
GLOBAL(JQUANT_TBL *)
|
||||
jpeg_alloc_quant_table (j_common_ptr cinfo)
|
||||
{
|
||||
JQUANT_TBL *tbl;
|
||||
|
||||
tbl = (JQUANT_TBL *)
|
||||
(*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL));
|
||||
tbl->sent_table = FALSE; /* make sure this is false in any new table */
|
||||
return tbl;
|
||||
}
|
||||
|
||||
|
||||
GLOBAL(JHUFF_TBL *)
|
||||
jpeg_alloc_huff_table (j_common_ptr cinfo)
|
||||
{
|
||||
JHUFF_TBL *tbl;
|
||||
|
||||
tbl = (JHUFF_TBL *)
|
||||
(*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL));
|
||||
tbl->sent_table = FALSE; /* make sure this is false in any new table */
|
||||
return tbl;
|
||||
}
|
||||
/*
|
||||
* jcomapi.c
|
||||
*
|
||||
* Copyright (C) 1994-1997, 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 application interface routines that are used for both
|
||||
* compression and decompression.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/*
|
||||
* Abort processing of a JPEG compression or decompression operation,
|
||||
* but don't destroy the object itself.
|
||||
*
|
||||
* For this, we merely clean up all the nonpermanent memory pools.
|
||||
* Note that temp files (virtual arrays) are not allowed to belong to
|
||||
* the permanent pool, so we will be able to close all temp files here.
|
||||
* Closing a data source or destination, if necessary, is the application's
|
||||
* responsibility.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_abort (j_common_ptr cinfo)
|
||||
{
|
||||
int pool;
|
||||
|
||||
/* Do nothing if called on a not-initialized or destroyed JPEG object. */
|
||||
if (cinfo->mem == NULL)
|
||||
return;
|
||||
|
||||
/* Releasing pools in reverse order might help avoid fragmentation
|
||||
* with some (brain-damaged) malloc libraries.
|
||||
*/
|
||||
for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) {
|
||||
(*cinfo->mem->free_pool) (cinfo, pool);
|
||||
}
|
||||
|
||||
/* Reset overall state for possible reuse of object */
|
||||
if (cinfo->is_decompressor) {
|
||||
cinfo->global_state = DSTATE_START;
|
||||
/* Try to keep application from accessing now-deleted marker list.
|
||||
* A bit kludgy to do it here, but this is the most central place.
|
||||
*/
|
||||
((j_decompress_ptr) cinfo)->marker_list = NULL;
|
||||
} else {
|
||||
cinfo->global_state = CSTATE_START;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Destruction of a JPEG object.
|
||||
*
|
||||
* Everything gets deallocated except the master jpeg_compress_struct itself
|
||||
* and the error manager struct. Both of these are supplied by the application
|
||||
* and must be freed, if necessary, by the application. (Often they are on
|
||||
* the stack and so don't need to be freed anyway.)
|
||||
* Closing a data source or destination, if necessary, is the application's
|
||||
* responsibility.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_destroy (j_common_ptr cinfo)
|
||||
{
|
||||
/* We need only tell the memory manager to release everything. */
|
||||
/* NB: mem pointer is NULL if memory mgr failed to initialize. */
|
||||
if (cinfo->mem != NULL)
|
||||
(*cinfo->mem->self_destruct) (cinfo);
|
||||
cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */
|
||||
cinfo->global_state = 0; /* mark it destroyed */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convenience routines for allocating quantization and Huffman tables.
|
||||
* (Would jutils.c be a more reasonable place to put these?)
|
||||
*/
|
||||
|
||||
GLOBAL(JQUANT_TBL *)
|
||||
jpeg_alloc_quant_table (j_common_ptr cinfo)
|
||||
{
|
||||
JQUANT_TBL *tbl;
|
||||
|
||||
tbl = (JQUANT_TBL *)
|
||||
(*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL));
|
||||
tbl->sent_table = FALSE; /* make sure this is false in any new table */
|
||||
return tbl;
|
||||
}
|
||||
|
||||
|
||||
GLOBAL(JHUFF_TBL *)
|
||||
jpeg_alloc_huff_table (j_common_ptr cinfo)
|
||||
{
|
||||
JHUFF_TBL *tbl;
|
||||
|
||||
tbl = (JHUFF_TBL *)
|
||||
(*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL));
|
||||
tbl->sent_table = FALSE; /* make sure this is false in any new table */
|
||||
return tbl;
|
||||
}
|
||||
|
@ -1,59 +1,59 @@
|
||||
/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */
|
||||
/* see jconfig.doc for explanations */
|
||||
|
||||
// disable all the warnings under MSVC
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4996 4267 4100 4127 4702 4244)
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma warn -8057
|
||||
#pragma warn -8019
|
||||
#pragma warn -8004
|
||||
#pragma warn -8008
|
||||
#endif
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
/* #define void char */
|
||||
/* #define const */
|
||||
#undef CHAR_IS_UNSIGNED
|
||||
#define HAVE_STDDEF_H
|
||||
#ifndef HAVE_STDLIB_H
|
||||
#define HAVE_STDLIB_H
|
||||
#endif
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#undef NEED_FAR_POINTERS /* we presume a 32-bit flat memory model */
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
/* Define "boolean" as unsigned char, not int, per Windows custom */
|
||||
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
|
||||
typedef unsigned char boolean;
|
||||
#endif
|
||||
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
|
||||
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#define TWO_FILE_COMMANDLINE /* optional */
|
||||
#define USE_SETMODE /* Microsoft has setmode() */
|
||||
#undef NEED_SIGNAL_CATCHER
|
||||
#undef DONT_USE_B_MODE
|
||||
#undef PROGRESS_REPORT /* optional */
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
||||
/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */
|
||||
/* see jconfig.doc for explanations */
|
||||
|
||||
// disable all the warnings under MSVC
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4996 4267 4100 4127 4702 4244)
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma warn -8057
|
||||
#pragma warn -8019
|
||||
#pragma warn -8004
|
||||
#pragma warn -8008
|
||||
#endif
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
/* #define void char */
|
||||
/* #define const */
|
||||
#undef CHAR_IS_UNSIGNED
|
||||
#define HAVE_STDDEF_H
|
||||
#ifndef HAVE_STDLIB_H
|
||||
#define HAVE_STDLIB_H
|
||||
#endif
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#undef NEED_FAR_POINTERS /* we presume a 32-bit flat memory model */
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
/* Define "boolean" as unsigned char, not int, per Windows custom */
|
||||
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
|
||||
typedef unsigned char boolean;
|
||||
#endif
|
||||
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
|
||||
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#define TWO_FILE_COMMANDLINE /* optional */
|
||||
#define USE_SETMODE /* Microsoft has setmode() */
|
||||
#undef NEED_SIGNAL_CATCHER
|
||||
#undef DONT_USE_B_MODE
|
||||
#undef PROGRESS_REPORT /* optional */
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,354 +1,354 @@
|
||||
/*
|
||||
* jcprepct.c
|
||||
*
|
||||
* Copyright (C) 1994-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 the compression preprocessing controller.
|
||||
* This controller manages the color conversion, downsampling,
|
||||
* and edge expansion steps.
|
||||
*
|
||||
* Most of the complexity here is associated with buffering input rows
|
||||
* as required by the downsampler. See the comments at the head of
|
||||
* jcsample.c for the downsampler's needs.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* At present, jcsample.c can request context rows only for smoothing.
|
||||
* In the future, we might also need context rows for CCIR601 sampling
|
||||
* or other more-complex downsampling procedures. The code to support
|
||||
* context rows should be compiled only if needed.
|
||||
*/
|
||||
#ifdef INPUT_SMOOTHING_SUPPORTED
|
||||
#define CONTEXT_ROWS_SUPPORTED
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* For the simple (no-context-row) case, we just need to buffer one
|
||||
* row group's worth of pixels for the downsampling step. At the bottom of
|
||||
* the image, we pad to a full row group by replicating the last pixel row.
|
||||
* The downsampler's last output row is then replicated if needed to pad
|
||||
* out to a full iMCU row.
|
||||
*
|
||||
* When providing context rows, we must buffer three row groups' worth of
|
||||
* pixels. Three row groups are physically allocated, but the row pointer
|
||||
* arrays are made five row groups high, with the extra pointers above and
|
||||
* below "wrapping around" to point to the last and first real row groups.
|
||||
* This allows the downsampler to access the proper context rows.
|
||||
* At the top and bottom of the image, we create dummy context rows by
|
||||
* copying the first or last real pixel row. This copying could be avoided
|
||||
* by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the
|
||||
* trouble on the compression side.
|
||||
*/
|
||||
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_c_prep_controller pub; /* public fields */
|
||||
|
||||
/* Downsampling input buffer. This buffer holds color-converted data
|
||||
* until we have enough to do a downsample step.
|
||||
*/
|
||||
JSAMPARRAY color_buf[MAX_COMPONENTS];
|
||||
|
||||
JDIMENSION rows_to_go; /* counts rows remaining in source image */
|
||||
int next_buf_row; /* index of next row to store in color_buf */
|
||||
|
||||
#ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */
|
||||
int this_row_group; /* starting row index of group to process */
|
||||
int next_buf_stop; /* downsample when we reach this index */
|
||||
#endif
|
||||
} my_prep_controller;
|
||||
|
||||
typedef my_prep_controller * my_prep_ptr;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
||||
{
|
||||
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
|
||||
|
||||
if (pass_mode != JBUF_PASS_THRU)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
|
||||
/* Initialize total-height counter for detecting bottom of image */
|
||||
prep->rows_to_go = cinfo->image_height;
|
||||
/* Mark the conversion buffer empty */
|
||||
prep->next_buf_row = 0;
|
||||
#ifdef CONTEXT_ROWS_SUPPORTED
|
||||
/* Preset additional state variables for context mode.
|
||||
* These aren't used in non-context mode, so we needn't test which mode.
|
||||
*/
|
||||
prep->this_row_group = 0;
|
||||
/* Set next_buf_stop to stop after two row groups have been read in. */
|
||||
prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Expand an image vertically from height input_rows to height output_rows,
|
||||
* by duplicating the bottom row.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
|
||||
int input_rows, int output_rows)
|
||||
{
|
||||
int row;
|
||||
|
||||
for (row = input_rows; row < output_rows; row++) {
|
||||
jcopy_sample_rows(image_data, input_rows-1, image_data, row,
|
||||
1, num_cols);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data in the simple no-context case.
|
||||
*
|
||||
* Preprocessor output data is counted in "row groups". A row group
|
||||
* is defined to be v_samp_factor sample rows of each component.
|
||||
* Downsampling will produce this much data from each max_v_samp_factor
|
||||
* input rows.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
pre_process_data (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail,
|
||||
JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
|
||||
JDIMENSION out_row_groups_avail)
|
||||
{
|
||||
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
|
||||
int numrows, ci;
|
||||
JDIMENSION inrows;
|
||||
jpeg_component_info * compptr;
|
||||
|
||||
while (*in_row_ctr < in_rows_avail &&
|
||||
*out_row_group_ctr < out_row_groups_avail) {
|
||||
/* Do color conversion to fill the conversion buffer. */
|
||||
inrows = in_rows_avail - *in_row_ctr;
|
||||
numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
|
||||
numrows = (int) MIN((JDIMENSION) numrows, inrows);
|
||||
(*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
|
||||
prep->color_buf,
|
||||
(JDIMENSION) prep->next_buf_row,
|
||||
numrows);
|
||||
*in_row_ctr += numrows;
|
||||
prep->next_buf_row += numrows;
|
||||
prep->rows_to_go -= numrows;
|
||||
/* If at bottom of image, pad to fill the conversion buffer. */
|
||||
if (prep->rows_to_go == 0 &&
|
||||
prep->next_buf_row < cinfo->max_v_samp_factor) {
|
||||
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||
expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
|
||||
prep->next_buf_row, cinfo->max_v_samp_factor);
|
||||
}
|
||||
prep->next_buf_row = cinfo->max_v_samp_factor;
|
||||
}
|
||||
/* If we've filled the conversion buffer, empty it. */
|
||||
if (prep->next_buf_row == cinfo->max_v_samp_factor) {
|
||||
(*cinfo->downsample->downsample) (cinfo,
|
||||
prep->color_buf, (JDIMENSION) 0,
|
||||
output_buf, *out_row_group_ctr);
|
||||
prep->next_buf_row = 0;
|
||||
(*out_row_group_ctr)++;
|
||||
}
|
||||
/* If at bottom of image, pad the output to a full iMCU height.
|
||||
* Note we assume the caller is providing a one-iMCU-height output buffer!
|
||||
*/
|
||||
if (prep->rows_to_go == 0 &&
|
||||
*out_row_group_ctr < out_row_groups_avail) {
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
expand_bottom_edge(output_buf[ci],
|
||||
compptr->width_in_blocks * DCTSIZE,
|
||||
(int) (*out_row_group_ctr * compptr->v_samp_factor),
|
||||
(int) (out_row_groups_avail * compptr->v_samp_factor));
|
||||
}
|
||||
*out_row_group_ctr = out_row_groups_avail;
|
||||
break; /* can exit outer loop without test */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONTEXT_ROWS_SUPPORTED
|
||||
|
||||
/*
|
||||
* Process some data in the context case.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
pre_process_context (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail,
|
||||
JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
|
||||
JDIMENSION out_row_groups_avail)
|
||||
{
|
||||
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
|
||||
int numrows, ci;
|
||||
int buf_height = cinfo->max_v_samp_factor * 3;
|
||||
JDIMENSION inrows;
|
||||
|
||||
while (*out_row_group_ctr < out_row_groups_avail) {
|
||||
if (*in_row_ctr < in_rows_avail) {
|
||||
/* Do color conversion to fill the conversion buffer. */
|
||||
inrows = in_rows_avail - *in_row_ctr;
|
||||
numrows = prep->next_buf_stop - prep->next_buf_row;
|
||||
numrows = (int) MIN((JDIMENSION) numrows, inrows);
|
||||
(*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
|
||||
prep->color_buf,
|
||||
(JDIMENSION) prep->next_buf_row,
|
||||
numrows);
|
||||
/* Pad at top of image, if first time through */
|
||||
if (prep->rows_to_go == cinfo->image_height) {
|
||||
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||
int row;
|
||||
for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
|
||||
jcopy_sample_rows(prep->color_buf[ci], 0,
|
||||
prep->color_buf[ci], -row,
|
||||
1, cinfo->image_width);
|
||||
}
|
||||
}
|
||||
}
|
||||
*in_row_ctr += numrows;
|
||||
prep->next_buf_row += numrows;
|
||||
prep->rows_to_go -= numrows;
|
||||
} else {
|
||||
/* Return for more data, unless we are at the bottom of the image. */
|
||||
if (prep->rows_to_go != 0)
|
||||
break;
|
||||
/* When at bottom of image, pad to fill the conversion buffer. */
|
||||
if (prep->next_buf_row < prep->next_buf_stop) {
|
||||
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||
expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
|
||||
prep->next_buf_row, prep->next_buf_stop);
|
||||
}
|
||||
prep->next_buf_row = prep->next_buf_stop;
|
||||
}
|
||||
}
|
||||
/* If we've gotten enough data, downsample a row group. */
|
||||
if (prep->next_buf_row == prep->next_buf_stop) {
|
||||
(*cinfo->downsample->downsample) (cinfo,
|
||||
prep->color_buf,
|
||||
(JDIMENSION) prep->this_row_group,
|
||||
output_buf, *out_row_group_ctr);
|
||||
(*out_row_group_ctr)++;
|
||||
/* Advance pointers with wraparound as necessary. */
|
||||
prep->this_row_group += cinfo->max_v_samp_factor;
|
||||
if (prep->this_row_group >= buf_height)
|
||||
prep->this_row_group = 0;
|
||||
if (prep->next_buf_row >= buf_height)
|
||||
prep->next_buf_row = 0;
|
||||
prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create the wrapped-around downsampling input buffer needed for context mode.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
create_context_buffer (j_compress_ptr cinfo)
|
||||
{
|
||||
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
|
||||
int rgroup_height = cinfo->max_v_samp_factor;
|
||||
int ci, i;
|
||||
jpeg_component_info * compptr;
|
||||
JSAMPARRAY true_buffer, fake_buffer;
|
||||
|
||||
/* Grab enough space for fake row pointers for all the components;
|
||||
* we need five row groups' worth of pointers for each component.
|
||||
*/
|
||||
fake_buffer = (JSAMPARRAY)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(cinfo->num_components * 5 * rgroup_height) *
|
||||
SIZEOF(JSAMPROW));
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Allocate the actual buffer space (3 row groups) for this component.
|
||||
* We make the buffer wide enough to allow the downsampler to edge-expand
|
||||
* horizontally within the buffer, if it so chooses.
|
||||
*/
|
||||
true_buffer = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
|
||||
cinfo->max_h_samp_factor) / compptr->h_samp_factor),
|
||||
(JDIMENSION) (3 * rgroup_height));
|
||||
/* Copy true buffer row pointers into the middle of the fake row array */
|
||||
MEMCOPY(fake_buffer + rgroup_height, true_buffer,
|
||||
3 * rgroup_height * SIZEOF(JSAMPROW));
|
||||
/* Fill in the above and below wraparound pointers */
|
||||
for (i = 0; i < rgroup_height; i++) {
|
||||
fake_buffer[i] = true_buffer[2 * rgroup_height + i];
|
||||
fake_buffer[4 * rgroup_height + i] = true_buffer[i];
|
||||
}
|
||||
prep->color_buf[ci] = fake_buffer + rgroup_height;
|
||||
fake_buffer += 5 * rgroup_height; /* point to space for next component */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONTEXT_ROWS_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize preprocessing controller.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_prep_ptr prep;
|
||||
int ci;
|
||||
jpeg_component_info * compptr;
|
||||
|
||||
if (need_full_buffer) /* safety check */
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
|
||||
prep = (my_prep_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_prep_controller));
|
||||
cinfo->prep = (struct jpeg_c_prep_controller *) prep;
|
||||
prep->pub.start_pass = start_pass_prep;
|
||||
|
||||
/* Allocate the color conversion buffer.
|
||||
* We make the buffer wide enough to allow the downsampler to edge-expand
|
||||
* horizontally within the buffer, if it so chooses.
|
||||
*/
|
||||
if (cinfo->downsample->need_context_rows) {
|
||||
/* Set up to provide context rows */
|
||||
#ifdef CONTEXT_ROWS_SUPPORTED
|
||||
prep->pub.pre_process_data = pre_process_context;
|
||||
create_context_buffer(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else {
|
||||
/* No context, just make it tall enough for one row group */
|
||||
prep->pub.pre_process_data = pre_process_data;
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
|
||||
cinfo->max_h_samp_factor) / compptr->h_samp_factor),
|
||||
(JDIMENSION) cinfo->max_v_samp_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* jcprepct.c
|
||||
*
|
||||
* Copyright (C) 1994-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 the compression preprocessing controller.
|
||||
* This controller manages the color conversion, downsampling,
|
||||
* and edge expansion steps.
|
||||
*
|
||||
* Most of the complexity here is associated with buffering input rows
|
||||
* as required by the downsampler. See the comments at the head of
|
||||
* jcsample.c for the downsampler's needs.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* At present, jcsample.c can request context rows only for smoothing.
|
||||
* In the future, we might also need context rows for CCIR601 sampling
|
||||
* or other more-complex downsampling procedures. The code to support
|
||||
* context rows should be compiled only if needed.
|
||||
*/
|
||||
#ifdef INPUT_SMOOTHING_SUPPORTED
|
||||
#define CONTEXT_ROWS_SUPPORTED
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* For the simple (no-context-row) case, we just need to buffer one
|
||||
* row group's worth of pixels for the downsampling step. At the bottom of
|
||||
* the image, we pad to a full row group by replicating the last pixel row.
|
||||
* The downsampler's last output row is then replicated if needed to pad
|
||||
* out to a full iMCU row.
|
||||
*
|
||||
* When providing context rows, we must buffer three row groups' worth of
|
||||
* pixels. Three row groups are physically allocated, but the row pointer
|
||||
* arrays are made five row groups high, with the extra pointers above and
|
||||
* below "wrapping around" to point to the last and first real row groups.
|
||||
* This allows the downsampler to access the proper context rows.
|
||||
* At the top and bottom of the image, we create dummy context rows by
|
||||
* copying the first or last real pixel row. This copying could be avoided
|
||||
* by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the
|
||||
* trouble on the compression side.
|
||||
*/
|
||||
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_c_prep_controller pub; /* public fields */
|
||||
|
||||
/* Downsampling input buffer. This buffer holds color-converted data
|
||||
* until we have enough to do a downsample step.
|
||||
*/
|
||||
JSAMPARRAY color_buf[MAX_COMPONENTS];
|
||||
|
||||
JDIMENSION rows_to_go; /* counts rows remaining in source image */
|
||||
int next_buf_row; /* index of next row to store in color_buf */
|
||||
|
||||
#ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */
|
||||
int this_row_group; /* starting row index of group to process */
|
||||
int next_buf_stop; /* downsample when we reach this index */
|
||||
#endif
|
||||
} my_prep_controller;
|
||||
|
||||
typedef my_prep_controller * my_prep_ptr;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
||||
{
|
||||
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
|
||||
|
||||
if (pass_mode != JBUF_PASS_THRU)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
|
||||
/* Initialize total-height counter for detecting bottom of image */
|
||||
prep->rows_to_go = cinfo->image_height;
|
||||
/* Mark the conversion buffer empty */
|
||||
prep->next_buf_row = 0;
|
||||
#ifdef CONTEXT_ROWS_SUPPORTED
|
||||
/* Preset additional state variables for context mode.
|
||||
* These aren't used in non-context mode, so we needn't test which mode.
|
||||
*/
|
||||
prep->this_row_group = 0;
|
||||
/* Set next_buf_stop to stop after two row groups have been read in. */
|
||||
prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Expand an image vertically from height input_rows to height output_rows,
|
||||
* by duplicating the bottom row.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
|
||||
int input_rows, int output_rows)
|
||||
{
|
||||
int row;
|
||||
|
||||
for (row = input_rows; row < output_rows; row++) {
|
||||
jcopy_sample_rows(image_data, input_rows-1, image_data, row,
|
||||
1, num_cols);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data in the simple no-context case.
|
||||
*
|
||||
* Preprocessor output data is counted in "row groups". A row group
|
||||
* is defined to be v_samp_factor sample rows of each component.
|
||||
* Downsampling will produce this much data from each max_v_samp_factor
|
||||
* input rows.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
pre_process_data (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail,
|
||||
JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
|
||||
JDIMENSION out_row_groups_avail)
|
||||
{
|
||||
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
|
||||
int numrows, ci;
|
||||
JDIMENSION inrows;
|
||||
jpeg_component_info * compptr;
|
||||
|
||||
while (*in_row_ctr < in_rows_avail &&
|
||||
*out_row_group_ctr < out_row_groups_avail) {
|
||||
/* Do color conversion to fill the conversion buffer. */
|
||||
inrows = in_rows_avail - *in_row_ctr;
|
||||
numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
|
||||
numrows = (int) MIN((JDIMENSION) numrows, inrows);
|
||||
(*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
|
||||
prep->color_buf,
|
||||
(JDIMENSION) prep->next_buf_row,
|
||||
numrows);
|
||||
*in_row_ctr += numrows;
|
||||
prep->next_buf_row += numrows;
|
||||
prep->rows_to_go -= numrows;
|
||||
/* If at bottom of image, pad to fill the conversion buffer. */
|
||||
if (prep->rows_to_go == 0 &&
|
||||
prep->next_buf_row < cinfo->max_v_samp_factor) {
|
||||
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||
expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
|
||||
prep->next_buf_row, cinfo->max_v_samp_factor);
|
||||
}
|
||||
prep->next_buf_row = cinfo->max_v_samp_factor;
|
||||
}
|
||||
/* If we've filled the conversion buffer, empty it. */
|
||||
if (prep->next_buf_row == cinfo->max_v_samp_factor) {
|
||||
(*cinfo->downsample->downsample) (cinfo,
|
||||
prep->color_buf, (JDIMENSION) 0,
|
||||
output_buf, *out_row_group_ctr);
|
||||
prep->next_buf_row = 0;
|
||||
(*out_row_group_ctr)++;
|
||||
}
|
||||
/* If at bottom of image, pad the output to a full iMCU height.
|
||||
* Note we assume the caller is providing a one-iMCU-height output buffer!
|
||||
*/
|
||||
if (prep->rows_to_go == 0 &&
|
||||
*out_row_group_ctr < out_row_groups_avail) {
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
expand_bottom_edge(output_buf[ci],
|
||||
compptr->width_in_blocks * DCTSIZE,
|
||||
(int) (*out_row_group_ctr * compptr->v_samp_factor),
|
||||
(int) (out_row_groups_avail * compptr->v_samp_factor));
|
||||
}
|
||||
*out_row_group_ctr = out_row_groups_avail;
|
||||
break; /* can exit outer loop without test */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONTEXT_ROWS_SUPPORTED
|
||||
|
||||
/*
|
||||
* Process some data in the context case.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
pre_process_context (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail,
|
||||
JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
|
||||
JDIMENSION out_row_groups_avail)
|
||||
{
|
||||
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
|
||||
int numrows, ci;
|
||||
int buf_height = cinfo->max_v_samp_factor * 3;
|
||||
JDIMENSION inrows;
|
||||
|
||||
while (*out_row_group_ctr < out_row_groups_avail) {
|
||||
if (*in_row_ctr < in_rows_avail) {
|
||||
/* Do color conversion to fill the conversion buffer. */
|
||||
inrows = in_rows_avail - *in_row_ctr;
|
||||
numrows = prep->next_buf_stop - prep->next_buf_row;
|
||||
numrows = (int) MIN((JDIMENSION) numrows, inrows);
|
||||
(*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
|
||||
prep->color_buf,
|
||||
(JDIMENSION) prep->next_buf_row,
|
||||
numrows);
|
||||
/* Pad at top of image, if first time through */
|
||||
if (prep->rows_to_go == cinfo->image_height) {
|
||||
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||
int row;
|
||||
for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
|
||||
jcopy_sample_rows(prep->color_buf[ci], 0,
|
||||
prep->color_buf[ci], -row,
|
||||
1, cinfo->image_width);
|
||||
}
|
||||
}
|
||||
}
|
||||
*in_row_ctr += numrows;
|
||||
prep->next_buf_row += numrows;
|
||||
prep->rows_to_go -= numrows;
|
||||
} else {
|
||||
/* Return for more data, unless we are at the bottom of the image. */
|
||||
if (prep->rows_to_go != 0)
|
||||
break;
|
||||
/* When at bottom of image, pad to fill the conversion buffer. */
|
||||
if (prep->next_buf_row < prep->next_buf_stop) {
|
||||
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||
expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
|
||||
prep->next_buf_row, prep->next_buf_stop);
|
||||
}
|
||||
prep->next_buf_row = prep->next_buf_stop;
|
||||
}
|
||||
}
|
||||
/* If we've gotten enough data, downsample a row group. */
|
||||
if (prep->next_buf_row == prep->next_buf_stop) {
|
||||
(*cinfo->downsample->downsample) (cinfo,
|
||||
prep->color_buf,
|
||||
(JDIMENSION) prep->this_row_group,
|
||||
output_buf, *out_row_group_ctr);
|
||||
(*out_row_group_ctr)++;
|
||||
/* Advance pointers with wraparound as necessary. */
|
||||
prep->this_row_group += cinfo->max_v_samp_factor;
|
||||
if (prep->this_row_group >= buf_height)
|
||||
prep->this_row_group = 0;
|
||||
if (prep->next_buf_row >= buf_height)
|
||||
prep->next_buf_row = 0;
|
||||
prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create the wrapped-around downsampling input buffer needed for context mode.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
create_context_buffer (j_compress_ptr cinfo)
|
||||
{
|
||||
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
|
||||
int rgroup_height = cinfo->max_v_samp_factor;
|
||||
int ci, i;
|
||||
jpeg_component_info * compptr;
|
||||
JSAMPARRAY true_buffer, fake_buffer;
|
||||
|
||||
/* Grab enough space for fake row pointers for all the components;
|
||||
* we need five row groups' worth of pointers for each component.
|
||||
*/
|
||||
fake_buffer = (JSAMPARRAY)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(cinfo->num_components * 5 * rgroup_height) *
|
||||
SIZEOF(JSAMPROW));
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Allocate the actual buffer space (3 row groups) for this component.
|
||||
* We make the buffer wide enough to allow the downsampler to edge-expand
|
||||
* horizontally within the buffer, if it so chooses.
|
||||
*/
|
||||
true_buffer = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
|
||||
cinfo->max_h_samp_factor) / compptr->h_samp_factor),
|
||||
(JDIMENSION) (3 * rgroup_height));
|
||||
/* Copy true buffer row pointers into the middle of the fake row array */
|
||||
MEMCOPY(fake_buffer + rgroup_height, true_buffer,
|
||||
3 * rgroup_height * SIZEOF(JSAMPROW));
|
||||
/* Fill in the above and below wraparound pointers */
|
||||
for (i = 0; i < rgroup_height; i++) {
|
||||
fake_buffer[i] = true_buffer[2 * rgroup_height + i];
|
||||
fake_buffer[4 * rgroup_height + i] = true_buffer[i];
|
||||
}
|
||||
prep->color_buf[ci] = fake_buffer + rgroup_height;
|
||||
fake_buffer += 5 * rgroup_height; /* point to space for next component */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONTEXT_ROWS_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize preprocessing controller.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_prep_ptr prep;
|
||||
int ci;
|
||||
jpeg_component_info * compptr;
|
||||
|
||||
if (need_full_buffer) /* safety check */
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
|
||||
prep = (my_prep_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_prep_controller));
|
||||
cinfo->prep = (struct jpeg_c_prep_controller *) prep;
|
||||
prep->pub.start_pass = start_pass_prep;
|
||||
|
||||
/* Allocate the color conversion buffer.
|
||||
* We make the buffer wide enough to allow the downsampler to edge-expand
|
||||
* horizontally within the buffer, if it so chooses.
|
||||
*/
|
||||
if (cinfo->downsample->need_context_rows) {
|
||||
/* Set up to provide context rows */
|
||||
#ifdef CONTEXT_ROWS_SUPPORTED
|
||||
prep->pub.pre_process_data = pre_process_context;
|
||||
create_context_buffer(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else {
|
||||
/* No context, just make it tall enough for one row group */
|
||||
prep->pub.pre_process_data = pre_process_data;
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
|
||||
cinfo->max_h_samp_factor) / compptr->h_samp_factor),
|
||||
(JDIMENSION) cinfo->max_v_samp_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,388 +1,388 @@
|
||||
/*
|
||||
* jctrans.c
|
||||
*
|
||||
* Copyright (C) 1995-1998, 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 library routines for transcoding compression,
|
||||
* that is, writing raw DCT coefficient arrays to an output JPEG file.
|
||||
* The routines in jcapimin.c will also be needed by a transcoder.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
LOCAL(void) transencode_master_selection
|
||||
JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
|
||||
LOCAL(void) transencode_coef_controller
|
||||
JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
|
||||
|
||||
|
||||
/*
|
||||
* Compression initialization for writing raw-coefficient data.
|
||||
* Before calling this, all parameters and a data destination must be set up.
|
||||
* Call jpeg_finish_compress() to actually write the data.
|
||||
*
|
||||
* The number of passed virtual arrays must match cinfo->num_components.
|
||||
* Note that the virtual arrays need not be filled or even realized at
|
||||
* the time write_coefficients is called; indeed, if the virtual arrays
|
||||
* were requested from this compression object's memory manager, they
|
||||
* typically will be realized during this routine and filled afterwards.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
|
||||
{
|
||||
if (cinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
/* Mark all tables to be written */
|
||||
jpeg_suppress_tables(cinfo, FALSE);
|
||||
/* (Re)initialize error mgr and destination modules */
|
||||
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
|
||||
(*cinfo->dest->init_destination) (cinfo);
|
||||
/* Perform master selection of active modules */
|
||||
transencode_master_selection(cinfo, coef_arrays);
|
||||
/* Wait for jpeg_finish_compress() call */
|
||||
cinfo->next_scanline = 0; /* so jpeg_write_marker works */
|
||||
cinfo->global_state = CSTATE_WRCOEFS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the compression object with default parameters,
|
||||
* then copy from the source object all parameters needed for lossless
|
||||
* transcoding. Parameters that can be varied without loss (such as
|
||||
* scan script and Huffman optimization) are left in their default states.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
|
||||
j_compress_ptr dstinfo)
|
||||
{
|
||||
JQUANT_TBL ** qtblptr;
|
||||
jpeg_component_info *incomp, *outcomp;
|
||||
JQUANT_TBL *c_quant, *slot_quant;
|
||||
int tblno, ci, coefi;
|
||||
|
||||
/* Safety check to ensure start_compress not called yet. */
|
||||
if (dstinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
|
||||
/* Copy fundamental image dimensions */
|
||||
dstinfo->image_width = srcinfo->image_width;
|
||||
dstinfo->image_height = srcinfo->image_height;
|
||||
dstinfo->input_components = srcinfo->num_components;
|
||||
dstinfo->in_color_space = srcinfo->jpeg_color_space;
|
||||
/* Initialize all parameters to default values */
|
||||
jpeg_set_defaults(dstinfo);
|
||||
/* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
|
||||
* Fix it to get the right header markers for the image colorspace.
|
||||
*/
|
||||
jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
|
||||
dstinfo->data_precision = srcinfo->data_precision;
|
||||
dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
|
||||
/* Copy the source's quantization tables. */
|
||||
for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
|
||||
if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
|
||||
qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
|
||||
if (*qtblptr == NULL)
|
||||
*qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo);
|
||||
MEMCOPY((*qtblptr)->quantval,
|
||||
srcinfo->quant_tbl_ptrs[tblno]->quantval,
|
||||
SIZEOF((*qtblptr)->quantval));
|
||||
(*qtblptr)->sent_table = FALSE;
|
||||
}
|
||||
}
|
||||
/* Copy the source's per-component info.
|
||||
* Note we assume jpeg_set_defaults has allocated the dest comp_info array.
|
||||
*/
|
||||
dstinfo->num_components = srcinfo->num_components;
|
||||
if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
|
||||
ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
|
||||
MAX_COMPONENTS);
|
||||
for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
|
||||
ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
|
||||
outcomp->component_id = incomp->component_id;
|
||||
outcomp->h_samp_factor = incomp->h_samp_factor;
|
||||
outcomp->v_samp_factor = incomp->v_samp_factor;
|
||||
outcomp->quant_tbl_no = incomp->quant_tbl_no;
|
||||
/* Make sure saved quantization table for component matches the qtable
|
||||
* slot. If not, the input file re-used this qtable slot.
|
||||
* IJG encoder currently cannot duplicate this.
|
||||
*/
|
||||
tblno = outcomp->quant_tbl_no;
|
||||
if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
|
||||
srcinfo->quant_tbl_ptrs[tblno] == NULL)
|
||||
ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
|
||||
slot_quant = srcinfo->quant_tbl_ptrs[tblno];
|
||||
c_quant = incomp->quant_table;
|
||||
if (c_quant != NULL) {
|
||||
for (coefi = 0; coefi < DCTSIZE2; coefi++) {
|
||||
if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
|
||||
ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
|
||||
}
|
||||
}
|
||||
/* Note: we do not copy the source's Huffman table assignments;
|
||||
* instead we rely on jpeg_set_colorspace to have made a suitable choice.
|
||||
*/
|
||||
}
|
||||
/* Also copy JFIF version and resolution information, if available.
|
||||
* Strictly speaking this isn't "critical" info, but it's nearly
|
||||
* always appropriate to copy it if available. In particular,
|
||||
* if the application chooses to copy JFIF 1.02 extension markers from
|
||||
* the source file, we need to copy the version to make sure we don't
|
||||
* emit a file that has 1.02 extensions but a claimed version of 1.01.
|
||||
* We will *not*, however, copy version info from mislabeled "2.01" files.
|
||||
*/
|
||||
if (srcinfo->saw_JFIF_marker) {
|
||||
if (srcinfo->JFIF_major_version == 1) {
|
||||
dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
|
||||
dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
|
||||
}
|
||||
dstinfo->density_unit = srcinfo->density_unit;
|
||||
dstinfo->X_density = srcinfo->X_density;
|
||||
dstinfo->Y_density = srcinfo->Y_density;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Master selection of compression modules for transcoding.
|
||||
* This substitutes for jcinit.c's initialization of the full compressor.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
transencode_master_selection (j_compress_ptr cinfo,
|
||||
jvirt_barray_ptr * coef_arrays)
|
||||
{
|
||||
/* Although we don't actually use input_components for transcoding,
|
||||
* jcmaster.c's initial_setup will complain if input_components is 0.
|
||||
*/
|
||||
cinfo->input_components = 1;
|
||||
/* Initialize master control (includes parameter checking/processing) */
|
||||
jinit_c_master_control(cinfo, TRUE /* transcode only */);
|
||||
|
||||
/* Entropy encoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
} else {
|
||||
if (cinfo->progressive_mode) {
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
jinit_phuff_encoder(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else
|
||||
jinit_huff_encoder(cinfo);
|
||||
}
|
||||
|
||||
/* We need a special coefficient buffer controller. */
|
||||
transencode_coef_controller(cinfo, coef_arrays);
|
||||
|
||||
jinit_marker_writer(cinfo);
|
||||
|
||||
/* We can now tell the memory manager to allocate virtual arrays. */
|
||||
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
|
||||
|
||||
/* Write the datastream header (SOI, JFIF) immediately.
|
||||
* Frame and scan headers are postponed till later.
|
||||
* This lets application insert special markers after the SOI.
|
||||
*/
|
||||
(*cinfo->marker->write_file_header) (cinfo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The rest of this file is a special implementation of the coefficient
|
||||
* buffer controller. This is similar to jccoefct.c, but it handles only
|
||||
* output from presupplied virtual arrays. Furthermore, we generate any
|
||||
* dummy padding blocks on-the-fly rather than expecting them to be present
|
||||
* in the arrays.
|
||||
*/
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_c_coef_controller pub; /* public fields */
|
||||
|
||||
JDIMENSION iMCU_row_num; /* iMCU row # within image */
|
||||
JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
|
||||
int MCU_vert_offset; /* counts MCU rows within iMCU row */
|
||||
int MCU_rows_per_iMCU_row; /* number of such rows needed */
|
||||
|
||||
/* Virtual block array for each component. */
|
||||
jvirt_barray_ptr * whole_image;
|
||||
|
||||
/* Workspace for constructing dummy blocks at right/bottom edges. */
|
||||
JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
|
||||
} my_coef_controller2;
|
||||
|
||||
typedef my_coef_controller2 * my_coef_ptr2;
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
start_iMCU_row2 (j_compress_ptr cinfo)
|
||||
/* Reset within-iMCU-row counters for a new row */
|
||||
{
|
||||
my_coef_ptr2 coef = (my_coef_ptr2) cinfo->coef;
|
||||
|
||||
/* In an interleaved scan, an MCU row is the same as an iMCU row.
|
||||
* In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
|
||||
* But at the bottom of the image, process only what's left.
|
||||
*/
|
||||
if (cinfo->comps_in_scan > 1) {
|
||||
coef->MCU_rows_per_iMCU_row = 1;
|
||||
} else {
|
||||
if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
|
||||
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
|
||||
else
|
||||
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
|
||||
}
|
||||
|
||||
coef->mcu_ctr = 0;
|
||||
coef->MCU_vert_offset = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_coef2 (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
||||
{
|
||||
my_coef_ptr2 coef = (my_coef_ptr2) cinfo->coef;
|
||||
|
||||
if (pass_mode != JBUF_CRANK_DEST)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
|
||||
coef->iMCU_row_num = 0;
|
||||
start_iMCU_row2(cinfo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data.
|
||||
* We process the equivalent of one fully interleaved MCU row ("iMCU" row)
|
||||
* per call, ie, v_samp_factor block rows for each component in the scan.
|
||||
* The data is obtained from the virtual arrays and fed to the entropy coder.
|
||||
* Returns TRUE if the iMCU row is completed, FALSE if suspended.
|
||||
*
|
||||
* NB: input_buf is ignored; it is likely to be a NULL pointer.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
compress_output2 (j_compress_ptr cinfo, JSAMPIMAGE)
|
||||
{
|
||||
my_coef_ptr2 coef = (my_coef_ptr2) cinfo->coef;
|
||||
JDIMENSION MCU_col_num; /* index of current MCU within row */
|
||||
JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
|
||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
||||
int blkn, ci, xindex, yindex, yoffset, blockcnt;
|
||||
JDIMENSION start_col;
|
||||
JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
|
||||
JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
|
||||
JBLOCKROW buffer_ptr;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Align the virtual buffers for the components used in this scan. */
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
buffer[ci] = (*cinfo->mem->access_virt_barray)
|
||||
((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
|
||||
coef->iMCU_row_num * compptr->v_samp_factor,
|
||||
(JDIMENSION) compptr->v_samp_factor, FALSE);
|
||||
}
|
||||
|
||||
/* Loop to process one whole iMCU row */
|
||||
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
|
||||
yoffset++) {
|
||||
for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
|
||||
MCU_col_num++) {
|
||||
/* Construct list of pointers to DCT blocks belonging to this MCU */
|
||||
blkn = 0; /* index of current DCT block within MCU */
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
start_col = MCU_col_num * compptr->MCU_width;
|
||||
blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
|
||||
: compptr->last_col_width;
|
||||
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
|
||||
if (coef->iMCU_row_num < last_iMCU_row ||
|
||||
yindex+yoffset < compptr->last_row_height) {
|
||||
/* Fill in pointers to real blocks in this row */
|
||||
buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
|
||||
for (xindex = 0; xindex < blockcnt; xindex++)
|
||||
MCU_buffer[blkn++] = buffer_ptr++;
|
||||
} else {
|
||||
/* At bottom of image, need a whole row of dummy blocks */
|
||||
xindex = 0;
|
||||
}
|
||||
/* Fill in any dummy blocks needed in this row.
|
||||
* Dummy blocks are filled in the same way as in jccoefct.c:
|
||||
* all zeroes in the AC entries, DC entries equal to previous
|
||||
* block's DC value. The init routine has already zeroed the
|
||||
* AC entries, so we need only set the DC entries correctly.
|
||||
*/
|
||||
for (; xindex < compptr->MCU_width; xindex++) {
|
||||
MCU_buffer[blkn] = coef->dummy_buffer[blkn];
|
||||
MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
|
||||
blkn++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Try to write the MCU. */
|
||||
if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
|
||||
/* Suspension forced; update state counters and exit */
|
||||
coef->MCU_vert_offset = yoffset;
|
||||
coef->mcu_ctr = MCU_col_num;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* Completed an MCU row, but perhaps not an iMCU row */
|
||||
coef->mcu_ctr = 0;
|
||||
}
|
||||
/* Completed the iMCU row, advance counters for next one */
|
||||
coef->iMCU_row_num++;
|
||||
start_iMCU_row2(cinfo);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize coefficient buffer controller.
|
||||
*
|
||||
* Each passed coefficient array must be the right size for that
|
||||
* coefficient: width_in_blocks wide and height_in_blocks high,
|
||||
* with unitheight at least v_samp_factor.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
transencode_coef_controller (j_compress_ptr cinfo,
|
||||
jvirt_barray_ptr * coef_arrays)
|
||||
{
|
||||
my_coef_ptr2 coef;
|
||||
JBLOCKROW buffer;
|
||||
int i;
|
||||
|
||||
coef = (my_coef_ptr2)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_coef_controller2));
|
||||
cinfo->coef = (struct jpeg_c_coef_controller *) coef;
|
||||
coef->pub.start_pass = start_pass_coef2;
|
||||
coef->pub.compress_data = compress_output2;
|
||||
|
||||
/* Save pointer to virtual arrays */
|
||||
coef->whole_image = coef_arrays;
|
||||
|
||||
/* Allocate and pre-zero space for dummy DCT blocks. */
|
||||
buffer = (JBLOCKROW)
|
||||
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
|
||||
jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
|
||||
for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
|
||||
coef->dummy_buffer[i] = buffer + i;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* jctrans.c
|
||||
*
|
||||
* Copyright (C) 1995-1998, 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 library routines for transcoding compression,
|
||||
* that is, writing raw DCT coefficient arrays to an output JPEG file.
|
||||
* The routines in jcapimin.c will also be needed by a transcoder.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
LOCAL(void) transencode_master_selection
|
||||
JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
|
||||
LOCAL(void) transencode_coef_controller
|
||||
JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
|
||||
|
||||
|
||||
/*
|
||||
* Compression initialization for writing raw-coefficient data.
|
||||
* Before calling this, all parameters and a data destination must be set up.
|
||||
* Call jpeg_finish_compress() to actually write the data.
|
||||
*
|
||||
* The number of passed virtual arrays must match cinfo->num_components.
|
||||
* Note that the virtual arrays need not be filled or even realized at
|
||||
* the time write_coefficients is called; indeed, if the virtual arrays
|
||||
* were requested from this compression object's memory manager, they
|
||||
* typically will be realized during this routine and filled afterwards.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
|
||||
{
|
||||
if (cinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
/* Mark all tables to be written */
|
||||
jpeg_suppress_tables(cinfo, FALSE);
|
||||
/* (Re)initialize error mgr and destination modules */
|
||||
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
|
||||
(*cinfo->dest->init_destination) (cinfo);
|
||||
/* Perform master selection of active modules */
|
||||
transencode_master_selection(cinfo, coef_arrays);
|
||||
/* Wait for jpeg_finish_compress() call */
|
||||
cinfo->next_scanline = 0; /* so jpeg_write_marker works */
|
||||
cinfo->global_state = CSTATE_WRCOEFS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the compression object with default parameters,
|
||||
* then copy from the source object all parameters needed for lossless
|
||||
* transcoding. Parameters that can be varied without loss (such as
|
||||
* scan script and Huffman optimization) are left in their default states.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
|
||||
j_compress_ptr dstinfo)
|
||||
{
|
||||
JQUANT_TBL ** qtblptr;
|
||||
jpeg_component_info *incomp, *outcomp;
|
||||
JQUANT_TBL *c_quant, *slot_quant;
|
||||
int tblno, ci, coefi;
|
||||
|
||||
/* Safety check to ensure start_compress not called yet. */
|
||||
if (dstinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
|
||||
/* Copy fundamental image dimensions */
|
||||
dstinfo->image_width = srcinfo->image_width;
|
||||
dstinfo->image_height = srcinfo->image_height;
|
||||
dstinfo->input_components = srcinfo->num_components;
|
||||
dstinfo->in_color_space = srcinfo->jpeg_color_space;
|
||||
/* Initialize all parameters to default values */
|
||||
jpeg_set_defaults(dstinfo);
|
||||
/* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
|
||||
* Fix it to get the right header markers for the image colorspace.
|
||||
*/
|
||||
jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
|
||||
dstinfo->data_precision = srcinfo->data_precision;
|
||||
dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
|
||||
/* Copy the source's quantization tables. */
|
||||
for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
|
||||
if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
|
||||
qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
|
||||
if (*qtblptr == NULL)
|
||||
*qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo);
|
||||
MEMCOPY((*qtblptr)->quantval,
|
||||
srcinfo->quant_tbl_ptrs[tblno]->quantval,
|
||||
SIZEOF((*qtblptr)->quantval));
|
||||
(*qtblptr)->sent_table = FALSE;
|
||||
}
|
||||
}
|
||||
/* Copy the source's per-component info.
|
||||
* Note we assume jpeg_set_defaults has allocated the dest comp_info array.
|
||||
*/
|
||||
dstinfo->num_components = srcinfo->num_components;
|
||||
if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
|
||||
ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
|
||||
MAX_COMPONENTS);
|
||||
for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
|
||||
ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
|
||||
outcomp->component_id = incomp->component_id;
|
||||
outcomp->h_samp_factor = incomp->h_samp_factor;
|
||||
outcomp->v_samp_factor = incomp->v_samp_factor;
|
||||
outcomp->quant_tbl_no = incomp->quant_tbl_no;
|
||||
/* Make sure saved quantization table for component matches the qtable
|
||||
* slot. If not, the input file re-used this qtable slot.
|
||||
* IJG encoder currently cannot duplicate this.
|
||||
*/
|
||||
tblno = outcomp->quant_tbl_no;
|
||||
if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
|
||||
srcinfo->quant_tbl_ptrs[tblno] == NULL)
|
||||
ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
|
||||
slot_quant = srcinfo->quant_tbl_ptrs[tblno];
|
||||
c_quant = incomp->quant_table;
|
||||
if (c_quant != NULL) {
|
||||
for (coefi = 0; coefi < DCTSIZE2; coefi++) {
|
||||
if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
|
||||
ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
|
||||
}
|
||||
}
|
||||
/* Note: we do not copy the source's Huffman table assignments;
|
||||
* instead we rely on jpeg_set_colorspace to have made a suitable choice.
|
||||
*/
|
||||
}
|
||||
/* Also copy JFIF version and resolution information, if available.
|
||||
* Strictly speaking this isn't "critical" info, but it's nearly
|
||||
* always appropriate to copy it if available. In particular,
|
||||
* if the application chooses to copy JFIF 1.02 extension markers from
|
||||
* the source file, we need to copy the version to make sure we don't
|
||||
* emit a file that has 1.02 extensions but a claimed version of 1.01.
|
||||
* We will *not*, however, copy version info from mislabeled "2.01" files.
|
||||
*/
|
||||
if (srcinfo->saw_JFIF_marker) {
|
||||
if (srcinfo->JFIF_major_version == 1) {
|
||||
dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
|
||||
dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
|
||||
}
|
||||
dstinfo->density_unit = srcinfo->density_unit;
|
||||
dstinfo->X_density = srcinfo->X_density;
|
||||
dstinfo->Y_density = srcinfo->Y_density;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Master selection of compression modules for transcoding.
|
||||
* This substitutes for jcinit.c's initialization of the full compressor.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
transencode_master_selection (j_compress_ptr cinfo,
|
||||
jvirt_barray_ptr * coef_arrays)
|
||||
{
|
||||
/* Although we don't actually use input_components for transcoding,
|
||||
* jcmaster.c's initial_setup will complain if input_components is 0.
|
||||
*/
|
||||
cinfo->input_components = 1;
|
||||
/* Initialize master control (includes parameter checking/processing) */
|
||||
jinit_c_master_control(cinfo, TRUE /* transcode only */);
|
||||
|
||||
/* Entropy encoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
} else {
|
||||
if (cinfo->progressive_mode) {
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
jinit_phuff_encoder(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else
|
||||
jinit_huff_encoder(cinfo);
|
||||
}
|
||||
|
||||
/* We need a special coefficient buffer controller. */
|
||||
transencode_coef_controller(cinfo, coef_arrays);
|
||||
|
||||
jinit_marker_writer(cinfo);
|
||||
|
||||
/* We can now tell the memory manager to allocate virtual arrays. */
|
||||
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
|
||||
|
||||
/* Write the datastream header (SOI, JFIF) immediately.
|
||||
* Frame and scan headers are postponed till later.
|
||||
* This lets application insert special markers after the SOI.
|
||||
*/
|
||||
(*cinfo->marker->write_file_header) (cinfo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The rest of this file is a special implementation of the coefficient
|
||||
* buffer controller. This is similar to jccoefct.c, but it handles only
|
||||
* output from presupplied virtual arrays. Furthermore, we generate any
|
||||
* dummy padding blocks on-the-fly rather than expecting them to be present
|
||||
* in the arrays.
|
||||
*/
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_c_coef_controller pub; /* public fields */
|
||||
|
||||
JDIMENSION iMCU_row_num; /* iMCU row # within image */
|
||||
JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
|
||||
int MCU_vert_offset; /* counts MCU rows within iMCU row */
|
||||
int MCU_rows_per_iMCU_row; /* number of such rows needed */
|
||||
|
||||
/* Virtual block array for each component. */
|
||||
jvirt_barray_ptr * whole_image;
|
||||
|
||||
/* Workspace for constructing dummy blocks at right/bottom edges. */
|
||||
JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
|
||||
} my_coef_controller2;
|
||||
|
||||
typedef my_coef_controller2 * my_coef_ptr2;
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
start_iMCU_row2 (j_compress_ptr cinfo)
|
||||
/* Reset within-iMCU-row counters for a new row */
|
||||
{
|
||||
my_coef_ptr2 coef = (my_coef_ptr2) cinfo->coef;
|
||||
|
||||
/* In an interleaved scan, an MCU row is the same as an iMCU row.
|
||||
* In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
|
||||
* But at the bottom of the image, process only what's left.
|
||||
*/
|
||||
if (cinfo->comps_in_scan > 1) {
|
||||
coef->MCU_rows_per_iMCU_row = 1;
|
||||
} else {
|
||||
if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
|
||||
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
|
||||
else
|
||||
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
|
||||
}
|
||||
|
||||
coef->mcu_ctr = 0;
|
||||
coef->MCU_vert_offset = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_coef2 (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
||||
{
|
||||
my_coef_ptr2 coef = (my_coef_ptr2) cinfo->coef;
|
||||
|
||||
if (pass_mode != JBUF_CRANK_DEST)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
|
||||
coef->iMCU_row_num = 0;
|
||||
start_iMCU_row2(cinfo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data.
|
||||
* We process the equivalent of one fully interleaved MCU row ("iMCU" row)
|
||||
* per call, ie, v_samp_factor block rows for each component in the scan.
|
||||
* The data is obtained from the virtual arrays and fed to the entropy coder.
|
||||
* Returns TRUE if the iMCU row is completed, FALSE if suspended.
|
||||
*
|
||||
* NB: input_buf is ignored; it is likely to be a NULL pointer.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
compress_output2 (j_compress_ptr cinfo, JSAMPIMAGE)
|
||||
{
|
||||
my_coef_ptr2 coef = (my_coef_ptr2) cinfo->coef;
|
||||
JDIMENSION MCU_col_num; /* index of current MCU within row */
|
||||
JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
|
||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
||||
int blkn, ci, xindex, yindex, yoffset, blockcnt;
|
||||
JDIMENSION start_col;
|
||||
JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
|
||||
JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
|
||||
JBLOCKROW buffer_ptr;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Align the virtual buffers for the components used in this scan. */
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
buffer[ci] = (*cinfo->mem->access_virt_barray)
|
||||
((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
|
||||
coef->iMCU_row_num * compptr->v_samp_factor,
|
||||
(JDIMENSION) compptr->v_samp_factor, FALSE);
|
||||
}
|
||||
|
||||
/* Loop to process one whole iMCU row */
|
||||
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
|
||||
yoffset++) {
|
||||
for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
|
||||
MCU_col_num++) {
|
||||
/* Construct list of pointers to DCT blocks belonging to this MCU */
|
||||
blkn = 0; /* index of current DCT block within MCU */
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
start_col = MCU_col_num * compptr->MCU_width;
|
||||
blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
|
||||
: compptr->last_col_width;
|
||||
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
|
||||
if (coef->iMCU_row_num < last_iMCU_row ||
|
||||
yindex+yoffset < compptr->last_row_height) {
|
||||
/* Fill in pointers to real blocks in this row */
|
||||
buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
|
||||
for (xindex = 0; xindex < blockcnt; xindex++)
|
||||
MCU_buffer[blkn++] = buffer_ptr++;
|
||||
} else {
|
||||
/* At bottom of image, need a whole row of dummy blocks */
|
||||
xindex = 0;
|
||||
}
|
||||
/* Fill in any dummy blocks needed in this row.
|
||||
* Dummy blocks are filled in the same way as in jccoefct.c:
|
||||
* all zeroes in the AC entries, DC entries equal to previous
|
||||
* block's DC value. The init routine has already zeroed the
|
||||
* AC entries, so we need only set the DC entries correctly.
|
||||
*/
|
||||
for (; xindex < compptr->MCU_width; xindex++) {
|
||||
MCU_buffer[blkn] = coef->dummy_buffer[blkn];
|
||||
MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
|
||||
blkn++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Try to write the MCU. */
|
||||
if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
|
||||
/* Suspension forced; update state counters and exit */
|
||||
coef->MCU_vert_offset = yoffset;
|
||||
coef->mcu_ctr = MCU_col_num;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* Completed an MCU row, but perhaps not an iMCU row */
|
||||
coef->mcu_ctr = 0;
|
||||
}
|
||||
/* Completed the iMCU row, advance counters for next one */
|
||||
coef->iMCU_row_num++;
|
||||
start_iMCU_row2(cinfo);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize coefficient buffer controller.
|
||||
*
|
||||
* Each passed coefficient array must be the right size for that
|
||||
* coefficient: width_in_blocks wide and height_in_blocks high,
|
||||
* with unitheight at least v_samp_factor.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
transencode_coef_controller (j_compress_ptr cinfo,
|
||||
jvirt_barray_ptr * coef_arrays)
|
||||
{
|
||||
my_coef_ptr2 coef;
|
||||
JBLOCKROW buffer;
|
||||
int i;
|
||||
|
||||
coef = (my_coef_ptr2)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_coef_controller2));
|
||||
cinfo->coef = (struct jpeg_c_coef_controller *) coef;
|
||||
coef->pub.start_pass = start_pass_coef2;
|
||||
coef->pub.compress_data = compress_output2;
|
||||
|
||||
/* Save pointer to virtual arrays */
|
||||
coef->whole_image = coef_arrays;
|
||||
|
||||
/* Allocate and pre-zero space for dummy DCT blocks. */
|
||||
buffer = (JBLOCKROW)
|
||||
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
|
||||
jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
|
||||
for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
|
||||
coef->dummy_buffer[i] = buffer + i;
|
||||
}
|
||||
}
|
||||
|
@ -1,395 +1,395 @@
|
||||
/*
|
||||
* jdapimin.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, 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 application interface code for the decompression half
|
||||
* of the JPEG library. These are the "minimum" API routines that may be
|
||||
* needed in either the normal full-decompression case or the
|
||||
* transcoding-only case.
|
||||
*
|
||||
* Most of the routines intended to be called directly by an application
|
||||
* are in this file or in jdapistd.c. But also see jcomapi.c for routines
|
||||
* shared by compression and decompression, and jdtrans.c for the transcoding
|
||||
* case.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/*
|
||||
* Initialization of a JPEG decompression object.
|
||||
* The error manager must already be set up (in case memory manager fails).
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Guard against version mismatches between library and caller. */
|
||||
cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
|
||||
if (version != JPEG_LIB_VERSION)
|
||||
ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
|
||||
if (structsize != SIZEOF(struct jpeg_decompress_struct))
|
||||
ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
|
||||
(int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
|
||||
|
||||
/* For debugging purposes, we zero the whole master structure.
|
||||
* But the application has already set the err pointer, and may have set
|
||||
* client_data, so we have to save and restore those fields.
|
||||
* Note: if application hasn't set client_data, tools like Purify may
|
||||
* complain here.
|
||||
*/
|
||||
{
|
||||
struct jpeg_error_mgr * err = cinfo->err;
|
||||
void * client_data = cinfo->client_data; /* ignore Purify complaint here */
|
||||
MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
|
||||
cinfo->err = err;
|
||||
cinfo->client_data = client_data;
|
||||
}
|
||||
cinfo->is_decompressor = TRUE;
|
||||
|
||||
/* Initialize a memory manager instance for this object */
|
||||
jinit_memory_mgr((j_common_ptr) cinfo);
|
||||
|
||||
/* Zero out pointers to permanent structures. */
|
||||
cinfo->progress = NULL;
|
||||
cinfo->src = NULL;
|
||||
|
||||
for (i = 0; i < NUM_QUANT_TBLS; i++)
|
||||
cinfo->quant_tbl_ptrs[i] = NULL;
|
||||
|
||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
||||
cinfo->dc_huff_tbl_ptrs[i] = NULL;
|
||||
cinfo->ac_huff_tbl_ptrs[i] = NULL;
|
||||
}
|
||||
|
||||
/* Initialize marker processor so application can override methods
|
||||
* for COM, APPn markers before calling jpeg_read_header.
|
||||
*/
|
||||
cinfo->marker_list = NULL;
|
||||
jinit_marker_reader(cinfo);
|
||||
|
||||
/* And initialize the overall input controller. */
|
||||
jinit_input_controller(cinfo);
|
||||
|
||||
/* OK, I'm ready */
|
||||
cinfo->global_state = DSTATE_START;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Destruction of a JPEG decompression object
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_destroy_decompress (j_decompress_ptr cinfo)
|
||||
{
|
||||
jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Abort processing of a JPEG decompression operation,
|
||||
* but don't destroy the object itself.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_abort_decompress (j_decompress_ptr cinfo)
|
||||
{
|
||||
jpeg_abort((j_common_ptr) cinfo); /* use common routine */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set default decompression parameters.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
default_decompress_parms (j_decompress_ptr cinfo)
|
||||
{
|
||||
/* Guess the input colorspace, and set output colorspace accordingly. */
|
||||
/* (Wish JPEG committee had provided a real way to specify this...) */
|
||||
/* Note application may override our guesses. */
|
||||
switch (cinfo->num_components) {
|
||||
case 1:
|
||||
cinfo->jpeg_color_space = JCS_GRAYSCALE;
|
||||
cinfo->out_color_space = JCS_GRAYSCALE;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (cinfo->saw_JFIF_marker) {
|
||||
cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */
|
||||
} else if (cinfo->saw_Adobe_marker) {
|
||||
switch (cinfo->Adobe_transform) {
|
||||
case 0:
|
||||
cinfo->jpeg_color_space = JCS_RGB;
|
||||
break;
|
||||
case 1:
|
||||
cinfo->jpeg_color_space = JCS_YCbCr;
|
||||
break;
|
||||
default:
|
||||
WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
|
||||
cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Saw no special markers, try to guess from the component IDs */
|
||||
int cid0 = cinfo->comp_info[0].component_id;
|
||||
int cid1 = cinfo->comp_info[1].component_id;
|
||||
int cid2 = cinfo->comp_info[2].component_id;
|
||||
|
||||
if (cid0 == 1 && cid1 == 2 && cid2 == 3)
|
||||
cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
|
||||
else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
|
||||
cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
|
||||
else {
|
||||
TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
|
||||
cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
|
||||
}
|
||||
}
|
||||
/* Always guess RGB is proper output colorspace. */
|
||||
cinfo->out_color_space = JCS_RGB;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (cinfo->saw_Adobe_marker) {
|
||||
switch (cinfo->Adobe_transform) {
|
||||
case 0:
|
||||
cinfo->jpeg_color_space = JCS_CMYK;
|
||||
break;
|
||||
case 2:
|
||||
cinfo->jpeg_color_space = JCS_YCCK;
|
||||
break;
|
||||
default:
|
||||
WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
|
||||
cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* No special markers, assume straight CMYK. */
|
||||
cinfo->jpeg_color_space = JCS_CMYK;
|
||||
}
|
||||
cinfo->out_color_space = JCS_CMYK;
|
||||
break;
|
||||
|
||||
default:
|
||||
cinfo->jpeg_color_space = JCS_UNKNOWN;
|
||||
cinfo->out_color_space = JCS_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set defaults for other decompression parameters. */
|
||||
cinfo->scale_num = 1; /* 1:1 scaling */
|
||||
cinfo->scale_denom = 1;
|
||||
cinfo->output_gamma = 1.0;
|
||||
cinfo->buffered_image = FALSE;
|
||||
cinfo->raw_data_out = FALSE;
|
||||
cinfo->dct_method = JDCT_DEFAULT;
|
||||
cinfo->do_fancy_upsampling = TRUE;
|
||||
cinfo->do_block_smoothing = TRUE;
|
||||
cinfo->quantize_colors = FALSE;
|
||||
/* We set these in case application only sets quantize_colors. */
|
||||
cinfo->dither_mode = JDITHER_FS;
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
cinfo->two_pass_quantize = TRUE;
|
||||
#else
|
||||
cinfo->two_pass_quantize = FALSE;
|
||||
#endif
|
||||
cinfo->desired_number_of_colors = 256;
|
||||
cinfo->colormap = NULL;
|
||||
/* Initialize for no mode change in buffered-image mode. */
|
||||
cinfo->enable_1pass_quant = FALSE;
|
||||
cinfo->enable_external_quant = FALSE;
|
||||
cinfo->enable_2pass_quant = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Decompression startup: read start of JPEG datastream to see what's there.
|
||||
* Need only initialize JPEG object and supply a data source before calling.
|
||||
*
|
||||
* This routine will read as far as the first SOS marker (ie, actual start of
|
||||
* compressed data), and will save all tables and parameters in the JPEG
|
||||
* object. It will also initialize the decompression parameters to default
|
||||
* values, and finally return JPEG_HEADER_OK. On return, the application may
|
||||
* adjust the decompression parameters and then call jpeg_start_decompress.
|
||||
* (Or, if the application only wanted to determine the image parameters,
|
||||
* the data need not be decompressed. In that case, call jpeg_abort or
|
||||
* jpeg_destroy to release any temporary space.)
|
||||
* If an abbreviated (tables only) datastream is presented, the routine will
|
||||
* return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then
|
||||
* re-use the JPEG object to read the abbreviated image datastream(s).
|
||||
* It is unnecessary (but OK) to call jpeg_abort in this case.
|
||||
* The JPEG_SUSPENDED return code only occurs if the data source module
|
||||
* requests suspension of the decompressor. In this case the application
|
||||
* should load more source data and then re-call jpeg_read_header to resume
|
||||
* processing.
|
||||
* If a non-suspending data source is used and require_image is TRUE, then the
|
||||
* return code need not be inspected since only JPEG_HEADER_OK is possible.
|
||||
*
|
||||
* This routine is now just a front end to jpeg_consume_input, with some
|
||||
* extra error checking.
|
||||
*/
|
||||
|
||||
GLOBAL(int)
|
||||
jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
|
||||
{
|
||||
int retcode;
|
||||
|
||||
if (cinfo->global_state != DSTATE_START &&
|
||||
cinfo->global_state != DSTATE_INHEADER)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
retcode = jpeg_consume_input(cinfo);
|
||||
|
||||
switch (retcode) {
|
||||
case JPEG_REACHED_SOS:
|
||||
retcode = JPEG_HEADER_OK;
|
||||
break;
|
||||
case JPEG_REACHED_EOI:
|
||||
if (require_image) /* Complain if application wanted an image */
|
||||
ERREXIT(cinfo, JERR_NO_IMAGE);
|
||||
/* Reset to start state; it would be safer to require the application to
|
||||
* call jpeg_abort, but we can't change it now for compatibility reasons.
|
||||
* A side effect is to free any temporary memory (there shouldn't be any).
|
||||
*/
|
||||
jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */
|
||||
retcode = JPEG_HEADER_TABLES_ONLY;
|
||||
break;
|
||||
case JPEG_SUSPENDED:
|
||||
/* no work */
|
||||
break;
|
||||
}
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Consume data in advance of what the decompressor requires.
|
||||
* This can be called at any time once the decompressor object has
|
||||
* been created and a data source has been set up.
|
||||
*
|
||||
* This routine is essentially a state machine that handles a couple
|
||||
* of critical state-transition actions, namely initial setup and
|
||||
* transition from header scanning to ready-for-start_decompress.
|
||||
* All the actual input is done via the input controller's consume_input
|
||||
* method.
|
||||
*/
|
||||
|
||||
GLOBAL(int)
|
||||
jpeg_consume_input (j_decompress_ptr cinfo)
|
||||
{
|
||||
int retcode = JPEG_SUSPENDED;
|
||||
|
||||
/* NB: every possible DSTATE value should be listed in this switch */
|
||||
switch (cinfo->global_state) {
|
||||
case DSTATE_START:
|
||||
/* Start-of-datastream actions: reset appropriate modules */
|
||||
(*cinfo->inputctl->reset_input_controller) (cinfo);
|
||||
/* Initialize application's data source module */
|
||||
(*cinfo->src->init_source) (cinfo);
|
||||
cinfo->global_state = DSTATE_INHEADER;
|
||||
/*FALLTHROUGH*/
|
||||
case DSTATE_INHEADER:
|
||||
retcode = (*cinfo->inputctl->consume_input) (cinfo);
|
||||
if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */
|
||||
/* Set up default parameters based on header data */
|
||||
default_decompress_parms(cinfo);
|
||||
/* Set global state: ready for start_decompress */
|
||||
cinfo->global_state = DSTATE_READY;
|
||||
}
|
||||
break;
|
||||
case DSTATE_READY:
|
||||
/* Can't advance past first SOS until start_decompress is called */
|
||||
retcode = JPEG_REACHED_SOS;
|
||||
break;
|
||||
case DSTATE_PRELOAD:
|
||||
case DSTATE_PRESCAN:
|
||||
case DSTATE_SCANNING:
|
||||
case DSTATE_RAW_OK:
|
||||
case DSTATE_BUFIMAGE:
|
||||
case DSTATE_BUFPOST:
|
||||
case DSTATE_STOPPING:
|
||||
retcode = (*cinfo->inputctl->consume_input) (cinfo);
|
||||
break;
|
||||
default:
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
}
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Have we finished reading the input file?
|
||||
*/
|
||||
|
||||
GLOBAL(boolean)
|
||||
jpeg_input_complete (j_decompress_ptr cinfo)
|
||||
{
|
||||
/* Check for valid jpeg object */
|
||||
if (cinfo->global_state < DSTATE_START ||
|
||||
cinfo->global_state > DSTATE_STOPPING)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
return cinfo->inputctl->eoi_reached;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Is there more than one scan?
|
||||
*/
|
||||
|
||||
GLOBAL(boolean)
|
||||
jpeg_has_multiple_scans (j_decompress_ptr cinfo)
|
||||
{
|
||||
/* Only valid after jpeg_read_header completes */
|
||||
if (cinfo->global_state < DSTATE_READY ||
|
||||
cinfo->global_state > DSTATE_STOPPING)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
return cinfo->inputctl->has_multiple_scans;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish JPEG decompression.
|
||||
*
|
||||
* This will normally just verify the file trailer and release temp storage.
|
||||
*
|
||||
* Returns FALSE if suspended. The return value need be inspected only if
|
||||
* a suspending data source is used.
|
||||
*/
|
||||
|
||||
GLOBAL(boolean)
|
||||
jpeg_finish_decompress (j_decompress_ptr cinfo)
|
||||
{
|
||||
if ((cinfo->global_state == DSTATE_SCANNING ||
|
||||
cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) {
|
||||
/* Terminate final pass of non-buffered mode */
|
||||
if (cinfo->output_scanline < cinfo->output_height)
|
||||
ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
|
||||
(*cinfo->master->finish_output_pass) (cinfo);
|
||||
cinfo->global_state = DSTATE_STOPPING;
|
||||
} else if (cinfo->global_state == DSTATE_BUFIMAGE) {
|
||||
/* Finishing after a buffered-image operation */
|
||||
cinfo->global_state = DSTATE_STOPPING;
|
||||
} else if (cinfo->global_state != DSTATE_STOPPING) {
|
||||
/* STOPPING = repeat call after a suspension, anything else is error */
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
}
|
||||
/* Read until EOI */
|
||||
while (! cinfo->inputctl->eoi_reached) {
|
||||
if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
|
||||
return FALSE; /* Suspend, come back later */
|
||||
}
|
||||
/* Do final cleanup */
|
||||
(*cinfo->src->term_source) (cinfo);
|
||||
/* We can use jpeg_abort to release memory and reset global_state */
|
||||
jpeg_abort((j_common_ptr) cinfo);
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
* jdapimin.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, 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 application interface code for the decompression half
|
||||
* of the JPEG library. These are the "minimum" API routines that may be
|
||||
* needed in either the normal full-decompression case or the
|
||||
* transcoding-only case.
|
||||
*
|
||||
* Most of the routines intended to be called directly by an application
|
||||
* are in this file or in jdapistd.c. But also see jcomapi.c for routines
|
||||
* shared by compression and decompression, and jdtrans.c for the transcoding
|
||||
* case.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/*
|
||||
* Initialization of a JPEG decompression object.
|
||||
* The error manager must already be set up (in case memory manager fails).
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Guard against version mismatches between library and caller. */
|
||||
cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
|
||||
if (version != JPEG_LIB_VERSION)
|
||||
ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
|
||||
if (structsize != SIZEOF(struct jpeg_decompress_struct))
|
||||
ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
|
||||
(int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
|
||||
|
||||
/* For debugging purposes, we zero the whole master structure.
|
||||
* But the application has already set the err pointer, and may have set
|
||||
* client_data, so we have to save and restore those fields.
|
||||
* Note: if application hasn't set client_data, tools like Purify may
|
||||
* complain here.
|
||||
*/
|
||||
{
|
||||
struct jpeg_error_mgr * err = cinfo->err;
|
||||
void * client_data = cinfo->client_data; /* ignore Purify complaint here */
|
||||
MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
|
||||
cinfo->err = err;
|
||||
cinfo->client_data = client_data;
|
||||
}
|
||||
cinfo->is_decompressor = TRUE;
|
||||
|
||||
/* Initialize a memory manager instance for this object */
|
||||
jinit_memory_mgr((j_common_ptr) cinfo);
|
||||
|
||||
/* Zero out pointers to permanent structures. */
|
||||
cinfo->progress = NULL;
|
||||
cinfo->src = NULL;
|
||||
|
||||
for (i = 0; i < NUM_QUANT_TBLS; i++)
|
||||
cinfo->quant_tbl_ptrs[i] = NULL;
|
||||
|
||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
||||
cinfo->dc_huff_tbl_ptrs[i] = NULL;
|
||||
cinfo->ac_huff_tbl_ptrs[i] = NULL;
|
||||
}
|
||||
|
||||
/* Initialize marker processor so application can override methods
|
||||
* for COM, APPn markers before calling jpeg_read_header.
|
||||
*/
|
||||
cinfo->marker_list = NULL;
|
||||
jinit_marker_reader(cinfo);
|
||||
|
||||
/* And initialize the overall input controller. */
|
||||
jinit_input_controller(cinfo);
|
||||
|
||||
/* OK, I'm ready */
|
||||
cinfo->global_state = DSTATE_START;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Destruction of a JPEG decompression object
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_destroy_decompress (j_decompress_ptr cinfo)
|
||||
{
|
||||
jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Abort processing of a JPEG decompression operation,
|
||||
* but don't destroy the object itself.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_abort_decompress (j_decompress_ptr cinfo)
|
||||
{
|
||||
jpeg_abort((j_common_ptr) cinfo); /* use common routine */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set default decompression parameters.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
default_decompress_parms (j_decompress_ptr cinfo)
|
||||
{
|
||||
/* Guess the input colorspace, and set output colorspace accordingly. */
|
||||
/* (Wish JPEG committee had provided a real way to specify this...) */
|
||||
/* Note application may override our guesses. */
|
||||
switch (cinfo->num_components) {
|
||||
case 1:
|
||||
cinfo->jpeg_color_space = JCS_GRAYSCALE;
|
||||
cinfo->out_color_space = JCS_GRAYSCALE;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (cinfo->saw_JFIF_marker) {
|
||||
cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */
|
||||
} else if (cinfo->saw_Adobe_marker) {
|
||||
switch (cinfo->Adobe_transform) {
|
||||
case 0:
|
||||
cinfo->jpeg_color_space = JCS_RGB;
|
||||
break;
|
||||
case 1:
|
||||
cinfo->jpeg_color_space = JCS_YCbCr;
|
||||
break;
|
||||
default:
|
||||
WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
|
||||
cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Saw no special markers, try to guess from the component IDs */
|
||||
int cid0 = cinfo->comp_info[0].component_id;
|
||||
int cid1 = cinfo->comp_info[1].component_id;
|
||||
int cid2 = cinfo->comp_info[2].component_id;
|
||||
|
||||
if (cid0 == 1 && cid1 == 2 && cid2 == 3)
|
||||
cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
|
||||
else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
|
||||
cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
|
||||
else {
|
||||
TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
|
||||
cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
|
||||
}
|
||||
}
|
||||
/* Always guess RGB is proper output colorspace. */
|
||||
cinfo->out_color_space = JCS_RGB;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (cinfo->saw_Adobe_marker) {
|
||||
switch (cinfo->Adobe_transform) {
|
||||
case 0:
|
||||
cinfo->jpeg_color_space = JCS_CMYK;
|
||||
break;
|
||||
case 2:
|
||||
cinfo->jpeg_color_space = JCS_YCCK;
|
||||
break;
|
||||
default:
|
||||
WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
|
||||
cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* No special markers, assume straight CMYK. */
|
||||
cinfo->jpeg_color_space = JCS_CMYK;
|
||||
}
|
||||
cinfo->out_color_space = JCS_CMYK;
|
||||
break;
|
||||
|
||||
default:
|
||||
cinfo->jpeg_color_space = JCS_UNKNOWN;
|
||||
cinfo->out_color_space = JCS_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set defaults for other decompression parameters. */
|
||||
cinfo->scale_num = 1; /* 1:1 scaling */
|
||||
cinfo->scale_denom = 1;
|
||||
cinfo->output_gamma = 1.0;
|
||||
cinfo->buffered_image = FALSE;
|
||||
cinfo->raw_data_out = FALSE;
|
||||
cinfo->dct_method = JDCT_DEFAULT;
|
||||
cinfo->do_fancy_upsampling = TRUE;
|
||||
cinfo->do_block_smoothing = TRUE;
|
||||
cinfo->quantize_colors = FALSE;
|
||||
/* We set these in case application only sets quantize_colors. */
|
||||
cinfo->dither_mode = JDITHER_FS;
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
cinfo->two_pass_quantize = TRUE;
|
||||
#else
|
||||
cinfo->two_pass_quantize = FALSE;
|
||||
#endif
|
||||
cinfo->desired_number_of_colors = 256;
|
||||
cinfo->colormap = NULL;
|
||||
/* Initialize for no mode change in buffered-image mode. */
|
||||
cinfo->enable_1pass_quant = FALSE;
|
||||
cinfo->enable_external_quant = FALSE;
|
||||
cinfo->enable_2pass_quant = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Decompression startup: read start of JPEG datastream to see what's there.
|
||||
* Need only initialize JPEG object and supply a data source before calling.
|
||||
*
|
||||
* This routine will read as far as the first SOS marker (ie, actual start of
|
||||
* compressed data), and will save all tables and parameters in the JPEG
|
||||
* object. It will also initialize the decompression parameters to default
|
||||
* values, and finally return JPEG_HEADER_OK. On return, the application may
|
||||
* adjust the decompression parameters and then call jpeg_start_decompress.
|
||||
* (Or, if the application only wanted to determine the image parameters,
|
||||
* the data need not be decompressed. In that case, call jpeg_abort or
|
||||
* jpeg_destroy to release any temporary space.)
|
||||
* If an abbreviated (tables only) datastream is presented, the routine will
|
||||
* return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then
|
||||
* re-use the JPEG object to read the abbreviated image datastream(s).
|
||||
* It is unnecessary (but OK) to call jpeg_abort in this case.
|
||||
* The JPEG_SUSPENDED return code only occurs if the data source module
|
||||
* requests suspension of the decompressor. In this case the application
|
||||
* should load more source data and then re-call jpeg_read_header to resume
|
||||
* processing.
|
||||
* If a non-suspending data source is used and require_image is TRUE, then the
|
||||
* return code need not be inspected since only JPEG_HEADER_OK is possible.
|
||||
*
|
||||
* This routine is now just a front end to jpeg_consume_input, with some
|
||||
* extra error checking.
|
||||
*/
|
||||
|
||||
GLOBAL(int)
|
||||
jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
|
||||
{
|
||||
int retcode;
|
||||
|
||||
if (cinfo->global_state != DSTATE_START &&
|
||||
cinfo->global_state != DSTATE_INHEADER)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
retcode = jpeg_consume_input(cinfo);
|
||||
|
||||
switch (retcode) {
|
||||
case JPEG_REACHED_SOS:
|
||||
retcode = JPEG_HEADER_OK;
|
||||
break;
|
||||
case JPEG_REACHED_EOI:
|
||||
if (require_image) /* Complain if application wanted an image */
|
||||
ERREXIT(cinfo, JERR_NO_IMAGE);
|
||||
/* Reset to start state; it would be safer to require the application to
|
||||
* call jpeg_abort, but we can't change it now for compatibility reasons.
|
||||
* A side effect is to free any temporary memory (there shouldn't be any).
|
||||
*/
|
||||
jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */
|
||||
retcode = JPEG_HEADER_TABLES_ONLY;
|
||||
break;
|
||||
case JPEG_SUSPENDED:
|
||||
/* no work */
|
||||
break;
|
||||
}
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Consume data in advance of what the decompressor requires.
|
||||
* This can be called at any time once the decompressor object has
|
||||
* been created and a data source has been set up.
|
||||
*
|
||||
* This routine is essentially a state machine that handles a couple
|
||||
* of critical state-transition actions, namely initial setup and
|
||||
* transition from header scanning to ready-for-start_decompress.
|
||||
* All the actual input is done via the input controller's consume_input
|
||||
* method.
|
||||
*/
|
||||
|
||||
GLOBAL(int)
|
||||
jpeg_consume_input (j_decompress_ptr cinfo)
|
||||
{
|
||||
int retcode = JPEG_SUSPENDED;
|
||||
|
||||
/* NB: every possible DSTATE value should be listed in this switch */
|
||||
switch (cinfo->global_state) {
|
||||
case DSTATE_START:
|
||||
/* Start-of-datastream actions: reset appropriate modules */
|
||||
(*cinfo->inputctl->reset_input_controller) (cinfo);
|
||||
/* Initialize application's data source module */
|
||||
(*cinfo->src->init_source) (cinfo);
|
||||
cinfo->global_state = DSTATE_INHEADER;
|
||||
/*FALLTHROUGH*/
|
||||
case DSTATE_INHEADER:
|
||||
retcode = (*cinfo->inputctl->consume_input) (cinfo);
|
||||
if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */
|
||||
/* Set up default parameters based on header data */
|
||||
default_decompress_parms(cinfo);
|
||||
/* Set global state: ready for start_decompress */
|
||||
cinfo->global_state = DSTATE_READY;
|
||||
}
|
||||
break;
|
||||
case DSTATE_READY:
|
||||
/* Can't advance past first SOS until start_decompress is called */
|
||||
retcode = JPEG_REACHED_SOS;
|
||||
break;
|
||||
case DSTATE_PRELOAD:
|
||||
case DSTATE_PRESCAN:
|
||||
case DSTATE_SCANNING:
|
||||
case DSTATE_RAW_OK:
|
||||
case DSTATE_BUFIMAGE:
|
||||
case DSTATE_BUFPOST:
|
||||
case DSTATE_STOPPING:
|
||||
retcode = (*cinfo->inputctl->consume_input) (cinfo);
|
||||
break;
|
||||
default:
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
}
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Have we finished reading the input file?
|
||||
*/
|
||||
|
||||
GLOBAL(boolean)
|
||||
jpeg_input_complete (j_decompress_ptr cinfo)
|
||||
{
|
||||
/* Check for valid jpeg object */
|
||||
if (cinfo->global_state < DSTATE_START ||
|
||||
cinfo->global_state > DSTATE_STOPPING)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
return cinfo->inputctl->eoi_reached;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Is there more than one scan?
|
||||
*/
|
||||
|
||||
GLOBAL(boolean)
|
||||
jpeg_has_multiple_scans (j_decompress_ptr cinfo)
|
||||
{
|
||||
/* Only valid after jpeg_read_header completes */
|
||||
if (cinfo->global_state < DSTATE_READY ||
|
||||
cinfo->global_state > DSTATE_STOPPING)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
return cinfo->inputctl->has_multiple_scans;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish JPEG decompression.
|
||||
*
|
||||
* This will normally just verify the file trailer and release temp storage.
|
||||
*
|
||||
* Returns FALSE if suspended. The return value need be inspected only if
|
||||
* a suspending data source is used.
|
||||
*/
|
||||
|
||||
GLOBAL(boolean)
|
||||
jpeg_finish_decompress (j_decompress_ptr cinfo)
|
||||
{
|
||||
if ((cinfo->global_state == DSTATE_SCANNING ||
|
||||
cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) {
|
||||
/* Terminate final pass of non-buffered mode */
|
||||
if (cinfo->output_scanline < cinfo->output_height)
|
||||
ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
|
||||
(*cinfo->master->finish_output_pass) (cinfo);
|
||||
cinfo->global_state = DSTATE_STOPPING;
|
||||
} else if (cinfo->global_state == DSTATE_BUFIMAGE) {
|
||||
/* Finishing after a buffered-image operation */
|
||||
cinfo->global_state = DSTATE_STOPPING;
|
||||
} else if (cinfo->global_state != DSTATE_STOPPING) {
|
||||
/* STOPPING = repeat call after a suspension, anything else is error */
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
}
|
||||
/* Read until EOI */
|
||||
while (! cinfo->inputctl->eoi_reached) {
|
||||
if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
|
||||
return FALSE; /* Suspend, come back later */
|
||||
}
|
||||
/* Do final cleanup */
|
||||
(*cinfo->src->term_source) (cinfo);
|
||||
/* We can use jpeg_abort to release memory and reset global_state */
|
||||
jpeg_abort((j_common_ptr) cinfo);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1,275 +1,275 @@
|
||||
/*
|
||||
* jdapistd.c
|
||||
*
|
||||
* Copyright (C) 1994-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 application interface code for the decompression half
|
||||
* of the JPEG library. These are the "standard" API routines that are
|
||||
* used in the normal full-decompression case. They are not used by a
|
||||
* transcoding-only application. Note that if an application links in
|
||||
* jpeg_start_decompress, it will end up linking in the entire decompressor.
|
||||
* We thus must separate this file from jdapimin.c to avoid linking the
|
||||
* whole decompression library into a transcoder.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
|
||||
|
||||
|
||||
/*
|
||||
* Decompression initialization.
|
||||
* jpeg_read_header must be completed before calling this.
|
||||
*
|
||||
* If a multipass operating mode was selected, this will do all but the
|
||||
* last pass, and thus may take a great deal of time.
|
||||
*
|
||||
* Returns FALSE if suspended. The return value need be inspected only if
|
||||
* a suspending data source is used.
|
||||
*/
|
||||
|
||||
GLOBAL(boolean)
|
||||
jpeg_start_decompress (j_decompress_ptr cinfo)
|
||||
{
|
||||
if (cinfo->global_state == DSTATE_READY) {
|
||||
/* First call: initialize master control, select active modules */
|
||||
jinit_master_decompress(cinfo);
|
||||
if (cinfo->buffered_image) {
|
||||
/* No more work here; expecting jpeg_start_output next */
|
||||
cinfo->global_state = DSTATE_BUFIMAGE;
|
||||
return TRUE;
|
||||
}
|
||||
cinfo->global_state = DSTATE_PRELOAD;
|
||||
}
|
||||
if (cinfo->global_state == DSTATE_PRELOAD) {
|
||||
/* If file has multiple scans, absorb them all into the coef buffer */
|
||||
if (cinfo->inputctl->has_multiple_scans) {
|
||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
||||
for (;;) {
|
||||
int retcode;
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL)
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
/* Absorb some more input */
|
||||
retcode = (*cinfo->inputctl->consume_input) (cinfo);
|
||||
if (retcode == JPEG_SUSPENDED)
|
||||
return FALSE;
|
||||
if (retcode == JPEG_REACHED_EOI)
|
||||
break;
|
||||
/* Advance progress counter if appropriate */
|
||||
if (cinfo->progress != NULL &&
|
||||
(retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
|
||||
if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
|
||||
/* jdmaster underestimated number of scans; ratchet up one scan */
|
||||
cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif /* D_MULTISCAN_FILES_SUPPORTED */
|
||||
}
|
||||
cinfo->output_scan_number = cinfo->input_scan_number;
|
||||
} else if (cinfo->global_state != DSTATE_PRESCAN)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
/* Perform any dummy output passes, and set up for the final pass */
|
||||
return output_pass_setup(cinfo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set up for an output pass, and perform any dummy pass(es) needed.
|
||||
* Common subroutine for jpeg_start_decompress and jpeg_start_output.
|
||||
* Entry: global_state = DSTATE_PRESCAN only if previously suspended.
|
||||
* Exit: If done, returns TRUE and sets global_state for proper output mode.
|
||||
* If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
|
||||
*/
|
||||
|
||||
LOCAL(boolean)
|
||||
output_pass_setup (j_decompress_ptr cinfo)
|
||||
{
|
||||
if (cinfo->global_state != DSTATE_PRESCAN) {
|
||||
/* First call: do pass setup */
|
||||
(*cinfo->master->prepare_for_output_pass) (cinfo);
|
||||
cinfo->output_scanline = 0;
|
||||
cinfo->global_state = DSTATE_PRESCAN;
|
||||
}
|
||||
/* Loop over any required dummy passes */
|
||||
while (cinfo->master->is_dummy_pass) {
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
/* Crank through the dummy pass */
|
||||
while (cinfo->output_scanline < cinfo->output_height) {
|
||||
JDIMENSION last_scanline;
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL) {
|
||||
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
|
||||
cinfo->progress->pass_limit = (long) cinfo->output_height;
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
}
|
||||
/* Process some data */
|
||||
last_scanline = cinfo->output_scanline;
|
||||
(*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
|
||||
&cinfo->output_scanline, (JDIMENSION) 0);
|
||||
if (cinfo->output_scanline == last_scanline)
|
||||
return FALSE; /* No progress made, must suspend */
|
||||
}
|
||||
/* Finish up dummy pass, and set up for another one */
|
||||
(*cinfo->master->finish_output_pass) (cinfo);
|
||||
(*cinfo->master->prepare_for_output_pass) (cinfo);
|
||||
cinfo->output_scanline = 0;
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
}
|
||||
/* Ready for application to drive output pass through
|
||||
* jpeg_read_scanlines or jpeg_read_raw_data.
|
||||
*/
|
||||
cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read some scanlines of data from the JPEG decompressor.
|
||||
*
|
||||
* The return value will be the number of lines actually read.
|
||||
* This may be less than the number requested in several cases,
|
||||
* including bottom of image, data source suspension, and operating
|
||||
* modes that emit multiple scanlines at a time.
|
||||
*
|
||||
* Note: we warn about excess calls to jpeg_read_scanlines() since
|
||||
* this likely signals an application programmer error. However,
|
||||
* an oversize buffer (max_lines > scanlines remaining) is not an error.
|
||||
*/
|
||||
|
||||
GLOBAL(JDIMENSION)
|
||||
jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
|
||||
JDIMENSION max_lines)
|
||||
{
|
||||
JDIMENSION row_ctr;
|
||||
|
||||
if (cinfo->global_state != DSTATE_SCANNING)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
if (cinfo->output_scanline >= cinfo->output_height) {
|
||||
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL) {
|
||||
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
|
||||
cinfo->progress->pass_limit = (long) cinfo->output_height;
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
}
|
||||
|
||||
/* Process some data */
|
||||
row_ctr = 0;
|
||||
(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
|
||||
cinfo->output_scanline += row_ctr;
|
||||
return row_ctr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Alternate entry point to read raw data.
|
||||
* Processes exactly one iMCU row per call, unless suspended.
|
||||
*/
|
||||
|
||||
GLOBAL(JDIMENSION)
|
||||
jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
|
||||
JDIMENSION max_lines)
|
||||
{
|
||||
JDIMENSION lines_per_iMCU_row;
|
||||
|
||||
if (cinfo->global_state != DSTATE_RAW_OK)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
if (cinfo->output_scanline >= cinfo->output_height) {
|
||||
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL) {
|
||||
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
|
||||
cinfo->progress->pass_limit = (long) cinfo->output_height;
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
}
|
||||
|
||||
/* Verify that at least one iMCU row can be returned. */
|
||||
lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
|
||||
if (max_lines < lines_per_iMCU_row)
|
||||
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
||||
|
||||
/* Decompress directly into user's buffer. */
|
||||
if (! (*cinfo->coef->decompress_data) (cinfo, data))
|
||||
return 0; /* suspension forced, can do nothing more */
|
||||
|
||||
/* OK, we processed one iMCU row. */
|
||||
cinfo->output_scanline += lines_per_iMCU_row;
|
||||
return lines_per_iMCU_row;
|
||||
}
|
||||
|
||||
|
||||
/* Additional entry points for buffered-image mode. */
|
||||
|
||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
||||
|
||||
/*
|
||||
* Initialize for an output pass in buffered-image mode.
|
||||
*/
|
||||
|
||||
GLOBAL(boolean)
|
||||
jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
|
||||
{
|
||||
if (cinfo->global_state != DSTATE_BUFIMAGE &&
|
||||
cinfo->global_state != DSTATE_PRESCAN)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
/* Limit scan number to valid range */
|
||||
if (scan_number <= 0)
|
||||
scan_number = 1;
|
||||
if (cinfo->inputctl->eoi_reached &&
|
||||
scan_number > cinfo->input_scan_number)
|
||||
scan_number = cinfo->input_scan_number;
|
||||
cinfo->output_scan_number = scan_number;
|
||||
/* Perform any dummy output passes, and set up for the real pass */
|
||||
return output_pass_setup(cinfo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish up after an output pass in buffered-image mode.
|
||||
*
|
||||
* Returns FALSE if suspended. The return value need be inspected only if
|
||||
* a suspending data source is used.
|
||||
*/
|
||||
|
||||
GLOBAL(boolean)
|
||||
jpeg_finish_output (j_decompress_ptr cinfo)
|
||||
{
|
||||
if ((cinfo->global_state == DSTATE_SCANNING ||
|
||||
cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
|
||||
/* Terminate this pass. */
|
||||
/* We do not require the whole pass to have been completed. */
|
||||
(*cinfo->master->finish_output_pass) (cinfo);
|
||||
cinfo->global_state = DSTATE_BUFPOST;
|
||||
} else if (cinfo->global_state != DSTATE_BUFPOST) {
|
||||
/* BUFPOST = repeat call after a suspension, anything else is error */
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
}
|
||||
/* Read markers looking for SOS or EOI */
|
||||
while (cinfo->input_scan_number <= cinfo->output_scan_number &&
|
||||
! cinfo->inputctl->eoi_reached) {
|
||||
if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
|
||||
return FALSE; /* Suspend, come back later */
|
||||
}
|
||||
cinfo->global_state = DSTATE_BUFIMAGE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* D_MULTISCAN_FILES_SUPPORTED */
|
||||
/*
|
||||
* jdapistd.c
|
||||
*
|
||||
* Copyright (C) 1994-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 application interface code for the decompression half
|
||||
* of the JPEG library. These are the "standard" API routines that are
|
||||
* used in the normal full-decompression case. They are not used by a
|
||||
* transcoding-only application. Note that if an application links in
|
||||
* jpeg_start_decompress, it will end up linking in the entire decompressor.
|
||||
* We thus must separate this file from jdapimin.c to avoid linking the
|
||||
* whole decompression library into a transcoder.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
|
||||
|
||||
|
||||
/*
|
||||
* Decompression initialization.
|
||||
* jpeg_read_header must be completed before calling this.
|
||||
*
|
||||
* If a multipass operating mode was selected, this will do all but the
|
||||
* last pass, and thus may take a great deal of time.
|
||||
*
|
||||
* Returns FALSE if suspended. The return value need be inspected only if
|
||||
* a suspending data source is used.
|
||||
*/
|
||||
|
||||
GLOBAL(boolean)
|
||||
jpeg_start_decompress (j_decompress_ptr cinfo)
|
||||
{
|
||||
if (cinfo->global_state == DSTATE_READY) {
|
||||
/* First call: initialize master control, select active modules */
|
||||
jinit_master_decompress(cinfo);
|
||||
if (cinfo->buffered_image) {
|
||||
/* No more work here; expecting jpeg_start_output next */
|
||||
cinfo->global_state = DSTATE_BUFIMAGE;
|
||||
return TRUE;
|
||||
}
|
||||
cinfo->global_state = DSTATE_PRELOAD;
|
||||
}
|
||||
if (cinfo->global_state == DSTATE_PRELOAD) {
|
||||
/* If file has multiple scans, absorb them all into the coef buffer */
|
||||
if (cinfo->inputctl->has_multiple_scans) {
|
||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
||||
for (;;) {
|
||||
int retcode;
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL)
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
/* Absorb some more input */
|
||||
retcode = (*cinfo->inputctl->consume_input) (cinfo);
|
||||
if (retcode == JPEG_SUSPENDED)
|
||||
return FALSE;
|
||||
if (retcode == JPEG_REACHED_EOI)
|
||||
break;
|
||||
/* Advance progress counter if appropriate */
|
||||
if (cinfo->progress != NULL &&
|
||||
(retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
|
||||
if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
|
||||
/* jdmaster underestimated number of scans; ratchet up one scan */
|
||||
cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif /* D_MULTISCAN_FILES_SUPPORTED */
|
||||
}
|
||||
cinfo->output_scan_number = cinfo->input_scan_number;
|
||||
} else if (cinfo->global_state != DSTATE_PRESCAN)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
/* Perform any dummy output passes, and set up for the final pass */
|
||||
return output_pass_setup(cinfo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set up for an output pass, and perform any dummy pass(es) needed.
|
||||
* Common subroutine for jpeg_start_decompress and jpeg_start_output.
|
||||
* Entry: global_state = DSTATE_PRESCAN only if previously suspended.
|
||||
* Exit: If done, returns TRUE and sets global_state for proper output mode.
|
||||
* If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
|
||||
*/
|
||||
|
||||
LOCAL(boolean)
|
||||
output_pass_setup (j_decompress_ptr cinfo)
|
||||
{
|
||||
if (cinfo->global_state != DSTATE_PRESCAN) {
|
||||
/* First call: do pass setup */
|
||||
(*cinfo->master->prepare_for_output_pass) (cinfo);
|
||||
cinfo->output_scanline = 0;
|
||||
cinfo->global_state = DSTATE_PRESCAN;
|
||||
}
|
||||
/* Loop over any required dummy passes */
|
||||
while (cinfo->master->is_dummy_pass) {
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
/* Crank through the dummy pass */
|
||||
while (cinfo->output_scanline < cinfo->output_height) {
|
||||
JDIMENSION last_scanline;
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL) {
|
||||
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
|
||||
cinfo->progress->pass_limit = (long) cinfo->output_height;
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
}
|
||||
/* Process some data */
|
||||
last_scanline = cinfo->output_scanline;
|
||||
(*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
|
||||
&cinfo->output_scanline, (JDIMENSION) 0);
|
||||
if (cinfo->output_scanline == last_scanline)
|
||||
return FALSE; /* No progress made, must suspend */
|
||||
}
|
||||
/* Finish up dummy pass, and set up for another one */
|
||||
(*cinfo->master->finish_output_pass) (cinfo);
|
||||
(*cinfo->master->prepare_for_output_pass) (cinfo);
|
||||
cinfo->output_scanline = 0;
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
}
|
||||
/* Ready for application to drive output pass through
|
||||
* jpeg_read_scanlines or jpeg_read_raw_data.
|
||||
*/
|
||||
cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read some scanlines of data from the JPEG decompressor.
|
||||
*
|
||||
* The return value will be the number of lines actually read.
|
||||
* This may be less than the number requested in several cases,
|
||||
* including bottom of image, data source suspension, and operating
|
||||
* modes that emit multiple scanlines at a time.
|
||||
*
|
||||
* Note: we warn about excess calls to jpeg_read_scanlines() since
|
||||
* this likely signals an application programmer error. However,
|
||||
* an oversize buffer (max_lines > scanlines remaining) is not an error.
|
||||
*/
|
||||
|
||||
GLOBAL(JDIMENSION)
|
||||
jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
|
||||
JDIMENSION max_lines)
|
||||
{
|
||||
JDIMENSION row_ctr;
|
||||
|
||||
if (cinfo->global_state != DSTATE_SCANNING)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
if (cinfo->output_scanline >= cinfo->output_height) {
|
||||
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL) {
|
||||
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
|
||||
cinfo->progress->pass_limit = (long) cinfo->output_height;
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
}
|
||||
|
||||
/* Process some data */
|
||||
row_ctr = 0;
|
||||
(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
|
||||
cinfo->output_scanline += row_ctr;
|
||||
return row_ctr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Alternate entry point to read raw data.
|
||||
* Processes exactly one iMCU row per call, unless suspended.
|
||||
*/
|
||||
|
||||
GLOBAL(JDIMENSION)
|
||||
jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
|
||||
JDIMENSION max_lines)
|
||||
{
|
||||
JDIMENSION lines_per_iMCU_row;
|
||||
|
||||
if (cinfo->global_state != DSTATE_RAW_OK)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
if (cinfo->output_scanline >= cinfo->output_height) {
|
||||
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL) {
|
||||
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
|
||||
cinfo->progress->pass_limit = (long) cinfo->output_height;
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
}
|
||||
|
||||
/* Verify that at least one iMCU row can be returned. */
|
||||
lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
|
||||
if (max_lines < lines_per_iMCU_row)
|
||||
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
||||
|
||||
/* Decompress directly into user's buffer. */
|
||||
if (! (*cinfo->coef->decompress_data) (cinfo, data))
|
||||
return 0; /* suspension forced, can do nothing more */
|
||||
|
||||
/* OK, we processed one iMCU row. */
|
||||
cinfo->output_scanline += lines_per_iMCU_row;
|
||||
return lines_per_iMCU_row;
|
||||
}
|
||||
|
||||
|
||||
/* Additional entry points for buffered-image mode. */
|
||||
|
||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
||||
|
||||
/*
|
||||
* Initialize for an output pass in buffered-image mode.
|
||||
*/
|
||||
|
||||
GLOBAL(boolean)
|
||||
jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
|
||||
{
|
||||
if (cinfo->global_state != DSTATE_BUFIMAGE &&
|
||||
cinfo->global_state != DSTATE_PRESCAN)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
/* Limit scan number to valid range */
|
||||
if (scan_number <= 0)
|
||||
scan_number = 1;
|
||||
if (cinfo->inputctl->eoi_reached &&
|
||||
scan_number > cinfo->input_scan_number)
|
||||
scan_number = cinfo->input_scan_number;
|
||||
cinfo->output_scan_number = scan_number;
|
||||
/* Perform any dummy output passes, and set up for the real pass */
|
||||
return output_pass_setup(cinfo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish up after an output pass in buffered-image mode.
|
||||
*
|
||||
* Returns FALSE if suspended. The return value need be inspected only if
|
||||
* a suspending data source is used.
|
||||
*/
|
||||
|
||||
GLOBAL(boolean)
|
||||
jpeg_finish_output (j_decompress_ptr cinfo)
|
||||
{
|
||||
if ((cinfo->global_state == DSTATE_SCANNING ||
|
||||
cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
|
||||
/* Terminate this pass. */
|
||||
/* We do not require the whole pass to have been completed. */
|
||||
(*cinfo->master->finish_output_pass) (cinfo);
|
||||
cinfo->global_state = DSTATE_BUFPOST;
|
||||
} else if (cinfo->global_state != DSTATE_BUFPOST) {
|
||||
/* BUFPOST = repeat call after a suspension, anything else is error */
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
}
|
||||
/* Read markers looking for SOS or EOI */
|
||||
while (cinfo->input_scan_number <= cinfo->output_scan_number &&
|
||||
! cinfo->inputctl->eoi_reached) {
|
||||
if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
|
||||
return FALSE; /* Suspend, come back later */
|
||||
}
|
||||
cinfo->global_state = DSTATE_BUFIMAGE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* D_MULTISCAN_FILES_SUPPORTED */
|
||||
|
@ -1,212 +1,212 @@
|
||||
/*
|
||||
* jdatasrc.c
|
||||
*
|
||||
* Copyright (C) 1994-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 decompression data source routines for the case of
|
||||
* reading JPEG data from a file (or any stdio stream). While these routines
|
||||
* are sufficient for most applications, some will want to use a different
|
||||
* source manager.
|
||||
* IMPORTANT: we assume that fread() will correctly transcribe an array of
|
||||
* JOCTETs from 8-bit-wide elements on external storage. If char is wider
|
||||
* than 8 bits on your machine, you may need to do some tweaking.
|
||||
*/
|
||||
|
||||
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jerror.h"
|
||||
|
||||
|
||||
/* Expanded data source object for stdio input */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_source_mgr pub; /* public fields */
|
||||
|
||||
FILE * infile; /* source stream */
|
||||
JOCTET * buffer; /* start of buffer */
|
||||
boolean start_of_file; /* have we gotten any data yet? */
|
||||
} my_source_mgr;
|
||||
|
||||
typedef my_source_mgr * my_src_ptr;
|
||||
|
||||
#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize source --- called by jpeg_read_header
|
||||
* before any data is actually read.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
init_source (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
|
||||
/* We reset the empty-input-file flag for each image,
|
||||
* but we don't clear the input buffer.
|
||||
* This is correct behavior for reading a series of images from one source.
|
||||
*/
|
||||
src->start_of_file = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fill the input buffer --- called whenever buffer is emptied.
|
||||
*
|
||||
* In typical applications, this should read fresh data into the buffer
|
||||
* (ignoring the current state of next_input_byte & bytes_in_buffer),
|
||||
* reset the pointer & count to the start of the buffer, and return TRUE
|
||||
* indicating that the buffer has been reloaded. It is not necessary to
|
||||
* fill the buffer entirely, only to obtain at least one more byte.
|
||||
*
|
||||
* There is no such thing as an EOF return. If the end of the file has been
|
||||
* reached, the routine has a choice of ERREXIT() or inserting fake data into
|
||||
* the buffer. In most cases, generating a warning message and inserting a
|
||||
* fake EOI marker is the best course of action --- this will allow the
|
||||
* decompressor to output however much of the image is there. However,
|
||||
* the resulting error message is misleading if the real problem is an empty
|
||||
* input file, so we handle that case specially.
|
||||
*
|
||||
* In applications that need to be able to suspend compression due to input
|
||||
* not being available yet, a FALSE return indicates that no more data can be
|
||||
* obtained right now, but more may be forthcoming later. In this situation,
|
||||
* the decompressor will return to its caller (with an indication of the
|
||||
* number of scanlines it has read, if any). The application should resume
|
||||
* decompression after it has loaded more data into the input buffer. Note
|
||||
* that there are substantial restrictions on the use of suspension --- see
|
||||
* the documentation.
|
||||
*
|
||||
* When suspending, the decompressor will back up to a convenient restart point
|
||||
* (typically the start of the current MCU). next_input_byte & bytes_in_buffer
|
||||
* indicate where the restart point will be if the current call returns FALSE.
|
||||
* Data beyond this point must be rescanned after resumption, so move it to
|
||||
* the front of the buffer rather than discarding it.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
fill_input_buffer (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
size_t nbytes;
|
||||
|
||||
nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE);
|
||||
|
||||
if (nbytes <= 0) {
|
||||
if (src->start_of_file) /* Treat empty input file as fatal error */
|
||||
ERREXIT(cinfo, JERR_INPUT_EMPTY);
|
||||
WARNMS(cinfo, JWRN_JPEG_EOF);
|
||||
/* Insert a fake EOI marker */
|
||||
src->buffer[0] = (JOCTET) 0xFF;
|
||||
src->buffer[1] = (JOCTET) JPEG_EOI;
|
||||
nbytes = 2;
|
||||
}
|
||||
|
||||
src->pub.next_input_byte = src->buffer;
|
||||
src->pub.bytes_in_buffer = nbytes;
|
||||
src->start_of_file = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Skip data --- used to skip over a potentially large amount of
|
||||
* uninteresting data (such as an APPn marker).
|
||||
*
|
||||
* Writers of suspendable-input applications must note that skip_input_data
|
||||
* is not granted the right to give a suspension return. If the skip extends
|
||||
* beyond the data currently in the buffer, the buffer can be marked empty so
|
||||
* that the next read will cause a fill_input_buffer call that can suspend.
|
||||
* Arranging for additional bytes to be discarded before reloading the input
|
||||
* buffer is the application writer's problem.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
|
||||
/* Just a dumb implementation for now. Could use fseek() except
|
||||
* it doesn't work on pipes. Not clear that being smart is worth
|
||||
* any trouble anyway --- large skips are infrequent.
|
||||
*/
|
||||
if (num_bytes > 0) {
|
||||
while (num_bytes > (long) src->pub.bytes_in_buffer) {
|
||||
num_bytes -= (long) src->pub.bytes_in_buffer;
|
||||
(void) fill_input_buffer(cinfo);
|
||||
/* note we assume that fill_input_buffer will never return FALSE,
|
||||
* so suspension need not be handled.
|
||||
*/
|
||||
}
|
||||
src->pub.next_input_byte += (size_t) num_bytes;
|
||||
src->pub.bytes_in_buffer -= (size_t) num_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* An additional method that can be provided by data source modules is the
|
||||
* resync_to_restart method for error recovery in the presence of RST markers.
|
||||
* For the moment, this source module just uses the default resync method
|
||||
* provided by the JPEG library. That method assumes that no backtracking
|
||||
* is possible.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Terminate source --- called by jpeg_finish_decompress
|
||||
* after all data has been read. Often a no-op.
|
||||
*
|
||||
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
|
||||
* application must deal with any cleanup that should happen even
|
||||
* for error exit.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
term_source (j_decompress_ptr)
|
||||
{
|
||||
/* no work necessary here */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for input from a stdio stream.
|
||||
* The caller must have already opened the stream, and is responsible
|
||||
* for closing it after finishing decompression.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
|
||||
{
|
||||
my_src_ptr src;
|
||||
|
||||
/* The source object and input buffer are made permanent so that a series
|
||||
* of JPEG images can be read from the same file by calling jpeg_stdio_src
|
||||
* only before the first one. (If we discarded the buffer at the end of
|
||||
* one image, we'd likely lose the start of the next one.)
|
||||
* This makes it unsafe to use this manager and a different source
|
||||
* manager serially with the same JPEG object. Caveat programmer.
|
||||
*/
|
||||
if (cinfo->src == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->src = (struct jpeg_source_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(my_source_mgr));
|
||||
src = (my_src_ptr) cinfo->src;
|
||||
src->buffer = (JOCTET *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
INPUT_BUF_SIZE * SIZEOF(JOCTET));
|
||||
}
|
||||
|
||||
src = (my_src_ptr) cinfo->src;
|
||||
src->pub.init_source = init_source;
|
||||
src->pub.fill_input_buffer = fill_input_buffer;
|
||||
src->pub.skip_input_data = skip_input_data;
|
||||
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
|
||||
src->pub.term_source = term_source;
|
||||
src->infile = infile;
|
||||
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
|
||||
src->pub.next_input_byte = NULL; /* until buffer loaded */
|
||||
}
|
||||
/*
|
||||
* jdatasrc.c
|
||||
*
|
||||
* Copyright (C) 1994-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 decompression data source routines for the case of
|
||||
* reading JPEG data from a file (or any stdio stream). While these routines
|
||||
* are sufficient for most applications, some will want to use a different
|
||||
* source manager.
|
||||
* IMPORTANT: we assume that fread() will correctly transcribe an array of
|
||||
* JOCTETs from 8-bit-wide elements on external storage. If char is wider
|
||||
* than 8 bits on your machine, you may need to do some tweaking.
|
||||
*/
|
||||
|
||||
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jerror.h"
|
||||
|
||||
|
||||
/* Expanded data source object for stdio input */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_source_mgr pub; /* public fields */
|
||||
|
||||
FILE * infile; /* source stream */
|
||||
JOCTET * buffer; /* start of buffer */
|
||||
boolean start_of_file; /* have we gotten any data yet? */
|
||||
} my_source_mgr;
|
||||
|
||||
typedef my_source_mgr * my_src_ptr;
|
||||
|
||||
#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize source --- called by jpeg_read_header
|
||||
* before any data is actually read.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
init_source (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
|
||||
/* We reset the empty-input-file flag for each image,
|
||||
* but we don't clear the input buffer.
|
||||
* This is correct behavior for reading a series of images from one source.
|
||||
*/
|
||||
src->start_of_file = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fill the input buffer --- called whenever buffer is emptied.
|
||||
*
|
||||
* In typical applications, this should read fresh data into the buffer
|
||||
* (ignoring the current state of next_input_byte & bytes_in_buffer),
|
||||
* reset the pointer & count to the start of the buffer, and return TRUE
|
||||
* indicating that the buffer has been reloaded. It is not necessary to
|
||||
* fill the buffer entirely, only to obtain at least one more byte.
|
||||
*
|
||||
* There is no such thing as an EOF return. If the end of the file has been
|
||||
* reached, the routine has a choice of ERREXIT() or inserting fake data into
|
||||
* the buffer. In most cases, generating a warning message and inserting a
|
||||
* fake EOI marker is the best course of action --- this will allow the
|
||||
* decompressor to output however much of the image is there. However,
|
||||
* the resulting error message is misleading if the real problem is an empty
|
||||
* input file, so we handle that case specially.
|
||||
*
|
||||
* In applications that need to be able to suspend compression due to input
|
||||
* not being available yet, a FALSE return indicates that no more data can be
|
||||
* obtained right now, but more may be forthcoming later. In this situation,
|
||||
* the decompressor will return to its caller (with an indication of the
|
||||
* number of scanlines it has read, if any). The application should resume
|
||||
* decompression after it has loaded more data into the input buffer. Note
|
||||
* that there are substantial restrictions on the use of suspension --- see
|
||||
* the documentation.
|
||||
*
|
||||
* When suspending, the decompressor will back up to a convenient restart point
|
||||
* (typically the start of the current MCU). next_input_byte & bytes_in_buffer
|
||||
* indicate where the restart point will be if the current call returns FALSE.
|
||||
* Data beyond this point must be rescanned after resumption, so move it to
|
||||
* the front of the buffer rather than discarding it.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
fill_input_buffer (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
size_t nbytes;
|
||||
|
||||
nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE);
|
||||
|
||||
if (nbytes <= 0) {
|
||||
if (src->start_of_file) /* Treat empty input file as fatal error */
|
||||
ERREXIT(cinfo, JERR_INPUT_EMPTY);
|
||||
WARNMS(cinfo, JWRN_JPEG_EOF);
|
||||
/* Insert a fake EOI marker */
|
||||
src->buffer[0] = (JOCTET) 0xFF;
|
||||
src->buffer[1] = (JOCTET) JPEG_EOI;
|
||||
nbytes = 2;
|
||||
}
|
||||
|
||||
src->pub.next_input_byte = src->buffer;
|
||||
src->pub.bytes_in_buffer = nbytes;
|
||||
src->start_of_file = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Skip data --- used to skip over a potentially large amount of
|
||||
* uninteresting data (such as an APPn marker).
|
||||
*
|
||||
* Writers of suspendable-input applications must note that skip_input_data
|
||||
* is not granted the right to give a suspension return. If the skip extends
|
||||
* beyond the data currently in the buffer, the buffer can be marked empty so
|
||||
* that the next read will cause a fill_input_buffer call that can suspend.
|
||||
* Arranging for additional bytes to be discarded before reloading the input
|
||||
* buffer is the application writer's problem.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
|
||||
/* Just a dumb implementation for now. Could use fseek() except
|
||||
* it doesn't work on pipes. Not clear that being smart is worth
|
||||
* any trouble anyway --- large skips are infrequent.
|
||||
*/
|
||||
if (num_bytes > 0) {
|
||||
while (num_bytes > (long) src->pub.bytes_in_buffer) {
|
||||
num_bytes -= (long) src->pub.bytes_in_buffer;
|
||||
(void) fill_input_buffer(cinfo);
|
||||
/* note we assume that fill_input_buffer will never return FALSE,
|
||||
* so suspension need not be handled.
|
||||
*/
|
||||
}
|
||||
src->pub.next_input_byte += (size_t) num_bytes;
|
||||
src->pub.bytes_in_buffer -= (size_t) num_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* An additional method that can be provided by data source modules is the
|
||||
* resync_to_restart method for error recovery in the presence of RST markers.
|
||||
* For the moment, this source module just uses the default resync method
|
||||
* provided by the JPEG library. That method assumes that no backtracking
|
||||
* is possible.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Terminate source --- called by jpeg_finish_decompress
|
||||
* after all data has been read. Often a no-op.
|
||||
*
|
||||
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
|
||||
* application must deal with any cleanup that should happen even
|
||||
* for error exit.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
term_source (j_decompress_ptr)
|
||||
{
|
||||
/* no work necessary here */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for input from a stdio stream.
|
||||
* The caller must have already opened the stream, and is responsible
|
||||
* for closing it after finishing decompression.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
|
||||
{
|
||||
my_src_ptr src;
|
||||
|
||||
/* The source object and input buffer are made permanent so that a series
|
||||
* of JPEG images can be read from the same file by calling jpeg_stdio_src
|
||||
* only before the first one. (If we discarded the buffer at the end of
|
||||
* one image, we'd likely lose the start of the next one.)
|
||||
* This makes it unsafe to use this manager and a different source
|
||||
* manager serially with the same JPEG object. Caveat programmer.
|
||||
*/
|
||||
if (cinfo->src == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->src = (struct jpeg_source_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(my_source_mgr));
|
||||
src = (my_src_ptr) cinfo->src;
|
||||
src->buffer = (JOCTET *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
INPUT_BUF_SIZE * SIZEOF(JOCTET));
|
||||
}
|
||||
|
||||
src = (my_src_ptr) cinfo->src;
|
||||
src->pub.init_source = init_source;
|
||||
src->pub.fill_input_buffer = fill_input_buffer;
|
||||
src->pub.skip_input_data = skip_input_data;
|
||||
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
|
||||
src->pub.term_source = term_source;
|
||||
src->infile = infile;
|
||||
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
|
||||
src->pub.next_input_byte = NULL; /* until buffer loaded */
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,396 +1,396 @@
|
||||
/*
|
||||
* jdcolor.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 output colorspace conversion routines.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Private subobject */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_color_deconverter pub; /* public fields */
|
||||
|
||||
/* Private state for YCC->RGB conversion */
|
||||
int * Cr_r_tab; /* => table for Cr to R conversion */
|
||||
int * Cb_b_tab; /* => table for Cb to B conversion */
|
||||
INT32 * Cr_g_tab; /* => table for Cr to G conversion */
|
||||
INT32 * Cb_g_tab; /* => table for Cb to G conversion */
|
||||
} my_color_deconverter2;
|
||||
|
||||
typedef my_color_deconverter2 * my_cconvert_ptr2;
|
||||
|
||||
|
||||
/**************** YCbCr -> RGB conversion: most common case **************/
|
||||
|
||||
/*
|
||||
* YCbCr is defined per CCIR 601-1, except that Cb and Cr are
|
||||
* normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
|
||||
* The conversion equations to be implemented are therefore
|
||||
* R = Y + 1.40200 * Cr
|
||||
* G = Y - 0.34414 * Cb - 0.71414 * Cr
|
||||
* B = Y + 1.77200 * Cb
|
||||
* where Cb and Cr represent the incoming values less CENTERJSAMPLE.
|
||||
* (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
|
||||
*
|
||||
* To avoid floating-point arithmetic, we represent the fractional constants
|
||||
* as integers scaled up by 2^16 (about 4 digits precision); we have to divide
|
||||
* the products by 2^16, with appropriate rounding, to get the correct answer.
|
||||
* Notice that Y, being an integral input, does not contribute any fraction
|
||||
* so it need not participate in the rounding.
|
||||
*
|
||||
* For even more speed, we avoid doing any multiplications in the inner loop
|
||||
* by precalculating the constants times Cb and Cr for all possible values.
|
||||
* For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
|
||||
* for 12-bit samples it is still acceptable. It's not very reasonable for
|
||||
* 16-bit samples, but if you want lossless storage you shouldn't be changing
|
||||
* colorspace anyway.
|
||||
* The Cr=>R and Cb=>B values can be rounded to integers in advance; the
|
||||
* values for the G calculation are left scaled up, since we must add them
|
||||
* together before rounding.
|
||||
*/
|
||||
|
||||
#define SCALEBITS 16 /* speediest right-shift on some machines */
|
||||
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
|
||||
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
|
||||
|
||||
|
||||
/*
|
||||
* Initialize tables for YCC->RGB colorspace conversion.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
build_ycc_rgb_table (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_cconvert_ptr2 cconvert = (my_cconvert_ptr2) cinfo->cconvert;
|
||||
int i;
|
||||
INT32 x;
|
||||
SHIFT_TEMPS
|
||||
|
||||
cconvert->Cr_r_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
cconvert->Cb_b_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
cconvert->Cr_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
cconvert->Cb_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
|
||||
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
|
||||
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
|
||||
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
|
||||
/* Cr=>R value is nearest int to 1.40200 * x */
|
||||
cconvert->Cr_r_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
|
||||
/* Cb=>B value is nearest int to 1.77200 * x */
|
||||
cconvert->Cb_b_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
|
||||
/* Cr=>G value is scaled-up -0.71414 * x */
|
||||
cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
|
||||
/* Cb=>G value is scaled-up -0.34414 * x */
|
||||
/* We also add in ONE_HALF so that need not do it in inner loop */
|
||||
cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the output colorspace.
|
||||
*
|
||||
* Note that we change from noninterleaved, one-plane-per-component format
|
||||
* to interleaved-pixel format. The output buffer is therefore three times
|
||||
* as wide as the input buffer.
|
||||
* A starting row offset is provided only for the input buffer. The caller
|
||||
* can easily adjust the passed output_buf value to accommodate any row
|
||||
* offset required on that side.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
ycc_rgb_convert (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr2 cconvert = (my_cconvert_ptr2) cinfo->cconvert;
|
||||
int y, cb, cr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPROW inptr0, inptr1, inptr2;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
/* copy these pointers into registers if possible */
|
||||
JSAMPLE * range_limit = cinfo->sample_range_limit;
|
||||
int * Crrtab = cconvert->Cr_r_tab;
|
||||
int * Cbbtab = cconvert->Cb_b_tab;
|
||||
INT32 * Crgtab = cconvert->Cr_g_tab;
|
||||
INT32 * Cbgtab = cconvert->Cb_g_tab;
|
||||
SHIFT_TEMPS
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr0 = input_buf[0][input_row];
|
||||
inptr1 = input_buf[1][input_row];
|
||||
inptr2 = input_buf[2][input_row];
|
||||
input_row++;
|
||||
outptr = *output_buf++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
y = GETJSAMPLE(inptr0[col]);
|
||||
cb = GETJSAMPLE(inptr1[col]);
|
||||
cr = GETJSAMPLE(inptr2[col]);
|
||||
/* Range-limiting is essential due to noise introduced by DCT losses. */
|
||||
outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
|
||||
outptr[RGB_GREEN] = range_limit[y +
|
||||
((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
||||
SCALEBITS))];
|
||||
outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];
|
||||
outptr += RGB_PIXELSIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************** Cases other than YCbCr -> RGB **************/
|
||||
|
||||
|
||||
/*
|
||||
* Color conversion for no colorspace change: just copy the data,
|
||||
* converting from separate-planes to interleaved representation.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
null_convert2 (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
JSAMPROW inptr, outptr;
|
||||
JDIMENSION count;
|
||||
int num_components = cinfo->num_components;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
int ci;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
for (ci = 0; ci < num_components; ci++) {
|
||||
inptr = input_buf[ci][input_row];
|
||||
outptr = output_buf[0] + ci;
|
||||
for (count = num_cols; count > 0; count--) {
|
||||
*outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */
|
||||
outptr += num_components;
|
||||
}
|
||||
}
|
||||
input_row++;
|
||||
output_buf++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Color conversion for grayscale: just copy the data.
|
||||
* This also works for YCbCr -> grayscale conversion, in which
|
||||
* we just copy the Y (luminance) component and ignore chrominance.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
grayscale_convert2 (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
|
||||
num_rows, cinfo->output_width);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert grayscale to RGB: just duplicate the graylevel three times.
|
||||
* This is provided to support applications that don't want to cope
|
||||
* with grayscale as a separate case.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
gray_rgb_convert (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
JSAMPROW inptr, outptr;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = input_buf[0][input_row++];
|
||||
outptr = *output_buf++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
/* We can dispense with GETJSAMPLE() here */
|
||||
outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
|
||||
outptr += RGB_PIXELSIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Adobe-style YCCK->CMYK conversion.
|
||||
* We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
|
||||
* conversion as above, while passing K (black) unchanged.
|
||||
* We assume build_ycc_rgb_table has been called.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
ycck_cmyk_convert (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr2 cconvert = (my_cconvert_ptr2) cinfo->cconvert;
|
||||
int y, cb, cr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPROW inptr0, inptr1, inptr2, inptr3;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
/* copy these pointers into registers if possible */
|
||||
JSAMPLE * range_limit = cinfo->sample_range_limit;
|
||||
int * Crrtab = cconvert->Cr_r_tab;
|
||||
int * Cbbtab = cconvert->Cb_b_tab;
|
||||
INT32 * Crgtab = cconvert->Cr_g_tab;
|
||||
INT32 * Cbgtab = cconvert->Cb_g_tab;
|
||||
SHIFT_TEMPS
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr0 = input_buf[0][input_row];
|
||||
inptr1 = input_buf[1][input_row];
|
||||
inptr2 = input_buf[2][input_row];
|
||||
inptr3 = input_buf[3][input_row];
|
||||
input_row++;
|
||||
outptr = *output_buf++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
y = GETJSAMPLE(inptr0[col]);
|
||||
cb = GETJSAMPLE(inptr1[col]);
|
||||
cr = GETJSAMPLE(inptr2[col]);
|
||||
/* Range-limiting is essential due to noise introduced by DCT losses. */
|
||||
outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */
|
||||
outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */
|
||||
((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
||||
SCALEBITS)))];
|
||||
outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */
|
||||
/* K passes through unchanged */
|
||||
outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */
|
||||
outptr += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Empty method for start_pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_dcolor (j_decompress_ptr)
|
||||
{
|
||||
/* no work needed */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for output colorspace conversion.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_color_deconverter (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_cconvert_ptr2 cconvert;
|
||||
int ci;
|
||||
|
||||
cconvert = (my_cconvert_ptr2)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_color_deconverter2));
|
||||
cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
|
||||
cconvert->pub.start_pass = start_pass_dcolor;
|
||||
|
||||
/* Make sure num_components agrees with jpeg_color_space */
|
||||
switch (cinfo->jpeg_color_space) {
|
||||
case JCS_GRAYSCALE:
|
||||
if (cinfo->num_components != 1)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
break;
|
||||
|
||||
case JCS_RGB:
|
||||
case JCS_YCbCr:
|
||||
if (cinfo->num_components != 3)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
case JCS_YCCK:
|
||||
if (cinfo->num_components != 4)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
break;
|
||||
|
||||
default: /* JCS_UNKNOWN can be anything */
|
||||
if (cinfo->num_components < 1)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set out_color_components and conversion method based on requested space.
|
||||
* Also clear the component_needed flags for any unused components,
|
||||
* so that earlier pipeline stages can avoid useless computation.
|
||||
*/
|
||||
|
||||
switch (cinfo->out_color_space) {
|
||||
case JCS_GRAYSCALE:
|
||||
cinfo->out_color_components = 1;
|
||||
if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
|
||||
cinfo->jpeg_color_space == JCS_YCbCr) {
|
||||
cconvert->pub.color_convert = grayscale_convert2;
|
||||
/* For color->grayscale conversion, only the Y (0) component is needed */
|
||||
for (ci = 1; ci < cinfo->num_components; ci++)
|
||||
cinfo->comp_info[ci].component_needed = FALSE;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_RGB:
|
||||
cinfo->out_color_components = RGB_PIXELSIZE;
|
||||
if (cinfo->jpeg_color_space == JCS_YCbCr) {
|
||||
cconvert->pub.color_convert = ycc_rgb_convert;
|
||||
build_ycc_rgb_table(cinfo);
|
||||
} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
|
||||
cconvert->pub.color_convert = gray_rgb_convert;
|
||||
} else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
|
||||
cconvert->pub.color_convert = null_convert2;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
cinfo->out_color_components = 4;
|
||||
if (cinfo->jpeg_color_space == JCS_YCCK) {
|
||||
cconvert->pub.color_convert = ycck_cmyk_convert;
|
||||
build_ycc_rgb_table(cinfo);
|
||||
} else if (cinfo->jpeg_color_space == JCS_CMYK) {
|
||||
cconvert->pub.color_convert = null_convert2;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Permit null conversion to same output space */
|
||||
if (cinfo->out_color_space == cinfo->jpeg_color_space) {
|
||||
cinfo->out_color_components = cinfo->num_components;
|
||||
cconvert->pub.color_convert = null_convert2;
|
||||
} else /* unsupported non-null conversion */
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
}
|
||||
|
||||
if (cinfo->quantize_colors)
|
||||
cinfo->output_components = 1; /* single colormapped output component */
|
||||
else
|
||||
cinfo->output_components = cinfo->out_color_components;
|
||||
}
|
||||
/*
|
||||
* jdcolor.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 output colorspace conversion routines.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Private subobject */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_color_deconverter pub; /* public fields */
|
||||
|
||||
/* Private state for YCC->RGB conversion */
|
||||
int * Cr_r_tab; /* => table for Cr to R conversion */
|
||||
int * Cb_b_tab; /* => table for Cb to B conversion */
|
||||
INT32 * Cr_g_tab; /* => table for Cr to G conversion */
|
||||
INT32 * Cb_g_tab; /* => table for Cb to G conversion */
|
||||
} my_color_deconverter2;
|
||||
|
||||
typedef my_color_deconverter2 * my_cconvert_ptr2;
|
||||
|
||||
|
||||
/**************** YCbCr -> RGB conversion: most common case **************/
|
||||
|
||||
/*
|
||||
* YCbCr is defined per CCIR 601-1, except that Cb and Cr are
|
||||
* normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
|
||||
* The conversion equations to be implemented are therefore
|
||||
* R = Y + 1.40200 * Cr
|
||||
* G = Y - 0.34414 * Cb - 0.71414 * Cr
|
||||
* B = Y + 1.77200 * Cb
|
||||
* where Cb and Cr represent the incoming values less CENTERJSAMPLE.
|
||||
* (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
|
||||
*
|
||||
* To avoid floating-point arithmetic, we represent the fractional constants
|
||||
* as integers scaled up by 2^16 (about 4 digits precision); we have to divide
|
||||
* the products by 2^16, with appropriate rounding, to get the correct answer.
|
||||
* Notice that Y, being an integral input, does not contribute any fraction
|
||||
* so it need not participate in the rounding.
|
||||
*
|
||||
* For even more speed, we avoid doing any multiplications in the inner loop
|
||||
* by precalculating the constants times Cb and Cr for all possible values.
|
||||
* For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
|
||||
* for 12-bit samples it is still acceptable. It's not very reasonable for
|
||||
* 16-bit samples, but if you want lossless storage you shouldn't be changing
|
||||
* colorspace anyway.
|
||||
* The Cr=>R and Cb=>B values can be rounded to integers in advance; the
|
||||
* values for the G calculation are left scaled up, since we must add them
|
||||
* together before rounding.
|
||||
*/
|
||||
|
||||
#define SCALEBITS 16 /* speediest right-shift on some machines */
|
||||
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
|
||||
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
|
||||
|
||||
|
||||
/*
|
||||
* Initialize tables for YCC->RGB colorspace conversion.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
build_ycc_rgb_table (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_cconvert_ptr2 cconvert = (my_cconvert_ptr2) cinfo->cconvert;
|
||||
int i;
|
||||
INT32 x;
|
||||
SHIFT_TEMPS
|
||||
|
||||
cconvert->Cr_r_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
cconvert->Cb_b_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
cconvert->Cr_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
cconvert->Cb_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
|
||||
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
|
||||
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
|
||||
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
|
||||
/* Cr=>R value is nearest int to 1.40200 * x */
|
||||
cconvert->Cr_r_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
|
||||
/* Cb=>B value is nearest int to 1.77200 * x */
|
||||
cconvert->Cb_b_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
|
||||
/* Cr=>G value is scaled-up -0.71414 * x */
|
||||
cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
|
||||
/* Cb=>G value is scaled-up -0.34414 * x */
|
||||
/* We also add in ONE_HALF so that need not do it in inner loop */
|
||||
cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert some rows of samples to the output colorspace.
|
||||
*
|
||||
* Note that we change from noninterleaved, one-plane-per-component format
|
||||
* to interleaved-pixel format. The output buffer is therefore three times
|
||||
* as wide as the input buffer.
|
||||
* A starting row offset is provided only for the input buffer. The caller
|
||||
* can easily adjust the passed output_buf value to accommodate any row
|
||||
* offset required on that side.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
ycc_rgb_convert (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr2 cconvert = (my_cconvert_ptr2) cinfo->cconvert;
|
||||
int y, cb, cr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPROW inptr0, inptr1, inptr2;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
/* copy these pointers into registers if possible */
|
||||
JSAMPLE * range_limit = cinfo->sample_range_limit;
|
||||
int * Crrtab = cconvert->Cr_r_tab;
|
||||
int * Cbbtab = cconvert->Cb_b_tab;
|
||||
INT32 * Crgtab = cconvert->Cr_g_tab;
|
||||
INT32 * Cbgtab = cconvert->Cb_g_tab;
|
||||
SHIFT_TEMPS
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr0 = input_buf[0][input_row];
|
||||
inptr1 = input_buf[1][input_row];
|
||||
inptr2 = input_buf[2][input_row];
|
||||
input_row++;
|
||||
outptr = *output_buf++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
y = GETJSAMPLE(inptr0[col]);
|
||||
cb = GETJSAMPLE(inptr1[col]);
|
||||
cr = GETJSAMPLE(inptr2[col]);
|
||||
/* Range-limiting is essential due to noise introduced by DCT losses. */
|
||||
outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
|
||||
outptr[RGB_GREEN] = range_limit[y +
|
||||
((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
||||
SCALEBITS))];
|
||||
outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];
|
||||
outptr += RGB_PIXELSIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************** Cases other than YCbCr -> RGB **************/
|
||||
|
||||
|
||||
/*
|
||||
* Color conversion for no colorspace change: just copy the data,
|
||||
* converting from separate-planes to interleaved representation.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
null_convert2 (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
JSAMPROW inptr, outptr;
|
||||
JDIMENSION count;
|
||||
int num_components = cinfo->num_components;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
int ci;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
for (ci = 0; ci < num_components; ci++) {
|
||||
inptr = input_buf[ci][input_row];
|
||||
outptr = output_buf[0] + ci;
|
||||
for (count = num_cols; count > 0; count--) {
|
||||
*outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */
|
||||
outptr += num_components;
|
||||
}
|
||||
}
|
||||
input_row++;
|
||||
output_buf++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Color conversion for grayscale: just copy the data.
|
||||
* This also works for YCbCr -> grayscale conversion, in which
|
||||
* we just copy the Y (luminance) component and ignore chrominance.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
grayscale_convert2 (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
|
||||
num_rows, cinfo->output_width);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert grayscale to RGB: just duplicate the graylevel three times.
|
||||
* This is provided to support applications that don't want to cope
|
||||
* with grayscale as a separate case.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
gray_rgb_convert (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
JSAMPROW inptr, outptr;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = input_buf[0][input_row++];
|
||||
outptr = *output_buf++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
/* We can dispense with GETJSAMPLE() here */
|
||||
outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
|
||||
outptr += RGB_PIXELSIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Adobe-style YCCK->CMYK conversion.
|
||||
* We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
|
||||
* conversion as above, while passing K (black) unchanged.
|
||||
* We assume build_ycc_rgb_table has been called.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
ycck_cmyk_convert (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr2 cconvert = (my_cconvert_ptr2) cinfo->cconvert;
|
||||
int y, cb, cr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPROW inptr0, inptr1, inptr2, inptr3;
|
||||
JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
/* copy these pointers into registers if possible */
|
||||
JSAMPLE * range_limit = cinfo->sample_range_limit;
|
||||
int * Crrtab = cconvert->Cr_r_tab;
|
||||
int * Cbbtab = cconvert->Cb_b_tab;
|
||||
INT32 * Crgtab = cconvert->Cr_g_tab;
|
||||
INT32 * Cbgtab = cconvert->Cb_g_tab;
|
||||
SHIFT_TEMPS
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr0 = input_buf[0][input_row];
|
||||
inptr1 = input_buf[1][input_row];
|
||||
inptr2 = input_buf[2][input_row];
|
||||
inptr3 = input_buf[3][input_row];
|
||||
input_row++;
|
||||
outptr = *output_buf++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
y = GETJSAMPLE(inptr0[col]);
|
||||
cb = GETJSAMPLE(inptr1[col]);
|
||||
cr = GETJSAMPLE(inptr2[col]);
|
||||
/* Range-limiting is essential due to noise introduced by DCT losses. */
|
||||
outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */
|
||||
outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */
|
||||
((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
||||
SCALEBITS)))];
|
||||
outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */
|
||||
/* K passes through unchanged */
|
||||
outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */
|
||||
outptr += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Empty method for start_pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_dcolor (j_decompress_ptr)
|
||||
{
|
||||
/* no work needed */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for output colorspace conversion.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_color_deconverter (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_cconvert_ptr2 cconvert;
|
||||
int ci;
|
||||
|
||||
cconvert = (my_cconvert_ptr2)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_color_deconverter2));
|
||||
cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
|
||||
cconvert->pub.start_pass = start_pass_dcolor;
|
||||
|
||||
/* Make sure num_components agrees with jpeg_color_space */
|
||||
switch (cinfo->jpeg_color_space) {
|
||||
case JCS_GRAYSCALE:
|
||||
if (cinfo->num_components != 1)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
break;
|
||||
|
||||
case JCS_RGB:
|
||||
case JCS_YCbCr:
|
||||
if (cinfo->num_components != 3)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
case JCS_YCCK:
|
||||
if (cinfo->num_components != 4)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
break;
|
||||
|
||||
default: /* JCS_UNKNOWN can be anything */
|
||||
if (cinfo->num_components < 1)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set out_color_components and conversion method based on requested space.
|
||||
* Also clear the component_needed flags for any unused components,
|
||||
* so that earlier pipeline stages can avoid useless computation.
|
||||
*/
|
||||
|
||||
switch (cinfo->out_color_space) {
|
||||
case JCS_GRAYSCALE:
|
||||
cinfo->out_color_components = 1;
|
||||
if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
|
||||
cinfo->jpeg_color_space == JCS_YCbCr) {
|
||||
cconvert->pub.color_convert = grayscale_convert2;
|
||||
/* For color->grayscale conversion, only the Y (0) component is needed */
|
||||
for (ci = 1; ci < cinfo->num_components; ci++)
|
||||
cinfo->comp_info[ci].component_needed = FALSE;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_RGB:
|
||||
cinfo->out_color_components = RGB_PIXELSIZE;
|
||||
if (cinfo->jpeg_color_space == JCS_YCbCr) {
|
||||
cconvert->pub.color_convert = ycc_rgb_convert;
|
||||
build_ycc_rgb_table(cinfo);
|
||||
} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
|
||||
cconvert->pub.color_convert = gray_rgb_convert;
|
||||
} else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
|
||||
cconvert->pub.color_convert = null_convert2;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
cinfo->out_color_components = 4;
|
||||
if (cinfo->jpeg_color_space == JCS_YCCK) {
|
||||
cconvert->pub.color_convert = ycck_cmyk_convert;
|
||||
build_ycc_rgb_table(cinfo);
|
||||
} else if (cinfo->jpeg_color_space == JCS_CMYK) {
|
||||
cconvert->pub.color_convert = null_convert2;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Permit null conversion to same output space */
|
||||
if (cinfo->out_color_space == cinfo->jpeg_color_space) {
|
||||
cinfo->out_color_components = cinfo->num_components;
|
||||
cconvert->pub.color_convert = null_convert2;
|
||||
} else /* unsupported non-null conversion */
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
}
|
||||
|
||||
if (cinfo->quantize_colors)
|
||||
cinfo->output_components = 1; /* single colormapped output component */
|
||||
else
|
||||
cinfo->output_components = cinfo->out_color_components;
|
||||
}
|
||||
|
@ -1,182 +1,182 @@
|
||||
/*
|
||||
* jdct.h
|
||||
*
|
||||
* Copyright (C) 1994-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 include file contains common declarations for the forward and
|
||||
* inverse DCT modules. These declarations are private to the DCT managers
|
||||
* (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms.
|
||||
* The individual DCT algorithms are kept in separate files to ease
|
||||
* machine-dependent tuning (e.g., assembly coding).
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* A forward DCT routine is given a pointer to a work area of type DCTELEM[];
|
||||
* the DCT is to be performed in-place in that buffer. Type DCTELEM is int
|
||||
* for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT
|
||||
* implementations use an array of type FAST_FLOAT, instead.)
|
||||
* The DCT inputs are expected to be signed (range +-CENTERJSAMPLE).
|
||||
* The DCT outputs are returned scaled up by a factor of 8; they therefore
|
||||
* have a range of +-8K for 8-bit data, +-128K for 12-bit data. This
|
||||
* convention improves accuracy in integer implementations and saves some
|
||||
* work in floating-point ones.
|
||||
* Quantization of the output coefficients is done by jcdctmgr.c.
|
||||
*/
|
||||
|
||||
#ifndef __jdct_h__
|
||||
#define __jdct_h__
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
typedef int DCTELEM; /* 16 or 32 bits is fine */
|
||||
#else
|
||||
typedef INT32 DCTELEM; /* must have 32 bits */
|
||||
#endif
|
||||
|
||||
typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
|
||||
typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
|
||||
|
||||
|
||||
/*
|
||||
* An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
|
||||
* to an output sample array. The routine must dequantize the input data as
|
||||
* well as perform the IDCT; for dequantization, it uses the multiplier table
|
||||
* pointed to by compptr->dct_table. The output data is to be placed into the
|
||||
* sample array starting at a specified column. (Any row offset needed will
|
||||
* be applied to the array pointer before it is passed to the IDCT code.)
|
||||
* Note that the number of samples emitted by the IDCT routine is
|
||||
* DCT_scaled_size * DCT_scaled_size.
|
||||
*/
|
||||
|
||||
/* typedef inverse_DCT_method_ptr is declared in jpegint.h */
|
||||
|
||||
/*
|
||||
* Each IDCT routine has its own ideas about the best dct_table element type.
|
||||
*/
|
||||
|
||||
typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */
|
||||
#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */
|
||||
#else
|
||||
typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */
|
||||
#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */
|
||||
#endif
|
||||
typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
|
||||
|
||||
|
||||
/*
|
||||
* Each IDCT routine is responsible for range-limiting its results and
|
||||
* converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could
|
||||
* be quite far out of range if the input data is corrupt, so a bulletproof
|
||||
* range-limiting step is required. We use a mask-and-table-lookup method
|
||||
* to do the combined operations quickly. See the comments with
|
||||
* prepare_range_limit_table (in jdmaster.c) for more info.
|
||||
*/
|
||||
|
||||
#define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit + CENTERJSAMPLE)
|
||||
|
||||
#define RANGE_MASK (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */
|
||||
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jpeg_fdct_islow jFDislow
|
||||
#define jpeg_fdct_ifast jFDifast
|
||||
#define jpeg_fdct_float jFDfloat
|
||||
#define jpeg_idct_islow jRDislow
|
||||
#define jpeg_idct_ifast jRDifast
|
||||
#define jpeg_idct_float jRDfloat
|
||||
#define jpeg_idct_4x4 jRD4x4
|
||||
#define jpeg_idct_2x2 jRD2x2
|
||||
#define jpeg_idct_1x1 jRD1x1
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
/* Extern declarations for the forward and inverse DCT routines. */
|
||||
|
||||
EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data));
|
||||
EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data));
|
||||
EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data));
|
||||
|
||||
EXTERN(void) jpeg_idct_islow
|
||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
EXTERN(void) jpeg_idct_ifast
|
||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
EXTERN(void) jpeg_idct_float
|
||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
EXTERN(void) jpeg_idct_4x4
|
||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
EXTERN(void) jpeg_idct_2x2
|
||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
EXTERN(void) jpeg_idct_1x1
|
||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
|
||||
|
||||
/*
|
||||
* Macros for handling fixed-point arithmetic; these are used by many
|
||||
* but not all of the DCT/IDCT modules.
|
||||
*
|
||||
* All values are expected to be of type INT32.
|
||||
* Fractional constants are scaled left by CONST_BITS bits.
|
||||
* CONST_BITS is defined within each module using these macros,
|
||||
* and may differ from one module to the next.
|
||||
*/
|
||||
|
||||
#define ONE ((INT32) 1)
|
||||
#define CONST_SCALE (ONE << CONST_BITS)
|
||||
|
||||
/* Convert a positive real constant to an integer scaled by CONST_SCALE.
|
||||
* Caution: some C compilers fail to reduce "FIX(constant)" at compile time,
|
||||
* thus causing a lot of useless floating-point operations at run time.
|
||||
*/
|
||||
|
||||
#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
|
||||
|
||||
/* Descale and correctly round an INT32 value that's scaled by N bits.
|
||||
* We assume RIGHT_SHIFT rounds towards minus infinity, so adding
|
||||
* the fudge factor is correct for either sign of X.
|
||||
*/
|
||||
|
||||
#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
|
||||
|
||||
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
|
||||
* This macro is used only when the two inputs will actually be no more than
|
||||
* 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a
|
||||
* full 32x32 multiply. This provides a useful speedup on many machines.
|
||||
* Unfortunately there is no way to specify a 16x16->32 multiply portably
|
||||
* in C, but some C compilers will do the right thing if you provide the
|
||||
* correct combination of casts.
|
||||
*/
|
||||
|
||||
#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
|
||||
#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const)))
|
||||
#endif
|
||||
#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */
|
||||
#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const)))
|
||||
#endif
|
||||
|
||||
#ifndef MULTIPLY16C16 /* default definition */
|
||||
#define MULTIPLY16C16(var,const) ((var) * (const))
|
||||
#endif
|
||||
|
||||
/* Same except both inputs are variables. */
|
||||
|
||||
#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
|
||||
#define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2)))
|
||||
#endif
|
||||
|
||||
#ifndef MULTIPLY16V16 /* default definition */
|
||||
#define MULTIPLY16V16(var1,var2) ((var1) * (var2))
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
* jdct.h
|
||||
*
|
||||
* Copyright (C) 1994-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 include file contains common declarations for the forward and
|
||||
* inverse DCT modules. These declarations are private to the DCT managers
|
||||
* (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms.
|
||||
* The individual DCT algorithms are kept in separate files to ease
|
||||
* machine-dependent tuning (e.g., assembly coding).
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* A forward DCT routine is given a pointer to a work area of type DCTELEM[];
|
||||
* the DCT is to be performed in-place in that buffer. Type DCTELEM is int
|
||||
* for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT
|
||||
* implementations use an array of type FAST_FLOAT, instead.)
|
||||
* The DCT inputs are expected to be signed (range +-CENTERJSAMPLE).
|
||||
* The DCT outputs are returned scaled up by a factor of 8; they therefore
|
||||
* have a range of +-8K for 8-bit data, +-128K for 12-bit data. This
|
||||
* convention improves accuracy in integer implementations and saves some
|
||||
* work in floating-point ones.
|
||||
* Quantization of the output coefficients is done by jcdctmgr.c.
|
||||
*/
|
||||
|
||||
#ifndef __jdct_h__
|
||||
#define __jdct_h__
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
typedef int DCTELEM; /* 16 or 32 bits is fine */
|
||||
#else
|
||||
typedef INT32 DCTELEM; /* must have 32 bits */
|
||||
#endif
|
||||
|
||||
typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
|
||||
typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
|
||||
|
||||
|
||||
/*
|
||||
* An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
|
||||
* to an output sample array. The routine must dequantize the input data as
|
||||
* well as perform the IDCT; for dequantization, it uses the multiplier table
|
||||
* pointed to by compptr->dct_table. The output data is to be placed into the
|
||||
* sample array starting at a specified column. (Any row offset needed will
|
||||
* be applied to the array pointer before it is passed to the IDCT code.)
|
||||
* Note that the number of samples emitted by the IDCT routine is
|
||||
* DCT_scaled_size * DCT_scaled_size.
|
||||
*/
|
||||
|
||||
/* typedef inverse_DCT_method_ptr is declared in jpegint.h */
|
||||
|
||||
/*
|
||||
* Each IDCT routine has its own ideas about the best dct_table element type.
|
||||
*/
|
||||
|
||||
typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */
|
||||
#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */
|
||||
#else
|
||||
typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */
|
||||
#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */
|
||||
#endif
|
||||
typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
|
||||
|
||||
|
||||
/*
|
||||
* Each IDCT routine is responsible for range-limiting its results and
|
||||
* converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could
|
||||
* be quite far out of range if the input data is corrupt, so a bulletproof
|
||||
* range-limiting step is required. We use a mask-and-table-lookup method
|
||||
* to do the combined operations quickly. See the comments with
|
||||
* prepare_range_limit_table (in jdmaster.c) for more info.
|
||||
*/
|
||||
|
||||
#define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit + CENTERJSAMPLE)
|
||||
|
||||
#define RANGE_MASK (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */
|
||||
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jpeg_fdct_islow jFDislow
|
||||
#define jpeg_fdct_ifast jFDifast
|
||||
#define jpeg_fdct_float jFDfloat
|
||||
#define jpeg_idct_islow jRDislow
|
||||
#define jpeg_idct_ifast jRDifast
|
||||
#define jpeg_idct_float jRDfloat
|
||||
#define jpeg_idct_4x4 jRD4x4
|
||||
#define jpeg_idct_2x2 jRD2x2
|
||||
#define jpeg_idct_1x1 jRD1x1
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
/* Extern declarations for the forward and inverse DCT routines. */
|
||||
|
||||
EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data));
|
||||
EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data));
|
||||
EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data));
|
||||
|
||||
EXTERN(void) jpeg_idct_islow
|
||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
EXTERN(void) jpeg_idct_ifast
|
||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
EXTERN(void) jpeg_idct_float
|
||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
EXTERN(void) jpeg_idct_4x4
|
||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
EXTERN(void) jpeg_idct_2x2
|
||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
EXTERN(void) jpeg_idct_1x1
|
||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
|
||||
|
||||
/*
|
||||
* Macros for handling fixed-point arithmetic; these are used by many
|
||||
* but not all of the DCT/IDCT modules.
|
||||
*
|
||||
* All values are expected to be of type INT32.
|
||||
* Fractional constants are scaled left by CONST_BITS bits.
|
||||
* CONST_BITS is defined within each module using these macros,
|
||||
* and may differ from one module to the next.
|
||||
*/
|
||||
|
||||
#define ONE ((INT32) 1)
|
||||
#define CONST_SCALE (ONE << CONST_BITS)
|
||||
|
||||
/* Convert a positive real constant to an integer scaled by CONST_SCALE.
|
||||
* Caution: some C compilers fail to reduce "FIX(constant)" at compile time,
|
||||
* thus causing a lot of useless floating-point operations at run time.
|
||||
*/
|
||||
|
||||
#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
|
||||
|
||||
/* Descale and correctly round an INT32 value that's scaled by N bits.
|
||||
* We assume RIGHT_SHIFT rounds towards minus infinity, so adding
|
||||
* the fudge factor is correct for either sign of X.
|
||||
*/
|
||||
|
||||
#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
|
||||
|
||||
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
|
||||
* This macro is used only when the two inputs will actually be no more than
|
||||
* 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a
|
||||
* full 32x32 multiply. This provides a useful speedup on many machines.
|
||||
* Unfortunately there is no way to specify a 16x16->32 multiply portably
|
||||
* in C, but some C compilers will do the right thing if you provide the
|
||||
* correct combination of casts.
|
||||
*/
|
||||
|
||||
#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
|
||||
#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const)))
|
||||
#endif
|
||||
#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */
|
||||
#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const)))
|
||||
#endif
|
||||
|
||||
#ifndef MULTIPLY16C16 /* default definition */
|
||||
#define MULTIPLY16C16(var,const) ((var) * (const))
|
||||
#endif
|
||||
|
||||
/* Same except both inputs are variables. */
|
||||
|
||||
#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
|
||||
#define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2)))
|
||||
#endif
|
||||
|
||||
#ifndef MULTIPLY16V16 /* default definition */
|
||||
#define MULTIPLY16V16(var1,var2) ((var1) * (var2))
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,269 +1,269 @@
|
||||
/*
|
||||
* jddctmgr.c
|
||||
*
|
||||
* Copyright (C) 1994-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 the inverse-DCT management logic.
|
||||
* This code selects a particular IDCT implementation to be used,
|
||||
* and it performs related housekeeping chores. No code in this file
|
||||
* is executed per IDCT step, only during output pass setup.
|
||||
*
|
||||
* Note that the IDCT routines are responsible for performing coefficient
|
||||
* dequantization as well as the IDCT proper. This module sets up the
|
||||
* dequantization multiplier table needed by the IDCT routine.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
|
||||
/*
|
||||
* The decompressor input side (jdinput.c) saves away the appropriate
|
||||
* quantization table for each component at the start of the first scan
|
||||
* involving that component. (This is necessary in order to correctly
|
||||
* decode files that reuse Q-table slots.)
|
||||
* When we are ready to make an output pass, the saved Q-table is converted
|
||||
* to a multiplier table that will actually be used by the IDCT routine.
|
||||
* The multiplier table contents are IDCT-method-dependent. To support
|
||||
* application changes in IDCT method between scans, we can remake the
|
||||
* multiplier tables if necessary.
|
||||
* In buffered-image mode, the first output pass may occur before any data
|
||||
* has been seen for some components, and thus before their Q-tables have
|
||||
* been saved away. To handle this case, multiplier tables are preset
|
||||
* to zeroes; the result of the IDCT will be a neutral gray level.
|
||||
*/
|
||||
|
||||
|
||||
/* Private subobject for this module */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_inverse_dct pub; /* public fields */
|
||||
|
||||
/* This array contains the IDCT method code that each multiplier table
|
||||
* is currently set up for, or -1 if it's not yet set up.
|
||||
* The actual multiplier tables are pointed to by dct_table in the
|
||||
* per-component comp_info structures.
|
||||
*/
|
||||
int cur_method[MAX_COMPONENTS];
|
||||
} my_idct_controller;
|
||||
|
||||
typedef my_idct_controller * my_idct_ptr;
|
||||
|
||||
|
||||
/* Allocated multiplier tables: big enough for any supported variant */
|
||||
|
||||
typedef union {
|
||||
ISLOW_MULT_TYPE islow_array[DCTSIZE2];
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
IFAST_MULT_TYPE ifast_array[DCTSIZE2];
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
FLOAT_MULT_TYPE float_array[DCTSIZE2];
|
||||
#endif
|
||||
} multiplier_table;
|
||||
|
||||
|
||||
/* The current scaled-IDCT routines require ISLOW-style multiplier tables,
|
||||
* so be sure to compile that code if either ISLOW or SCALING is requested.
|
||||
*/
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
#define PROVIDE_ISLOW_TABLES
|
||||
#else
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
#define PROVIDE_ISLOW_TABLES
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for an output pass.
|
||||
* Here we select the proper IDCT routine for each component and build
|
||||
* a matching multiplier table.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
|
||||
int ci, i;
|
||||
jpeg_component_info *compptr;
|
||||
int method = 0;
|
||||
inverse_DCT_method_ptr method_ptr = NULL;
|
||||
JQUANT_TBL * qtbl;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Select the proper IDCT routine for this component's scaling */
|
||||
switch (compptr->DCT_scaled_size) {
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
case 1:
|
||||
method_ptr = jpeg_idct_1x1;
|
||||
method = JDCT_ISLOW; /* jidctred uses islow-style table */
|
||||
break;
|
||||
case 2:
|
||||
method_ptr = jpeg_idct_2x2;
|
||||
method = JDCT_ISLOW; /* jidctred uses islow-style table */
|
||||
break;
|
||||
case 4:
|
||||
method_ptr = jpeg_idct_4x4;
|
||||
method = JDCT_ISLOW; /* jidctred uses islow-style table */
|
||||
break;
|
||||
#endif
|
||||
case DCTSIZE:
|
||||
switch (cinfo->dct_method) {
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
case JDCT_ISLOW:
|
||||
method_ptr = jpeg_idct_islow;
|
||||
method = JDCT_ISLOW;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
method_ptr = jpeg_idct_ifast;
|
||||
method = JDCT_IFAST;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
method_ptr = jpeg_idct_float;
|
||||
method = JDCT_FLOAT;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
|
||||
break;
|
||||
}
|
||||
idct->pub.inverse_DCT[ci] = method_ptr;
|
||||
/* Create multiplier table from quant table.
|
||||
* However, we can skip this if the component is uninteresting
|
||||
* or if we already built the table. Also, if no quant table
|
||||
* has yet been saved for the component, we leave the
|
||||
* multiplier table all-zero; we'll be reading zeroes from the
|
||||
* coefficient controller's buffer anyway.
|
||||
*/
|
||||
if (! compptr->component_needed || idct->cur_method[ci] == method)
|
||||
continue;
|
||||
qtbl = compptr->quant_table;
|
||||
if (qtbl == NULL) /* happens if no data yet for component */
|
||||
continue;
|
||||
idct->cur_method[ci] = method;
|
||||
switch (method) {
|
||||
#ifdef PROVIDE_ISLOW_TABLES
|
||||
case JDCT_ISLOW:
|
||||
{
|
||||
/* For LL&M IDCT method, multipliers are equal to raw quantization
|
||||
* coefficients, but are stored as ints to ensure access efficiency.
|
||||
*/
|
||||
ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
{
|
||||
/* For AA&N IDCT method, multipliers are equal to quantization
|
||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
||||
* scalefactor[0] = 1
|
||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
||||
* For integer operation, the multiplier table is to be scaled by
|
||||
* IFAST_SCALE_BITS.
|
||||
*/
|
||||
IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
|
||||
#define CONST_BITS 14
|
||||
static const INT16 aanscales[DCTSIZE2] = {
|
||||
/* precomputed values scaled up by 14 bits */
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
|
||||
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
|
||||
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
|
||||
8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
|
||||
4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
|
||||
};
|
||||
SHIFT_TEMPS
|
||||
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
ifmtbl[i] = (IFAST_MULT_TYPE)
|
||||
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
|
||||
(INT32) aanscales[i]),
|
||||
CONST_BITS-IFAST_SCALE_BITS);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
{
|
||||
/* For float AA&N IDCT method, multipliers are equal to quantization
|
||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
||||
* scalefactor[0] = 1
|
||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
||||
*/
|
||||
FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
|
||||
int row, col;
|
||||
static const double aanscalefactor[DCTSIZE] = {
|
||||
1.0, 1.387039845, 1.306562965, 1.175875602,
|
||||
1.0, 0.785694958, 0.541196100, 0.275899379
|
||||
};
|
||||
|
||||
i = 0;
|
||||
for (row = 0; row < DCTSIZE; row++) {
|
||||
for (col = 0; col < DCTSIZE; col++) {
|
||||
fmtbl[i] = (FLOAT_MULT_TYPE)
|
||||
((double) qtbl->quantval[i] *
|
||||
aanscalefactor[row] * aanscalefactor[col]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize IDCT manager.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_inverse_dct (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_idct_ptr idct;
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
idct = (my_idct_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_idct_controller));
|
||||
cinfo->idct = (struct jpeg_inverse_dct *) idct;
|
||||
idct->pub.start_pass = start_pass;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Allocate and pre-zero a multiplier table for each component */
|
||||
compptr->dct_table =
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(multiplier_table));
|
||||
MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
|
||||
/* Mark multiplier table not yet set up for any method */
|
||||
idct->cur_method[ci] = -1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* jddctmgr.c
|
||||
*
|
||||
* Copyright (C) 1994-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 the inverse-DCT management logic.
|
||||
* This code selects a particular IDCT implementation to be used,
|
||||
* and it performs related housekeeping chores. No code in this file
|
||||
* is executed per IDCT step, only during output pass setup.
|
||||
*
|
||||
* Note that the IDCT routines are responsible for performing coefficient
|
||||
* dequantization as well as the IDCT proper. This module sets up the
|
||||
* dequantization multiplier table needed by the IDCT routine.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
|
||||
/*
|
||||
* The decompressor input side (jdinput.c) saves away the appropriate
|
||||
* quantization table for each component at the start of the first scan
|
||||
* involving that component. (This is necessary in order to correctly
|
||||
* decode files that reuse Q-table slots.)
|
||||
* When we are ready to make an output pass, the saved Q-table is converted
|
||||
* to a multiplier table that will actually be used by the IDCT routine.
|
||||
* The multiplier table contents are IDCT-method-dependent. To support
|
||||
* application changes in IDCT method between scans, we can remake the
|
||||
* multiplier tables if necessary.
|
||||
* In buffered-image mode, the first output pass may occur before any data
|
||||
* has been seen for some components, and thus before their Q-tables have
|
||||
* been saved away. To handle this case, multiplier tables are preset
|
||||
* to zeroes; the result of the IDCT will be a neutral gray level.
|
||||
*/
|
||||
|
||||
|
||||
/* Private subobject for this module */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_inverse_dct pub; /* public fields */
|
||||
|
||||
/* This array contains the IDCT method code that each multiplier table
|
||||
* is currently set up for, or -1 if it's not yet set up.
|
||||
* The actual multiplier tables are pointed to by dct_table in the
|
||||
* per-component comp_info structures.
|
||||
*/
|
||||
int cur_method[MAX_COMPONENTS];
|
||||
} my_idct_controller;
|
||||
|
||||
typedef my_idct_controller * my_idct_ptr;
|
||||
|
||||
|
||||
/* Allocated multiplier tables: big enough for any supported variant */
|
||||
|
||||
typedef union {
|
||||
ISLOW_MULT_TYPE islow_array[DCTSIZE2];
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
IFAST_MULT_TYPE ifast_array[DCTSIZE2];
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
FLOAT_MULT_TYPE float_array[DCTSIZE2];
|
||||
#endif
|
||||
} multiplier_table;
|
||||
|
||||
|
||||
/* The current scaled-IDCT routines require ISLOW-style multiplier tables,
|
||||
* so be sure to compile that code if either ISLOW or SCALING is requested.
|
||||
*/
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
#define PROVIDE_ISLOW_TABLES
|
||||
#else
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
#define PROVIDE_ISLOW_TABLES
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for an output pass.
|
||||
* Here we select the proper IDCT routine for each component and build
|
||||
* a matching multiplier table.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
|
||||
int ci, i;
|
||||
jpeg_component_info *compptr;
|
||||
int method = 0;
|
||||
inverse_DCT_method_ptr method_ptr = NULL;
|
||||
JQUANT_TBL * qtbl;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Select the proper IDCT routine for this component's scaling */
|
||||
switch (compptr->DCT_scaled_size) {
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
case 1:
|
||||
method_ptr = jpeg_idct_1x1;
|
||||
method = JDCT_ISLOW; /* jidctred uses islow-style table */
|
||||
break;
|
||||
case 2:
|
||||
method_ptr = jpeg_idct_2x2;
|
||||
method = JDCT_ISLOW; /* jidctred uses islow-style table */
|
||||
break;
|
||||
case 4:
|
||||
method_ptr = jpeg_idct_4x4;
|
||||
method = JDCT_ISLOW; /* jidctred uses islow-style table */
|
||||
break;
|
||||
#endif
|
||||
case DCTSIZE:
|
||||
switch (cinfo->dct_method) {
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
case JDCT_ISLOW:
|
||||
method_ptr = jpeg_idct_islow;
|
||||
method = JDCT_ISLOW;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
method_ptr = jpeg_idct_ifast;
|
||||
method = JDCT_IFAST;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
method_ptr = jpeg_idct_float;
|
||||
method = JDCT_FLOAT;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
|
||||
break;
|
||||
}
|
||||
idct->pub.inverse_DCT[ci] = method_ptr;
|
||||
/* Create multiplier table from quant table.
|
||||
* However, we can skip this if the component is uninteresting
|
||||
* or if we already built the table. Also, if no quant table
|
||||
* has yet been saved for the component, we leave the
|
||||
* multiplier table all-zero; we'll be reading zeroes from the
|
||||
* coefficient controller's buffer anyway.
|
||||
*/
|
||||
if (! compptr->component_needed || idct->cur_method[ci] == method)
|
||||
continue;
|
||||
qtbl = compptr->quant_table;
|
||||
if (qtbl == NULL) /* happens if no data yet for component */
|
||||
continue;
|
||||
idct->cur_method[ci] = method;
|
||||
switch (method) {
|
||||
#ifdef PROVIDE_ISLOW_TABLES
|
||||
case JDCT_ISLOW:
|
||||
{
|
||||
/* For LL&M IDCT method, multipliers are equal to raw quantization
|
||||
* coefficients, but are stored as ints to ensure access efficiency.
|
||||
*/
|
||||
ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
{
|
||||
/* For AA&N IDCT method, multipliers are equal to quantization
|
||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
||||
* scalefactor[0] = 1
|
||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
||||
* For integer operation, the multiplier table is to be scaled by
|
||||
* IFAST_SCALE_BITS.
|
||||
*/
|
||||
IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
|
||||
#define CONST_BITS 14
|
||||
static const INT16 aanscales[DCTSIZE2] = {
|
||||
/* precomputed values scaled up by 14 bits */
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
|
||||
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
|
||||
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
|
||||
8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
|
||||
4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
|
||||
};
|
||||
SHIFT_TEMPS
|
||||
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
ifmtbl[i] = (IFAST_MULT_TYPE)
|
||||
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
|
||||
(INT32) aanscales[i]),
|
||||
CONST_BITS-IFAST_SCALE_BITS);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
{
|
||||
/* For float AA&N IDCT method, multipliers are equal to quantization
|
||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
||||
* scalefactor[0] = 1
|
||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
||||
*/
|
||||
FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
|
||||
int row, col;
|
||||
static const double aanscalefactor[DCTSIZE] = {
|
||||
1.0, 1.387039845, 1.306562965, 1.175875602,
|
||||
1.0, 0.785694958, 0.541196100, 0.275899379
|
||||
};
|
||||
|
||||
i = 0;
|
||||
for (row = 0; row < DCTSIZE; row++) {
|
||||
for (col = 0; col < DCTSIZE; col++) {
|
||||
fmtbl[i] = (FLOAT_MULT_TYPE)
|
||||
((double) qtbl->quantval[i] *
|
||||
aanscalefactor[row] * aanscalefactor[col]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize IDCT manager.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_inverse_dct (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_idct_ptr idct;
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
idct = (my_idct_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_idct_controller));
|
||||
cinfo->idct = (struct jpeg_inverse_dct *) idct;
|
||||
idct->pub.start_pass = start_pass;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Allocate and pre-zero a multiplier table for each component */
|
||||
compptr->dct_table =
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(multiplier_table));
|
||||
MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
|
||||
/* Mark multiplier table not yet set up for any method */
|
||||
idct->cur_method[ci] = -1;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,206 +1,206 @@
|
||||
/*
|
||||
* jdhuff.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 declarations for Huffman entropy decoding routines
|
||||
* that are shared between the sequential decoder (jdhuff.c) and the
|
||||
* progressive decoder (jdphuff.c). No other modules need to see these.
|
||||
*/
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifndef __jdhuff_h__
|
||||
#define __jdhuff_h__
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jpeg_make_d_derived_tbl jMkDDerived
|
||||
#define jpeg_fill_bit_buffer jFilBitBuf
|
||||
#define jpeg_huff_decode jHufDecode
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
|
||||
/* Derived data constructed for each Huffman table */
|
||||
|
||||
#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
|
||||
|
||||
typedef struct {
|
||||
/* Basic tables: (element [0] of each array is unused) */
|
||||
INT32 maxcode[18]; /* largest code of length k (-1 if none) */
|
||||
/* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */
|
||||
INT32 valoffset[17]; /* huffval[] offset for codes of length k */
|
||||
/* valoffset[k] = huffval[] index of 1st symbol of code length k, less
|
||||
* the smallest code of length k; so given a code of length k, the
|
||||
* corresponding symbol is huffval[code + valoffset[k]]
|
||||
*/
|
||||
|
||||
/* Link to public Huffman table (needed only in jpeg_huff_decode) */
|
||||
JHUFF_TBL *pub;
|
||||
|
||||
/* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
|
||||
* the input data stream. If the next Huffman code is no more
|
||||
* than HUFF_LOOKAHEAD bits long, we can obtain its length and
|
||||
* the corresponding symbol directly from these tables.
|
||||
*/
|
||||
int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
|
||||
UINT8 look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
|
||||
} d_derived_tbl;
|
||||
|
||||
/* Expand a Huffman table definition into the derived format */
|
||||
EXTERN(void) jpeg_make_d_derived_tbl
|
||||
JPP((j_decompress_ptr cinfo, boolean isDC, int tblno,
|
||||
d_derived_tbl ** pdtbl));
|
||||
|
||||
|
||||
/*
|
||||
* Fetching the next N bits from the input stream is a time-critical operation
|
||||
* for the Huffman decoders. We implement it with a combination of inline
|
||||
* macros and out-of-line subroutines. Note that N (the number of bits
|
||||
* demanded at one time) never exceeds 15 for JPEG use.
|
||||
*
|
||||
* We read source bytes into get_buffer and dole out bits as needed.
|
||||
* If get_buffer already contains enough bits, they are fetched in-line
|
||||
* by the macros CHECK_BIT_BUFFER and GET_BITS. When there aren't enough
|
||||
* bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer
|
||||
* as full as possible (not just to the number of bits needed; this
|
||||
* prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer).
|
||||
* Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension.
|
||||
* On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer contains
|
||||
* at least the requested number of bits --- dummy zeroes are inserted if
|
||||
* necessary.
|
||||
*/
|
||||
|
||||
typedef INT32 bit_buf_type; /* type of bit-extraction buffer */
|
||||
#define BIT_BUF_SIZE 32 /* size of buffer in bits */
|
||||
|
||||
/* If long is > 32 bits on your machine, and shifting/masking longs is
|
||||
* reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE
|
||||
* appropriately should be a win. Unfortunately we can't define the size
|
||||
* with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
|
||||
* because not all machines measure sizeof in 8-bit bytes.
|
||||
*/
|
||||
|
||||
typedef struct { /* Bitreading state saved across MCUs */
|
||||
bit_buf_type get_buffer; /* current bit-extraction buffer */
|
||||
int bits_left; /* # of unused bits in it */
|
||||
} bitread_perm_state;
|
||||
|
||||
typedef struct { /* Bitreading working state within an MCU */
|
||||
/* Current data source location */
|
||||
/* We need a copy, rather than munging the original, in case of suspension */
|
||||
const JOCTET * next_input_byte; /* => next byte to read from source */
|
||||
size_t bytes_in_buffer; /* # of bytes remaining in source buffer */
|
||||
/* Bit input buffer --- note these values are kept in register variables,
|
||||
* not in this struct, inside the inner loops.
|
||||
*/
|
||||
bit_buf_type get_buffer; /* current bit-extraction buffer */
|
||||
int bits_left; /* # of unused bits in it */
|
||||
/* Pointer needed by jpeg_fill_bit_buffer. */
|
||||
j_decompress_ptr cinfo; /* back link to decompress master record */
|
||||
} bitread_working_state;
|
||||
|
||||
/* Macros to declare and load/save bitread local variables. */
|
||||
#define BITREAD_STATE_VARS \
|
||||
bit_buf_type get_buffer; \
|
||||
int bits_left; \
|
||||
bitread_working_state br_state
|
||||
|
||||
#define BITREAD_LOAD_STATE(cinfop,permstate) \
|
||||
br_state.cinfo = cinfop; \
|
||||
br_state.next_input_byte = cinfop->src->next_input_byte; \
|
||||
br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \
|
||||
get_buffer = permstate.get_buffer; \
|
||||
bits_left = permstate.bits_left;
|
||||
|
||||
#define BITREAD_SAVE_STATE(cinfop,permstate) \
|
||||
cinfop->src->next_input_byte = br_state.next_input_byte; \
|
||||
cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \
|
||||
permstate.get_buffer = get_buffer; \
|
||||
permstate.bits_left = bits_left
|
||||
|
||||
/*
|
||||
* These macros provide the in-line portion of bit fetching.
|
||||
* Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer
|
||||
* before using GET_BITS, PEEK_BITS, or DROP_BITS.
|
||||
* The variables get_buffer and bits_left are assumed to be locals,
|
||||
* but the state struct might not be (jpeg_huff_decode needs this).
|
||||
* CHECK_BIT_BUFFER(state,n,action);
|
||||
* Ensure there are N bits in get_buffer; if suspend, take action.
|
||||
* val = GET_BITS(n);
|
||||
* Fetch next N bits.
|
||||
* val = PEEK_BITS(n);
|
||||
* Fetch next N bits without removing them from the buffer.
|
||||
* DROP_BITS(n);
|
||||
* Discard next N bits.
|
||||
* The value N should be a simple variable, not an expression, because it
|
||||
* is evaluated multiple times.
|
||||
*/
|
||||
|
||||
#define CHECK_BIT_BUFFER(state,nbits,action) \
|
||||
{ if (bits_left < (nbits)) { \
|
||||
if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \
|
||||
{ action; } \
|
||||
get_buffer = (state).get_buffer; bits_left = (state).bits_left; } }
|
||||
|
||||
#define GET_BITS(nbits) \
|
||||
(((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1))
|
||||
|
||||
#define PEEK_BITS(nbits) \
|
||||
(((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1))
|
||||
|
||||
#define DROP_BITS(nbits) \
|
||||
(bits_left -= (nbits))
|
||||
|
||||
/* Load up the bit buffer to a depth of at least nbits */
|
||||
EXTERN(boolean) jpeg_fill_bit_buffer
|
||||
JPP((bitread_working_state * state, bit_buf_type get_buffer,
|
||||
int bits_left, int nbits));
|
||||
|
||||
|
||||
/*
|
||||
* Code for extracting next Huffman-coded symbol from input bit stream.
|
||||
* Again, this is time-critical and we make the main paths be macros.
|
||||
*
|
||||
* We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits
|
||||
* without looping. Usually, more than 95% of the Huffman codes will be 8
|
||||
* or fewer bits long. The few overlength codes are handled with a loop,
|
||||
* which need not be inline code.
|
||||
*
|
||||
* Notes about the HUFF_DECODE macro:
|
||||
* 1. Near the end of the data segment, we may fail to get enough bits
|
||||
* for a lookahead. In that case, we do it the hard way.
|
||||
* 2. If the lookahead table contains no entry, the next code must be
|
||||
* more than HUFF_LOOKAHEAD bits long.
|
||||
* 3. jpeg_huff_decode returns -1 if forced to suspend.
|
||||
*/
|
||||
|
||||
#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \
|
||||
{ int nb, look; \
|
||||
if (bits_left < HUFF_LOOKAHEAD) { \
|
||||
if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \
|
||||
get_buffer = state.get_buffer; bits_left = state.bits_left; \
|
||||
if (bits_left < HUFF_LOOKAHEAD) { \
|
||||
nb = 1; goto slowlabel; \
|
||||
} \
|
||||
} \
|
||||
look = PEEK_BITS(HUFF_LOOKAHEAD); \
|
||||
if ((nb = htbl->look_nbits[look]) != 0) { \
|
||||
DROP_BITS(nb); \
|
||||
result = htbl->look_sym[look]; \
|
||||
} else { \
|
||||
nb = HUFF_LOOKAHEAD+1; \
|
||||
slowlabel: \
|
||||
if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \
|
||||
{ failaction; } \
|
||||
get_buffer = state.get_buffer; bits_left = state.bits_left; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Out-of-line case for Huffman code fetching */
|
||||
EXTERN(int) jpeg_huff_decode
|
||||
JPP((bitread_working_state * state, bit_buf_type get_buffer,
|
||||
int bits_left, d_derived_tbl * htbl, int min_bits));
|
||||
|
||||
#endif
|
||||
/*
|
||||
* jdhuff.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 declarations for Huffman entropy decoding routines
|
||||
* that are shared between the sequential decoder (jdhuff.c) and the
|
||||
* progressive decoder (jdphuff.c). No other modules need to see these.
|
||||
*/
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifndef __jdhuff_h__
|
||||
#define __jdhuff_h__
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jpeg_make_d_derived_tbl jMkDDerived
|
||||
#define jpeg_fill_bit_buffer jFilBitBuf
|
||||
#define jpeg_huff_decode jHufDecode
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
|
||||
/* Derived data constructed for each Huffman table */
|
||||
|
||||
#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
|
||||
|
||||
typedef struct {
|
||||
/* Basic tables: (element [0] of each array is unused) */
|
||||
INT32 maxcode[18]; /* largest code of length k (-1 if none) */
|
||||
/* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */
|
||||
INT32 valoffset[17]; /* huffval[] offset for codes of length k */
|
||||
/* valoffset[k] = huffval[] index of 1st symbol of code length k, less
|
||||
* the smallest code of length k; so given a code of length k, the
|
||||
* corresponding symbol is huffval[code + valoffset[k]]
|
||||
*/
|
||||
|
||||
/* Link to public Huffman table (needed only in jpeg_huff_decode) */
|
||||
JHUFF_TBL *pub;
|
||||
|
||||
/* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
|
||||
* the input data stream. If the next Huffman code is no more
|
||||
* than HUFF_LOOKAHEAD bits long, we can obtain its length and
|
||||
* the corresponding symbol directly from these tables.
|
||||
*/
|
||||
int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
|
||||
UINT8 look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
|
||||
} d_derived_tbl;
|
||||
|
||||
/* Expand a Huffman table definition into the derived format */
|
||||
EXTERN(void) jpeg_make_d_derived_tbl
|
||||
JPP((j_decompress_ptr cinfo, boolean isDC, int tblno,
|
||||
d_derived_tbl ** pdtbl));
|
||||
|
||||
|
||||
/*
|
||||
* Fetching the next N bits from the input stream is a time-critical operation
|
||||
* for the Huffman decoders. We implement it with a combination of inline
|
||||
* macros and out-of-line subroutines. Note that N (the number of bits
|
||||
* demanded at one time) never exceeds 15 for JPEG use.
|
||||
*
|
||||
* We read source bytes into get_buffer and dole out bits as needed.
|
||||
* If get_buffer already contains enough bits, they are fetched in-line
|
||||
* by the macros CHECK_BIT_BUFFER and GET_BITS. When there aren't enough
|
||||
* bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer
|
||||
* as full as possible (not just to the number of bits needed; this
|
||||
* prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer).
|
||||
* Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension.
|
||||
* On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer contains
|
||||
* at least the requested number of bits --- dummy zeroes are inserted if
|
||||
* necessary.
|
||||
*/
|
||||
|
||||
typedef INT32 bit_buf_type; /* type of bit-extraction buffer */
|
||||
#define BIT_BUF_SIZE 32 /* size of buffer in bits */
|
||||
|
||||
/* If long is > 32 bits on your machine, and shifting/masking longs is
|
||||
* reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE
|
||||
* appropriately should be a win. Unfortunately we can't define the size
|
||||
* with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
|
||||
* because not all machines measure sizeof in 8-bit bytes.
|
||||
*/
|
||||
|
||||
typedef struct { /* Bitreading state saved across MCUs */
|
||||
bit_buf_type get_buffer; /* current bit-extraction buffer */
|
||||
int bits_left; /* # of unused bits in it */
|
||||
} bitread_perm_state;
|
||||
|
||||
typedef struct { /* Bitreading working state within an MCU */
|
||||
/* Current data source location */
|
||||
/* We need a copy, rather than munging the original, in case of suspension */
|
||||
const JOCTET * next_input_byte; /* => next byte to read from source */
|
||||
size_t bytes_in_buffer; /* # of bytes remaining in source buffer */
|
||||
/* Bit input buffer --- note these values are kept in register variables,
|
||||
* not in this struct, inside the inner loops.
|
||||
*/
|
||||
bit_buf_type get_buffer; /* current bit-extraction buffer */
|
||||
int bits_left; /* # of unused bits in it */
|
||||
/* Pointer needed by jpeg_fill_bit_buffer. */
|
||||
j_decompress_ptr cinfo; /* back link to decompress master record */
|
||||
} bitread_working_state;
|
||||
|
||||
/* Macros to declare and load/save bitread local variables. */
|
||||
#define BITREAD_STATE_VARS \
|
||||
bit_buf_type get_buffer; \
|
||||
int bits_left; \
|
||||
bitread_working_state br_state
|
||||
|
||||
#define BITREAD_LOAD_STATE(cinfop,permstate) \
|
||||
br_state.cinfo = cinfop; \
|
||||
br_state.next_input_byte = cinfop->src->next_input_byte; \
|
||||
br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \
|
||||
get_buffer = permstate.get_buffer; \
|
||||
bits_left = permstate.bits_left;
|
||||
|
||||
#define BITREAD_SAVE_STATE(cinfop,permstate) \
|
||||
cinfop->src->next_input_byte = br_state.next_input_byte; \
|
||||
cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \
|
||||
permstate.get_buffer = get_buffer; \
|
||||
permstate.bits_left = bits_left
|
||||
|
||||
/*
|
||||
* These macros provide the in-line portion of bit fetching.
|
||||
* Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer
|
||||
* before using GET_BITS, PEEK_BITS, or DROP_BITS.
|
||||
* The variables get_buffer and bits_left are assumed to be locals,
|
||||
* but the state struct might not be (jpeg_huff_decode needs this).
|
||||
* CHECK_BIT_BUFFER(state,n,action);
|
||||
* Ensure there are N bits in get_buffer; if suspend, take action.
|
||||
* val = GET_BITS(n);
|
||||
* Fetch next N bits.
|
||||
* val = PEEK_BITS(n);
|
||||
* Fetch next N bits without removing them from the buffer.
|
||||
* DROP_BITS(n);
|
||||
* Discard next N bits.
|
||||
* The value N should be a simple variable, not an expression, because it
|
||||
* is evaluated multiple times.
|
||||
*/
|
||||
|
||||
#define CHECK_BIT_BUFFER(state,nbits,action) \
|
||||
{ if (bits_left < (nbits)) { \
|
||||
if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \
|
||||
{ action; } \
|
||||
get_buffer = (state).get_buffer; bits_left = (state).bits_left; } }
|
||||
|
||||
#define GET_BITS(nbits) \
|
||||
(((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1))
|
||||
|
||||
#define PEEK_BITS(nbits) \
|
||||
(((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1))
|
||||
|
||||
#define DROP_BITS(nbits) \
|
||||
(bits_left -= (nbits))
|
||||
|
||||
/* Load up the bit buffer to a depth of at least nbits */
|
||||
EXTERN(boolean) jpeg_fill_bit_buffer
|
||||
JPP((bitread_working_state * state, bit_buf_type get_buffer,
|
||||
int bits_left, int nbits));
|
||||
|
||||
|
||||
/*
|
||||
* Code for extracting next Huffman-coded symbol from input bit stream.
|
||||
* Again, this is time-critical and we make the main paths be macros.
|
||||
*
|
||||
* We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits
|
||||
* without looping. Usually, more than 95% of the Huffman codes will be 8
|
||||
* or fewer bits long. The few overlength codes are handled with a loop,
|
||||
* which need not be inline code.
|
||||
*
|
||||
* Notes about the HUFF_DECODE macro:
|
||||
* 1. Near the end of the data segment, we may fail to get enough bits
|
||||
* for a lookahead. In that case, we do it the hard way.
|
||||
* 2. If the lookahead table contains no entry, the next code must be
|
||||
* more than HUFF_LOOKAHEAD bits long.
|
||||
* 3. jpeg_huff_decode returns -1 if forced to suspend.
|
||||
*/
|
||||
|
||||
#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \
|
||||
{ int nb, look; \
|
||||
if (bits_left < HUFF_LOOKAHEAD) { \
|
||||
if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \
|
||||
get_buffer = state.get_buffer; bits_left = state.bits_left; \
|
||||
if (bits_left < HUFF_LOOKAHEAD) { \
|
||||
nb = 1; goto slowlabel; \
|
||||
} \
|
||||
} \
|
||||
look = PEEK_BITS(HUFF_LOOKAHEAD); \
|
||||
if ((nb = htbl->look_nbits[look]) != 0) { \
|
||||
DROP_BITS(nb); \
|
||||
result = htbl->look_sym[look]; \
|
||||
} else { \
|
||||
nb = HUFF_LOOKAHEAD+1; \
|
||||
slowlabel: \
|
||||
if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \
|
||||
{ failaction; } \
|
||||
get_buffer = state.get_buffer; bits_left = state.bits_left; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Out-of-line case for Huffman code fetching */
|
||||
EXTERN(int) jpeg_huff_decode
|
||||
JPP((bitread_working_state * state, bit_buf_type get_buffer,
|
||||
int bits_left, d_derived_tbl * htbl, int min_bits));
|
||||
|
||||
#endif
|
||||
|
@ -1,381 +1,381 @@
|
||||
/*
|
||||
* jdinput.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 input control logic for the JPEG decompressor.
|
||||
* These routines are concerned with controlling the decompressor's input
|
||||
* processing (marker reading and coefficient decoding). The actual input
|
||||
* reading is done in jdmarker.c, jdhuff.c, and jdphuff.c.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Private state */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_input_controller pub; /* public fields */
|
||||
|
||||
boolean inheaders; /* TRUE until first SOS is reached */
|
||||
} my_input_controller;
|
||||
|
||||
typedef my_input_controller * my_inputctl_ptr;
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
|
||||
|
||||
|
||||
/*
|
||||
* Routines to calculate various quantities related to the size of the image.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
initial_setup2 (j_decompress_ptr cinfo)
|
||||
/* Called once, when first SOS marker is reached */
|
||||
{
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Make sure image isn't bigger than I can handle */
|
||||
if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
|
||||
(long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
|
||||
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
|
||||
|
||||
/* For now, precision must match compiled-in value... */
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
/* Check that number of components won't exceed internal array sizes */
|
||||
if (cinfo->num_components > MAX_COMPONENTS)
|
||||
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
|
||||
MAX_COMPONENTS);
|
||||
|
||||
/* Compute maximum sampling factors; check factor validity */
|
||||
cinfo->max_h_samp_factor = 1;
|
||||
cinfo->max_v_samp_factor = 1;
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
|
||||
compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
|
||||
ERREXIT(cinfo, JERR_BAD_SAMPLING);
|
||||
cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
|
||||
compptr->h_samp_factor);
|
||||
cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
|
||||
compptr->v_samp_factor);
|
||||
}
|
||||
|
||||
/* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE.
|
||||
* In the full decompressor, this will be overridden by jdmaster.c;
|
||||
* but in the transcoder, jdmaster.c is not used, so we must do it here.
|
||||
*/
|
||||
cinfo->min_DCT_scaled_size = DCTSIZE;
|
||||
|
||||
/* Compute dimensions of components */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
compptr->DCT_scaled_size = DCTSIZE;
|
||||
/* Size in DCT blocks */
|
||||
compptr->width_in_blocks = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
|
||||
(long) (cinfo->max_h_samp_factor * DCTSIZE));
|
||||
compptr->height_in_blocks = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
|
||||
(long) (cinfo->max_v_samp_factor * DCTSIZE));
|
||||
/* downsampled_width and downsampled_height will also be overridden by
|
||||
* jdmaster.c if we are doing full decompression. The transcoder library
|
||||
* doesn't use these values, but the calling application might.
|
||||
*/
|
||||
/* Size in samples */
|
||||
compptr->downsampled_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
|
||||
(long) cinfo->max_h_samp_factor);
|
||||
compptr->downsampled_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
|
||||
(long) cinfo->max_v_samp_factor);
|
||||
/* Mark component needed, until color conversion says otherwise */
|
||||
compptr->component_needed = TRUE;
|
||||
/* Mark no quantization table yet saved for component */
|
||||
compptr->quant_table = NULL;
|
||||
}
|
||||
|
||||
/* Compute number of fully interleaved MCU rows. */
|
||||
cinfo->total_iMCU_rows = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height,
|
||||
(long) (cinfo->max_v_samp_factor*DCTSIZE));
|
||||
|
||||
/* Decide whether file contains multiple scans */
|
||||
if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode)
|
||||
cinfo->inputctl->has_multiple_scans = TRUE;
|
||||
else
|
||||
cinfo->inputctl->has_multiple_scans = FALSE;
|
||||
}
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
per_scan_setup2 (j_decompress_ptr cinfo)
|
||||
/* Do computations that are needed before processing a JPEG scan */
|
||||
/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */
|
||||
{
|
||||
int ci, mcublks, tmp;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
if (cinfo->comps_in_scan == 1) {
|
||||
|
||||
/* Noninterleaved (single-component) scan */
|
||||
compptr = cinfo->cur_comp_info[0];
|
||||
|
||||
/* Overall image size in MCUs */
|
||||
cinfo->MCUs_per_row = compptr->width_in_blocks;
|
||||
cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
|
||||
|
||||
/* For noninterleaved scan, always one block per MCU */
|
||||
compptr->MCU_width = 1;
|
||||
compptr->MCU_height = 1;
|
||||
compptr->MCU_blocks = 1;
|
||||
compptr->MCU_sample_width = compptr->DCT_scaled_size;
|
||||
compptr->last_col_width = 1;
|
||||
/* For noninterleaved scans, it is convenient to define last_row_height
|
||||
* as the number of block rows present in the last iMCU row.
|
||||
*/
|
||||
tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
|
||||
if (tmp == 0) tmp = compptr->v_samp_factor;
|
||||
compptr->last_row_height = tmp;
|
||||
|
||||
/* Prepare array describing MCU composition */
|
||||
cinfo->blocks_in_MCU = 1;
|
||||
cinfo->MCU_membership[0] = 0;
|
||||
|
||||
} else {
|
||||
|
||||
/* Interleaved (multi-component) scan */
|
||||
if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
|
||||
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
|
||||
MAX_COMPS_IN_SCAN);
|
||||
|
||||
/* Overall image size in MCUs */
|
||||
cinfo->MCUs_per_row = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width,
|
||||
(long) (cinfo->max_h_samp_factor*DCTSIZE));
|
||||
cinfo->MCU_rows_in_scan = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height,
|
||||
(long) (cinfo->max_v_samp_factor*DCTSIZE));
|
||||
|
||||
cinfo->blocks_in_MCU = 0;
|
||||
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
/* Sampling factors give # of blocks of component in each MCU */
|
||||
compptr->MCU_width = compptr->h_samp_factor;
|
||||
compptr->MCU_height = compptr->v_samp_factor;
|
||||
compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
|
||||
compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size;
|
||||
/* Figure number of non-dummy blocks in last MCU column & row */
|
||||
tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
|
||||
if (tmp == 0) tmp = compptr->MCU_width;
|
||||
compptr->last_col_width = tmp;
|
||||
tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
|
||||
if (tmp == 0) tmp = compptr->MCU_height;
|
||||
compptr->last_row_height = tmp;
|
||||
/* Prepare array describing MCU composition */
|
||||
mcublks = compptr->MCU_blocks;
|
||||
if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU)
|
||||
ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
|
||||
while (mcublks-- > 0) {
|
||||
cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Save away a copy of the Q-table referenced by each component present
|
||||
* in the current scan, unless already saved during a prior scan.
|
||||
*
|
||||
* In a multiple-scan JPEG file, the encoder could assign different components
|
||||
* the same Q-table slot number, but change table definitions between scans
|
||||
* so that each component uses a different Q-table. (The IJG encoder is not
|
||||
* currently capable of doing this, but other encoders might.) Since we want
|
||||
* to be able to dequantize all the components at the end of the file, this
|
||||
* means that we have to save away the table actually used for each component.
|
||||
* We do this by copying the table at the start of the first scan containing
|
||||
* the component.
|
||||
* The JPEG spec prohibits the encoder from changing the contents of a Q-table
|
||||
* slot between scans of a component using that slot. If the encoder does so
|
||||
* anyway, this decoder will simply use the Q-table values that were current
|
||||
* at the start of the first scan for the component.
|
||||
*
|
||||
* The decompressor output side looks only at the saved quant tables,
|
||||
* not at the current Q-table slots.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
latch_quant_tables (j_decompress_ptr cinfo)
|
||||
{
|
||||
int ci, qtblno;
|
||||
jpeg_component_info *compptr;
|
||||
JQUANT_TBL * qtbl;
|
||||
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
/* No work if we already saved Q-table for this component */
|
||||
if (compptr->quant_table != NULL)
|
||||
continue;
|
||||
/* Make sure specified quantization table is present */
|
||||
qtblno = compptr->quant_tbl_no;
|
||||
if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
|
||||
cinfo->quant_tbl_ptrs[qtblno] == NULL)
|
||||
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
|
||||
/* OK, save away the quantization table */
|
||||
qtbl = (JQUANT_TBL *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(JQUANT_TBL));
|
||||
MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL));
|
||||
compptr->quant_table = qtbl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the input modules to read a scan of compressed data.
|
||||
* The first call to this is done by jdmaster.c after initializing
|
||||
* the entire decompressor (during jpeg_start_decompress).
|
||||
* Subsequent calls come from consume_markers, below.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_input_pass2 (j_decompress_ptr cinfo)
|
||||
{
|
||||
per_scan_setup2(cinfo);
|
||||
latch_quant_tables(cinfo);
|
||||
(*cinfo->entropy->start_pass) (cinfo);
|
||||
(*cinfo->coef->start_input_pass) (cinfo);
|
||||
cinfo->inputctl->consume_input = cinfo->coef->consume_data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish up after inputting a compressed-data scan.
|
||||
* This is called by the coefficient controller after it's read all
|
||||
* the expected data of the scan.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
finish_input_pass (j_decompress_ptr cinfo)
|
||||
{
|
||||
cinfo->inputctl->consume_input = consume_markers;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read JPEG markers before, between, or after compressed-data scans.
|
||||
* Change state as necessary when a new scan is reached.
|
||||
* Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
|
||||
*
|
||||
* The consume_input method pointer points either here or to the
|
||||
* coefficient controller's consume_data routine, depending on whether
|
||||
* we are reading a compressed data segment or inter-segment markers.
|
||||
*/
|
||||
|
||||
METHODDEF(int)
|
||||
consume_markers (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
|
||||
int val;
|
||||
|
||||
if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */
|
||||
return JPEG_REACHED_EOI;
|
||||
|
||||
val = (*cinfo->marker->read_markers) (cinfo);
|
||||
|
||||
switch (val) {
|
||||
case JPEG_REACHED_SOS: /* Found SOS */
|
||||
if (inputctl->inheaders) { /* 1st SOS */
|
||||
initial_setup2(cinfo);
|
||||
inputctl->inheaders = FALSE;
|
||||
/* Note: start_input_pass must be called by jdmaster.c
|
||||
* before any more input can be consumed. jdapimin.c is
|
||||
* responsible for enforcing this sequencing.
|
||||
*/
|
||||
} else { /* 2nd or later SOS marker */
|
||||
if (! inputctl->pub.has_multiple_scans)
|
||||
ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */
|
||||
start_input_pass2(cinfo);
|
||||
}
|
||||
break;
|
||||
case JPEG_REACHED_EOI: /* Found EOI */
|
||||
inputctl->pub.eoi_reached = TRUE;
|
||||
if (inputctl->inheaders) { /* Tables-only datastream, apparently */
|
||||
if (cinfo->marker->saw_SOF)
|
||||
ERREXIT(cinfo, JERR_SOF_NO_SOS);
|
||||
} else {
|
||||
/* Prevent infinite loop in coef ctlr's decompress_data routine
|
||||
* if user set output_scan_number larger than number of scans.
|
||||
*/
|
||||
if (cinfo->output_scan_number > cinfo->input_scan_number)
|
||||
cinfo->output_scan_number = cinfo->input_scan_number;
|
||||
}
|
||||
break;
|
||||
case JPEG_SUSPENDED:
|
||||
break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reset state to begin a fresh datastream.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
reset_input_controller (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
|
||||
|
||||
inputctl->pub.consume_input = consume_markers;
|
||||
inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
|
||||
inputctl->pub.eoi_reached = FALSE;
|
||||
inputctl->inheaders = TRUE;
|
||||
/* Reset other modules */
|
||||
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
|
||||
(*cinfo->marker->reset_marker_reader) (cinfo);
|
||||
/* Reset progression state -- would be cleaner if entropy decoder did this */
|
||||
cinfo->coef_bits = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the input controller module.
|
||||
* This is called only once, when the decompression object is created.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_input_controller (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_inputctl_ptr inputctl;
|
||||
|
||||
/* Create subobject in permanent pool */
|
||||
inputctl = (my_inputctl_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(my_input_controller));
|
||||
cinfo->inputctl = (struct jpeg_input_controller *) inputctl;
|
||||
/* Initialize method pointers */
|
||||
inputctl->pub.consume_input = consume_markers;
|
||||
inputctl->pub.reset_input_controller = reset_input_controller;
|
||||
inputctl->pub.start_input_pass = start_input_pass2;
|
||||
inputctl->pub.finish_input_pass = finish_input_pass;
|
||||
/* Initialize state: can't use reset_input_controller since we don't
|
||||
* want to try to reset other modules yet.
|
||||
*/
|
||||
inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
|
||||
inputctl->pub.eoi_reached = FALSE;
|
||||
inputctl->inheaders = TRUE;
|
||||
}
|
||||
/*
|
||||
* jdinput.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 input control logic for the JPEG decompressor.
|
||||
* These routines are concerned with controlling the decompressor's input
|
||||
* processing (marker reading and coefficient decoding). The actual input
|
||||
* reading is done in jdmarker.c, jdhuff.c, and jdphuff.c.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Private state */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_input_controller pub; /* public fields */
|
||||
|
||||
boolean inheaders; /* TRUE until first SOS is reached */
|
||||
} my_input_controller;
|
||||
|
||||
typedef my_input_controller * my_inputctl_ptr;
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
|
||||
|
||||
|
||||
/*
|
||||
* Routines to calculate various quantities related to the size of the image.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
initial_setup2 (j_decompress_ptr cinfo)
|
||||
/* Called once, when first SOS marker is reached */
|
||||
{
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Make sure image isn't bigger than I can handle */
|
||||
if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
|
||||
(long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
|
||||
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
|
||||
|
||||
/* For now, precision must match compiled-in value... */
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
/* Check that number of components won't exceed internal array sizes */
|
||||
if (cinfo->num_components > MAX_COMPONENTS)
|
||||
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
|
||||
MAX_COMPONENTS);
|
||||
|
||||
/* Compute maximum sampling factors; check factor validity */
|
||||
cinfo->max_h_samp_factor = 1;
|
||||
cinfo->max_v_samp_factor = 1;
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
|
||||
compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
|
||||
ERREXIT(cinfo, JERR_BAD_SAMPLING);
|
||||
cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
|
||||
compptr->h_samp_factor);
|
||||
cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
|
||||
compptr->v_samp_factor);
|
||||
}
|
||||
|
||||
/* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE.
|
||||
* In the full decompressor, this will be overridden by jdmaster.c;
|
||||
* but in the transcoder, jdmaster.c is not used, so we must do it here.
|
||||
*/
|
||||
cinfo->min_DCT_scaled_size = DCTSIZE;
|
||||
|
||||
/* Compute dimensions of components */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
compptr->DCT_scaled_size = DCTSIZE;
|
||||
/* Size in DCT blocks */
|
||||
compptr->width_in_blocks = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
|
||||
(long) (cinfo->max_h_samp_factor * DCTSIZE));
|
||||
compptr->height_in_blocks = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
|
||||
(long) (cinfo->max_v_samp_factor * DCTSIZE));
|
||||
/* downsampled_width and downsampled_height will also be overridden by
|
||||
* jdmaster.c if we are doing full decompression. The transcoder library
|
||||
* doesn't use these values, but the calling application might.
|
||||
*/
|
||||
/* Size in samples */
|
||||
compptr->downsampled_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
|
||||
(long) cinfo->max_h_samp_factor);
|
||||
compptr->downsampled_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
|
||||
(long) cinfo->max_v_samp_factor);
|
||||
/* Mark component needed, until color conversion says otherwise */
|
||||
compptr->component_needed = TRUE;
|
||||
/* Mark no quantization table yet saved for component */
|
||||
compptr->quant_table = NULL;
|
||||
}
|
||||
|
||||
/* Compute number of fully interleaved MCU rows. */
|
||||
cinfo->total_iMCU_rows = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height,
|
||||
(long) (cinfo->max_v_samp_factor*DCTSIZE));
|
||||
|
||||
/* Decide whether file contains multiple scans */
|
||||
if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode)
|
||||
cinfo->inputctl->has_multiple_scans = TRUE;
|
||||
else
|
||||
cinfo->inputctl->has_multiple_scans = FALSE;
|
||||
}
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
per_scan_setup2 (j_decompress_ptr cinfo)
|
||||
/* Do computations that are needed before processing a JPEG scan */
|
||||
/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */
|
||||
{
|
||||
int ci, mcublks, tmp;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
if (cinfo->comps_in_scan == 1) {
|
||||
|
||||
/* Noninterleaved (single-component) scan */
|
||||
compptr = cinfo->cur_comp_info[0];
|
||||
|
||||
/* Overall image size in MCUs */
|
||||
cinfo->MCUs_per_row = compptr->width_in_blocks;
|
||||
cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
|
||||
|
||||
/* For noninterleaved scan, always one block per MCU */
|
||||
compptr->MCU_width = 1;
|
||||
compptr->MCU_height = 1;
|
||||
compptr->MCU_blocks = 1;
|
||||
compptr->MCU_sample_width = compptr->DCT_scaled_size;
|
||||
compptr->last_col_width = 1;
|
||||
/* For noninterleaved scans, it is convenient to define last_row_height
|
||||
* as the number of block rows present in the last iMCU row.
|
||||
*/
|
||||
tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
|
||||
if (tmp == 0) tmp = compptr->v_samp_factor;
|
||||
compptr->last_row_height = tmp;
|
||||
|
||||
/* Prepare array describing MCU composition */
|
||||
cinfo->blocks_in_MCU = 1;
|
||||
cinfo->MCU_membership[0] = 0;
|
||||
|
||||
} else {
|
||||
|
||||
/* Interleaved (multi-component) scan */
|
||||
if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
|
||||
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
|
||||
MAX_COMPS_IN_SCAN);
|
||||
|
||||
/* Overall image size in MCUs */
|
||||
cinfo->MCUs_per_row = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width,
|
||||
(long) (cinfo->max_h_samp_factor*DCTSIZE));
|
||||
cinfo->MCU_rows_in_scan = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height,
|
||||
(long) (cinfo->max_v_samp_factor*DCTSIZE));
|
||||
|
||||
cinfo->blocks_in_MCU = 0;
|
||||
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
/* Sampling factors give # of blocks of component in each MCU */
|
||||
compptr->MCU_width = compptr->h_samp_factor;
|
||||
compptr->MCU_height = compptr->v_samp_factor;
|
||||
compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
|
||||
compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size;
|
||||
/* Figure number of non-dummy blocks in last MCU column & row */
|
||||
tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
|
||||
if (tmp == 0) tmp = compptr->MCU_width;
|
||||
compptr->last_col_width = tmp;
|
||||
tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
|
||||
if (tmp == 0) tmp = compptr->MCU_height;
|
||||
compptr->last_row_height = tmp;
|
||||
/* Prepare array describing MCU composition */
|
||||
mcublks = compptr->MCU_blocks;
|
||||
if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU)
|
||||
ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
|
||||
while (mcublks-- > 0) {
|
||||
cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Save away a copy of the Q-table referenced by each component present
|
||||
* in the current scan, unless already saved during a prior scan.
|
||||
*
|
||||
* In a multiple-scan JPEG file, the encoder could assign different components
|
||||
* the same Q-table slot number, but change table definitions between scans
|
||||
* so that each component uses a different Q-table. (The IJG encoder is not
|
||||
* currently capable of doing this, but other encoders might.) Since we want
|
||||
* to be able to dequantize all the components at the end of the file, this
|
||||
* means that we have to save away the table actually used for each component.
|
||||
* We do this by copying the table at the start of the first scan containing
|
||||
* the component.
|
||||
* The JPEG spec prohibits the encoder from changing the contents of a Q-table
|
||||
* slot between scans of a component using that slot. If the encoder does so
|
||||
* anyway, this decoder will simply use the Q-table values that were current
|
||||
* at the start of the first scan for the component.
|
||||
*
|
||||
* The decompressor output side looks only at the saved quant tables,
|
||||
* not at the current Q-table slots.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
latch_quant_tables (j_decompress_ptr cinfo)
|
||||
{
|
||||
int ci, qtblno;
|
||||
jpeg_component_info *compptr;
|
||||
JQUANT_TBL * qtbl;
|
||||
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
/* No work if we already saved Q-table for this component */
|
||||
if (compptr->quant_table != NULL)
|
||||
continue;
|
||||
/* Make sure specified quantization table is present */
|
||||
qtblno = compptr->quant_tbl_no;
|
||||
if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
|
||||
cinfo->quant_tbl_ptrs[qtblno] == NULL)
|
||||
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
|
||||
/* OK, save away the quantization table */
|
||||
qtbl = (JQUANT_TBL *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(JQUANT_TBL));
|
||||
MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL));
|
||||
compptr->quant_table = qtbl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the input modules to read a scan of compressed data.
|
||||
* The first call to this is done by jdmaster.c after initializing
|
||||
* the entire decompressor (during jpeg_start_decompress).
|
||||
* Subsequent calls come from consume_markers, below.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_input_pass2 (j_decompress_ptr cinfo)
|
||||
{
|
||||
per_scan_setup2(cinfo);
|
||||
latch_quant_tables(cinfo);
|
||||
(*cinfo->entropy->start_pass) (cinfo);
|
||||
(*cinfo->coef->start_input_pass) (cinfo);
|
||||
cinfo->inputctl->consume_input = cinfo->coef->consume_data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish up after inputting a compressed-data scan.
|
||||
* This is called by the coefficient controller after it's read all
|
||||
* the expected data of the scan.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
finish_input_pass (j_decompress_ptr cinfo)
|
||||
{
|
||||
cinfo->inputctl->consume_input = consume_markers;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read JPEG markers before, between, or after compressed-data scans.
|
||||
* Change state as necessary when a new scan is reached.
|
||||
* Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
|
||||
*
|
||||
* The consume_input method pointer points either here or to the
|
||||
* coefficient controller's consume_data routine, depending on whether
|
||||
* we are reading a compressed data segment or inter-segment markers.
|
||||
*/
|
||||
|
||||
METHODDEF(int)
|
||||
consume_markers (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
|
||||
int val;
|
||||
|
||||
if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */
|
||||
return JPEG_REACHED_EOI;
|
||||
|
||||
val = (*cinfo->marker->read_markers) (cinfo);
|
||||
|
||||
switch (val) {
|
||||
case JPEG_REACHED_SOS: /* Found SOS */
|
||||
if (inputctl->inheaders) { /* 1st SOS */
|
||||
initial_setup2(cinfo);
|
||||
inputctl->inheaders = FALSE;
|
||||
/* Note: start_input_pass must be called by jdmaster.c
|
||||
* before any more input can be consumed. jdapimin.c is
|
||||
* responsible for enforcing this sequencing.
|
||||
*/
|
||||
} else { /* 2nd or later SOS marker */
|
||||
if (! inputctl->pub.has_multiple_scans)
|
||||
ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */
|
||||
start_input_pass2(cinfo);
|
||||
}
|
||||
break;
|
||||
case JPEG_REACHED_EOI: /* Found EOI */
|
||||
inputctl->pub.eoi_reached = TRUE;
|
||||
if (inputctl->inheaders) { /* Tables-only datastream, apparently */
|
||||
if (cinfo->marker->saw_SOF)
|
||||
ERREXIT(cinfo, JERR_SOF_NO_SOS);
|
||||
} else {
|
||||
/* Prevent infinite loop in coef ctlr's decompress_data routine
|
||||
* if user set output_scan_number larger than number of scans.
|
||||
*/
|
||||
if (cinfo->output_scan_number > cinfo->input_scan_number)
|
||||
cinfo->output_scan_number = cinfo->input_scan_number;
|
||||
}
|
||||
break;
|
||||
case JPEG_SUSPENDED:
|
||||
break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reset state to begin a fresh datastream.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
reset_input_controller (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
|
||||
|
||||
inputctl->pub.consume_input = consume_markers;
|
||||
inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
|
||||
inputctl->pub.eoi_reached = FALSE;
|
||||
inputctl->inheaders = TRUE;
|
||||
/* Reset other modules */
|
||||
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
|
||||
(*cinfo->marker->reset_marker_reader) (cinfo);
|
||||
/* Reset progression state -- would be cleaner if entropy decoder did this */
|
||||
cinfo->coef_bits = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the input controller module.
|
||||
* This is called only once, when the decompression object is created.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_input_controller (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_inputctl_ptr inputctl;
|
||||
|
||||
/* Create subobject in permanent pool */
|
||||
inputctl = (my_inputctl_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(my_input_controller));
|
||||
cinfo->inputctl = (struct jpeg_input_controller *) inputctl;
|
||||
/* Initialize method pointers */
|
||||
inputctl->pub.consume_input = consume_markers;
|
||||
inputctl->pub.reset_input_controller = reset_input_controller;
|
||||
inputctl->pub.start_input_pass = start_input_pass2;
|
||||
inputctl->pub.finish_input_pass = finish_input_pass;
|
||||
/* Initialize state: can't use reset_input_controller since we don't
|
||||
* want to try to reset other modules yet.
|
||||
*/
|
||||
inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
|
||||
inputctl->pub.eoi_reached = FALSE;
|
||||
inputctl->inheaders = TRUE;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,400 +1,400 @@
|
||||
/*
|
||||
* jdmerge.c
|
||||
*
|
||||
* Copyright (C) 1994-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 code for merged upsampling/color conversion.
|
||||
*
|
||||
* This file combines functions from jdsample.c and jdcolor.c;
|
||||
* read those files first to understand what's going on.
|
||||
*
|
||||
* When the chroma components are to be upsampled by simple replication
|
||||
* (ie, box filtering), we can save some work in color conversion by
|
||||
* calculating all the output pixels corresponding to a pair of chroma
|
||||
* samples at one time. In the conversion equations
|
||||
* R = Y + K1 * Cr
|
||||
* G = Y + K2 * Cb + K3 * Cr
|
||||
* B = Y + K4 * Cb
|
||||
* only the Y term varies among the group of pixels corresponding to a pair
|
||||
* of chroma samples, so the rest of the terms can be calculated just once.
|
||||
* At typical sampling ratios, this eliminates half or three-quarters of the
|
||||
* multiplications needed for color conversion.
|
||||
*
|
||||
* This file currently provides implementations for the following cases:
|
||||
* YCbCr => RGB color conversion only.
|
||||
* Sampling ratios of 2h1v or 2h2v.
|
||||
* No scaling needed at upsample time.
|
||||
* Corner-aligned (non-CCIR601) sampling alignment.
|
||||
* Other special cases could be added, but in most applications these are
|
||||
* the only common cases. (For uncommon cases we fall back on the more
|
||||
* general code in jdsample.c and jdcolor.c.)
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
#ifdef UPSAMPLE_MERGING_SUPPORTED
|
||||
|
||||
|
||||
/* Private subobject */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_upsampler pub; /* public fields */
|
||||
|
||||
/* Pointer to routine to do actual upsampling/conversion of one row group */
|
||||
JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf));
|
||||
|
||||
/* Private state for YCC->RGB conversion */
|
||||
int * Cr_r_tab; /* => table for Cr to R conversion */
|
||||
int * Cb_b_tab; /* => table for Cb to B conversion */
|
||||
INT32 * Cr_g_tab; /* => table for Cr to G conversion */
|
||||
INT32 * Cb_g_tab; /* => table for Cb to G conversion */
|
||||
|
||||
/* For 2:1 vertical sampling, we produce two output rows at a time.
|
||||
* We need a "spare" row buffer to hold the second output row if the
|
||||
* application provides just a one-row buffer; we also use the spare
|
||||
* to discard the dummy last row if the image height is odd.
|
||||
*/
|
||||
JSAMPROW spare_row;
|
||||
boolean spare_full; /* T if spare buffer is occupied */
|
||||
|
||||
JDIMENSION out_row_width; /* samples per output row */
|
||||
JDIMENSION rows_to_go; /* counts rows remaining in image */
|
||||
} my_upsampler;
|
||||
|
||||
typedef my_upsampler * my_upsample_ptr;
|
||||
|
||||
#define SCALEBITS 16 /* speediest right-shift on some machines */
|
||||
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
|
||||
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
|
||||
|
||||
|
||||
/*
|
||||
* Initialize tables for YCC->RGB colorspace conversion.
|
||||
* This is taken directly from jdcolor.c; see that file for more info.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
build_ycc_rgb_table2 (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
||||
int i;
|
||||
INT32 x;
|
||||
SHIFT_TEMPS
|
||||
|
||||
upsample->Cr_r_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
upsample->Cb_b_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
upsample->Cr_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
upsample->Cb_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
|
||||
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
|
||||
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
|
||||
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
|
||||
/* Cr=>R value is nearest int to 1.40200 * x */
|
||||
upsample->Cr_r_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
|
||||
/* Cb=>B value is nearest int to 1.77200 * x */
|
||||
upsample->Cb_b_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
|
||||
/* Cr=>G value is scaled-up -0.71414 * x */
|
||||
upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
|
||||
/* Cb=>G value is scaled-up -0.34414 * x */
|
||||
/* We also add in ONE_HALF so that need not do it in inner loop */
|
||||
upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for an upsampling pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_merged_upsample (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
||||
|
||||
/* Mark the spare buffer empty */
|
||||
upsample->spare_full = FALSE;
|
||||
/* Initialize total-height counter for detecting bottom of image */
|
||||
upsample->rows_to_go = cinfo->output_height;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Control routine to do upsampling (and color conversion).
|
||||
*
|
||||
* The control routine just handles the row buffering considerations.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
merged_2v_upsample (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail)
|
||||
/* 2:1 vertical sampling case: may need a spare row. */
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
||||
JSAMPROW work_ptrs[2];
|
||||
JDIMENSION num_rows; /* number of rows returned to caller */
|
||||
|
||||
if (upsample->spare_full) {
|
||||
/* If we have a spare row saved from a previous cycle, just return it. */
|
||||
jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
|
||||
1, upsample->out_row_width);
|
||||
num_rows = 1;
|
||||
upsample->spare_full = FALSE;
|
||||
} else {
|
||||
/* Figure number of rows to return to caller. */
|
||||
num_rows = 2;
|
||||
/* Not more than the distance to the end of the image. */
|
||||
if (num_rows > upsample->rows_to_go)
|
||||
num_rows = upsample->rows_to_go;
|
||||
/* And not more than what the client can accept: */
|
||||
out_rows_avail -= *out_row_ctr;
|
||||
if (num_rows > out_rows_avail)
|
||||
num_rows = out_rows_avail;
|
||||
/* Create output pointer array for upsampler. */
|
||||
work_ptrs[0] = output_buf[*out_row_ctr];
|
||||
if (num_rows > 1) {
|
||||
work_ptrs[1] = output_buf[*out_row_ctr + 1];
|
||||
} else {
|
||||
work_ptrs[1] = upsample->spare_row;
|
||||
upsample->spare_full = TRUE;
|
||||
}
|
||||
/* Now do the upsampling. */
|
||||
(*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
|
||||
}
|
||||
|
||||
/* Adjust counts */
|
||||
*out_row_ctr += num_rows;
|
||||
upsample->rows_to_go -= num_rows;
|
||||
/* When the buffer is emptied, declare this input row group consumed */
|
||||
if (! upsample->spare_full)
|
||||
(*in_row_group_ctr)++;
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
merged_1v_upsample (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION)
|
||||
/* 1:1 vertical sampling case: much easier, never need a spare row. */
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
||||
|
||||
/* Just do the upsampling. */
|
||||
(*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
|
||||
output_buf + *out_row_ctr);
|
||||
/* Adjust counts */
|
||||
(*out_row_ctr)++;
|
||||
(*in_row_group_ctr)++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These are the routines invoked by the control routines to do
|
||||
* the actual upsampling/conversion. One row group is processed per call.
|
||||
*
|
||||
* Note: since we may be writing directly into application-supplied buffers,
|
||||
* we have to be honest about the output width; we can't assume the buffer
|
||||
* has been rounded up to an even width.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v1_merged_upsample (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf)
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
||||
int y, cred, cgreen, cblue;
|
||||
int cb, cr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPROW inptr0, inptr1, inptr2;
|
||||
JDIMENSION col;
|
||||
/* copy these pointers into registers if possible */
|
||||
JSAMPLE * range_limit = cinfo->sample_range_limit;
|
||||
int * Crrtab = upsample->Cr_r_tab;
|
||||
int * Cbbtab = upsample->Cb_b_tab;
|
||||
INT32 * Crgtab = upsample->Cr_g_tab;
|
||||
INT32 * Cbgtab = upsample->Cb_g_tab;
|
||||
SHIFT_TEMPS
|
||||
|
||||
inptr0 = input_buf[0][in_row_group_ctr];
|
||||
inptr1 = input_buf[1][in_row_group_ctr];
|
||||
inptr2 = input_buf[2][in_row_group_ctr];
|
||||
outptr = output_buf[0];
|
||||
/* Loop for each pair of output pixels */
|
||||
for (col = cinfo->output_width >> 1; col > 0; col--) {
|
||||
/* Do the chroma part of the calculation */
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
/* Fetch 2 Y values and emit 2 pixels */
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
outptr[RGB_RED] = range_limit[y + cred];
|
||||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
||||
outptr += RGB_PIXELSIZE;
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
outptr[RGB_RED] = range_limit[y + cred];
|
||||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
||||
outptr += RGB_PIXELSIZE;
|
||||
}
|
||||
/* If image width is odd, do the last output column separately */
|
||||
if (cinfo->output_width & 1) {
|
||||
cb = GETJSAMPLE(*inptr1);
|
||||
cr = GETJSAMPLE(*inptr2);
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
y = GETJSAMPLE(*inptr0);
|
||||
outptr[RGB_RED] = range_limit[y + cred];
|
||||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v2_merged_upsample (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf)
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
||||
int y, cred, cgreen, cblue;
|
||||
int cb, cr;
|
||||
JSAMPROW outptr0, outptr1;
|
||||
JSAMPROW inptr00, inptr01, inptr1, inptr2;
|
||||
JDIMENSION col;
|
||||
/* copy these pointers into registers if possible */
|
||||
JSAMPLE * range_limit = cinfo->sample_range_limit;
|
||||
int * Crrtab = upsample->Cr_r_tab;
|
||||
int * Cbbtab = upsample->Cb_b_tab;
|
||||
INT32 * Crgtab = upsample->Cr_g_tab;
|
||||
INT32 * Cbgtab = upsample->Cb_g_tab;
|
||||
SHIFT_TEMPS
|
||||
|
||||
inptr00 = input_buf[0][in_row_group_ctr*2];
|
||||
inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
|
||||
inptr1 = input_buf[1][in_row_group_ctr];
|
||||
inptr2 = input_buf[2][in_row_group_ctr];
|
||||
outptr0 = output_buf[0];
|
||||
outptr1 = output_buf[1];
|
||||
/* Loop for each group of output pixels */
|
||||
for (col = cinfo->output_width >> 1; col > 0; col--) {
|
||||
/* Do the chroma part of the calculation */
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
/* Fetch 4 Y values and emit 4 pixels */
|
||||
y = GETJSAMPLE(*inptr00++);
|
||||
outptr0[RGB_RED] = range_limit[y + cred];
|
||||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
||||
outptr0 += RGB_PIXELSIZE;
|
||||
y = GETJSAMPLE(*inptr00++);
|
||||
outptr0[RGB_RED] = range_limit[y + cred];
|
||||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
||||
outptr0 += RGB_PIXELSIZE;
|
||||
y = GETJSAMPLE(*inptr01++);
|
||||
outptr1[RGB_RED] = range_limit[y + cred];
|
||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
||||
outptr1 += RGB_PIXELSIZE;
|
||||
y = GETJSAMPLE(*inptr01++);
|
||||
outptr1[RGB_RED] = range_limit[y + cred];
|
||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
||||
outptr1 += RGB_PIXELSIZE;
|
||||
}
|
||||
/* If image width is odd, do the last output column separately */
|
||||
if (cinfo->output_width & 1) {
|
||||
cb = GETJSAMPLE(*inptr1);
|
||||
cr = GETJSAMPLE(*inptr2);
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
y = GETJSAMPLE(*inptr00);
|
||||
outptr0[RGB_RED] = range_limit[y + cred];
|
||||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
||||
y = GETJSAMPLE(*inptr01);
|
||||
outptr1[RGB_RED] = range_limit[y + cred];
|
||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for merged upsampling/color conversion.
|
||||
*
|
||||
* NB: this is called under the conditions determined by use_merged_upsample()
|
||||
* in jdmaster.c. That routine MUST correspond to the actual capabilities
|
||||
* of this module; no safety checks are made here.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_merged_upsampler (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_upsample_ptr upsample;
|
||||
|
||||
upsample = (my_upsample_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_upsampler));
|
||||
cinfo->upsample = (struct jpeg_upsampler *) upsample;
|
||||
upsample->pub.start_pass = start_pass_merged_upsample;
|
||||
upsample->pub.need_context_rows = FALSE;
|
||||
|
||||
upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
|
||||
|
||||
if (cinfo->max_v_samp_factor == 2) {
|
||||
upsample->pub.upsample = merged_2v_upsample;
|
||||
upsample->upmethod = h2v2_merged_upsample;
|
||||
/* Allocate a spare row buffer */
|
||||
upsample->spare_row = (JSAMPROW)
|
||||
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
|
||||
} else {
|
||||
upsample->pub.upsample = merged_1v_upsample;
|
||||
upsample->upmethod = h2v1_merged_upsample;
|
||||
/* No spare row needed */
|
||||
upsample->spare_row = NULL;
|
||||
}
|
||||
|
||||
build_ycc_rgb_table2(cinfo);
|
||||
}
|
||||
|
||||
#endif /* UPSAMPLE_MERGING_SUPPORTED */
|
||||
/*
|
||||
* jdmerge.c
|
||||
*
|
||||
* Copyright (C) 1994-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 code for merged upsampling/color conversion.
|
||||
*
|
||||
* This file combines functions from jdsample.c and jdcolor.c;
|
||||
* read those files first to understand what's going on.
|
||||
*
|
||||
* When the chroma components are to be upsampled by simple replication
|
||||
* (ie, box filtering), we can save some work in color conversion by
|
||||
* calculating all the output pixels corresponding to a pair of chroma
|
||||
* samples at one time. In the conversion equations
|
||||
* R = Y + K1 * Cr
|
||||
* G = Y + K2 * Cb + K3 * Cr
|
||||
* B = Y + K4 * Cb
|
||||
* only the Y term varies among the group of pixels corresponding to a pair
|
||||
* of chroma samples, so the rest of the terms can be calculated just once.
|
||||
* At typical sampling ratios, this eliminates half or three-quarters of the
|
||||
* multiplications needed for color conversion.
|
||||
*
|
||||
* This file currently provides implementations for the following cases:
|
||||
* YCbCr => RGB color conversion only.
|
||||
* Sampling ratios of 2h1v or 2h2v.
|
||||
* No scaling needed at upsample time.
|
||||
* Corner-aligned (non-CCIR601) sampling alignment.
|
||||
* Other special cases could be added, but in most applications these are
|
||||
* the only common cases. (For uncommon cases we fall back on the more
|
||||
* general code in jdsample.c and jdcolor.c.)
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
#ifdef UPSAMPLE_MERGING_SUPPORTED
|
||||
|
||||
|
||||
/* Private subobject */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_upsampler pub; /* public fields */
|
||||
|
||||
/* Pointer to routine to do actual upsampling/conversion of one row group */
|
||||
JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf));
|
||||
|
||||
/* Private state for YCC->RGB conversion */
|
||||
int * Cr_r_tab; /* => table for Cr to R conversion */
|
||||
int * Cb_b_tab; /* => table for Cb to B conversion */
|
||||
INT32 * Cr_g_tab; /* => table for Cr to G conversion */
|
||||
INT32 * Cb_g_tab; /* => table for Cb to G conversion */
|
||||
|
||||
/* For 2:1 vertical sampling, we produce two output rows at a time.
|
||||
* We need a "spare" row buffer to hold the second output row if the
|
||||
* application provides just a one-row buffer; we also use the spare
|
||||
* to discard the dummy last row if the image height is odd.
|
||||
*/
|
||||
JSAMPROW spare_row;
|
||||
boolean spare_full; /* T if spare buffer is occupied */
|
||||
|
||||
JDIMENSION out_row_width; /* samples per output row */
|
||||
JDIMENSION rows_to_go; /* counts rows remaining in image */
|
||||
} my_upsampler;
|
||||
|
||||
typedef my_upsampler * my_upsample_ptr;
|
||||
|
||||
#define SCALEBITS 16 /* speediest right-shift on some machines */
|
||||
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
|
||||
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
|
||||
|
||||
|
||||
/*
|
||||
* Initialize tables for YCC->RGB colorspace conversion.
|
||||
* This is taken directly from jdcolor.c; see that file for more info.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
build_ycc_rgb_table2 (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
||||
int i;
|
||||
INT32 x;
|
||||
SHIFT_TEMPS
|
||||
|
||||
upsample->Cr_r_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
upsample->Cb_b_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
||||
upsample->Cr_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
upsample->Cb_g_tab = (INT32 *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
||||
|
||||
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
|
||||
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
|
||||
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
|
||||
/* Cr=>R value is nearest int to 1.40200 * x */
|
||||
upsample->Cr_r_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
|
||||
/* Cb=>B value is nearest int to 1.77200 * x */
|
||||
upsample->Cb_b_tab[i] = (int)
|
||||
RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
|
||||
/* Cr=>G value is scaled-up -0.71414 * x */
|
||||
upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
|
||||
/* Cb=>G value is scaled-up -0.34414 * x */
|
||||
/* We also add in ONE_HALF so that need not do it in inner loop */
|
||||
upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for an upsampling pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_merged_upsample (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
||||
|
||||
/* Mark the spare buffer empty */
|
||||
upsample->spare_full = FALSE;
|
||||
/* Initialize total-height counter for detecting bottom of image */
|
||||
upsample->rows_to_go = cinfo->output_height;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Control routine to do upsampling (and color conversion).
|
||||
*
|
||||
* The control routine just handles the row buffering considerations.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
merged_2v_upsample (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail)
|
||||
/* 2:1 vertical sampling case: may need a spare row. */
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
||||
JSAMPROW work_ptrs[2];
|
||||
JDIMENSION num_rows; /* number of rows returned to caller */
|
||||
|
||||
if (upsample->spare_full) {
|
||||
/* If we have a spare row saved from a previous cycle, just return it. */
|
||||
jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
|
||||
1, upsample->out_row_width);
|
||||
num_rows = 1;
|
||||
upsample->spare_full = FALSE;
|
||||
} else {
|
||||
/* Figure number of rows to return to caller. */
|
||||
num_rows = 2;
|
||||
/* Not more than the distance to the end of the image. */
|
||||
if (num_rows > upsample->rows_to_go)
|
||||
num_rows = upsample->rows_to_go;
|
||||
/* And not more than what the client can accept: */
|
||||
out_rows_avail -= *out_row_ctr;
|
||||
if (num_rows > out_rows_avail)
|
||||
num_rows = out_rows_avail;
|
||||
/* Create output pointer array for upsampler. */
|
||||
work_ptrs[0] = output_buf[*out_row_ctr];
|
||||
if (num_rows > 1) {
|
||||
work_ptrs[1] = output_buf[*out_row_ctr + 1];
|
||||
} else {
|
||||
work_ptrs[1] = upsample->spare_row;
|
||||
upsample->spare_full = TRUE;
|
||||
}
|
||||
/* Now do the upsampling. */
|
||||
(*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
|
||||
}
|
||||
|
||||
/* Adjust counts */
|
||||
*out_row_ctr += num_rows;
|
||||
upsample->rows_to_go -= num_rows;
|
||||
/* When the buffer is emptied, declare this input row group consumed */
|
||||
if (! upsample->spare_full)
|
||||
(*in_row_group_ctr)++;
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
merged_1v_upsample (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION)
|
||||
/* 1:1 vertical sampling case: much easier, never need a spare row. */
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
||||
|
||||
/* Just do the upsampling. */
|
||||
(*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
|
||||
output_buf + *out_row_ctr);
|
||||
/* Adjust counts */
|
||||
(*out_row_ctr)++;
|
||||
(*in_row_group_ctr)++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These are the routines invoked by the control routines to do
|
||||
* the actual upsampling/conversion. One row group is processed per call.
|
||||
*
|
||||
* Note: since we may be writing directly into application-supplied buffers,
|
||||
* we have to be honest about the output width; we can't assume the buffer
|
||||
* has been rounded up to an even width.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v1_merged_upsample (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf)
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
||||
int y, cred, cgreen, cblue;
|
||||
int cb, cr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPROW inptr0, inptr1, inptr2;
|
||||
JDIMENSION col;
|
||||
/* copy these pointers into registers if possible */
|
||||
JSAMPLE * range_limit = cinfo->sample_range_limit;
|
||||
int * Crrtab = upsample->Cr_r_tab;
|
||||
int * Cbbtab = upsample->Cb_b_tab;
|
||||
INT32 * Crgtab = upsample->Cr_g_tab;
|
||||
INT32 * Cbgtab = upsample->Cb_g_tab;
|
||||
SHIFT_TEMPS
|
||||
|
||||
inptr0 = input_buf[0][in_row_group_ctr];
|
||||
inptr1 = input_buf[1][in_row_group_ctr];
|
||||
inptr2 = input_buf[2][in_row_group_ctr];
|
||||
outptr = output_buf[0];
|
||||
/* Loop for each pair of output pixels */
|
||||
for (col = cinfo->output_width >> 1; col > 0; col--) {
|
||||
/* Do the chroma part of the calculation */
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
/* Fetch 2 Y values and emit 2 pixels */
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
outptr[RGB_RED] = range_limit[y + cred];
|
||||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
||||
outptr += RGB_PIXELSIZE;
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
outptr[RGB_RED] = range_limit[y + cred];
|
||||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
||||
outptr += RGB_PIXELSIZE;
|
||||
}
|
||||
/* If image width is odd, do the last output column separately */
|
||||
if (cinfo->output_width & 1) {
|
||||
cb = GETJSAMPLE(*inptr1);
|
||||
cr = GETJSAMPLE(*inptr2);
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
y = GETJSAMPLE(*inptr0);
|
||||
outptr[RGB_RED] = range_limit[y + cred];
|
||||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v2_merged_upsample (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf)
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
||||
int y, cred, cgreen, cblue;
|
||||
int cb, cr;
|
||||
JSAMPROW outptr0, outptr1;
|
||||
JSAMPROW inptr00, inptr01, inptr1, inptr2;
|
||||
JDIMENSION col;
|
||||
/* copy these pointers into registers if possible */
|
||||
JSAMPLE * range_limit = cinfo->sample_range_limit;
|
||||
int * Crrtab = upsample->Cr_r_tab;
|
||||
int * Cbbtab = upsample->Cb_b_tab;
|
||||
INT32 * Crgtab = upsample->Cr_g_tab;
|
||||
INT32 * Cbgtab = upsample->Cb_g_tab;
|
||||
SHIFT_TEMPS
|
||||
|
||||
inptr00 = input_buf[0][in_row_group_ctr*2];
|
||||
inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
|
||||
inptr1 = input_buf[1][in_row_group_ctr];
|
||||
inptr2 = input_buf[2][in_row_group_ctr];
|
||||
outptr0 = output_buf[0];
|
||||
outptr1 = output_buf[1];
|
||||
/* Loop for each group of output pixels */
|
||||
for (col = cinfo->output_width >> 1; col > 0; col--) {
|
||||
/* Do the chroma part of the calculation */
|
||||
cb = GETJSAMPLE(*inptr1++);
|
||||
cr = GETJSAMPLE(*inptr2++);
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
/* Fetch 4 Y values and emit 4 pixels */
|
||||
y = GETJSAMPLE(*inptr00++);
|
||||
outptr0[RGB_RED] = range_limit[y + cred];
|
||||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
||||
outptr0 += RGB_PIXELSIZE;
|
||||
y = GETJSAMPLE(*inptr00++);
|
||||
outptr0[RGB_RED] = range_limit[y + cred];
|
||||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
||||
outptr0 += RGB_PIXELSIZE;
|
||||
y = GETJSAMPLE(*inptr01++);
|
||||
outptr1[RGB_RED] = range_limit[y + cred];
|
||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
||||
outptr1 += RGB_PIXELSIZE;
|
||||
y = GETJSAMPLE(*inptr01++);
|
||||
outptr1[RGB_RED] = range_limit[y + cred];
|
||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
||||
outptr1 += RGB_PIXELSIZE;
|
||||
}
|
||||
/* If image width is odd, do the last output column separately */
|
||||
if (cinfo->output_width & 1) {
|
||||
cb = GETJSAMPLE(*inptr1);
|
||||
cr = GETJSAMPLE(*inptr2);
|
||||
cred = Crrtab[cr];
|
||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
y = GETJSAMPLE(*inptr00);
|
||||
outptr0[RGB_RED] = range_limit[y + cred];
|
||||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
||||
y = GETJSAMPLE(*inptr01);
|
||||
outptr1[RGB_RED] = range_limit[y + cred];
|
||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for merged upsampling/color conversion.
|
||||
*
|
||||
* NB: this is called under the conditions determined by use_merged_upsample()
|
||||
* in jdmaster.c. That routine MUST correspond to the actual capabilities
|
||||
* of this module; no safety checks are made here.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_merged_upsampler (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_upsample_ptr upsample;
|
||||
|
||||
upsample = (my_upsample_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_upsampler));
|
||||
cinfo->upsample = (struct jpeg_upsampler *) upsample;
|
||||
upsample->pub.start_pass = start_pass_merged_upsample;
|
||||
upsample->pub.need_context_rows = FALSE;
|
||||
|
||||
upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
|
||||
|
||||
if (cinfo->max_v_samp_factor == 2) {
|
||||
upsample->pub.upsample = merged_2v_upsample;
|
||||
upsample->upmethod = h2v2_merged_upsample;
|
||||
/* Allocate a spare row buffer */
|
||||
upsample->spare_row = (JSAMPROW)
|
||||
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
|
||||
} else {
|
||||
upsample->pub.upsample = merged_1v_upsample;
|
||||
upsample->upmethod = h2v1_merged_upsample;
|
||||
/* No spare row needed */
|
||||
upsample->spare_row = NULL;
|
||||
}
|
||||
|
||||
build_ycc_rgb_table2(cinfo);
|
||||
}
|
||||
|
||||
#endif /* UPSAMPLE_MERGING_SUPPORTED */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,290 +1,290 @@
|
||||
/*
|
||||
* jdpostct.c
|
||||
*
|
||||
* Copyright (C) 1994-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 the decompression postprocessing controller.
|
||||
* This controller manages the upsampling, color conversion, and color
|
||||
* quantization/reduction steps; specifically, it controls the buffering
|
||||
* between upsample/color conversion and color quantization/reduction.
|
||||
*
|
||||
* If no color quantization/reduction is required, then this module has no
|
||||
* work to do, and it just hands off to the upsample/color conversion code.
|
||||
* An integrated upsample/convert/quantize process would replace this module
|
||||
* entirely.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_d_post_controller pub; /* public fields */
|
||||
|
||||
/* Color quantization source buffer: this holds output data from
|
||||
* the upsample/color conversion step to be passed to the quantizer.
|
||||
* For two-pass color quantization, we need a full-image buffer;
|
||||
* for one-pass operation, a strip buffer is sufficient.
|
||||
*/
|
||||
jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */
|
||||
JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */
|
||||
JDIMENSION strip_height; /* buffer size in rows */
|
||||
/* for two-pass mode only: */
|
||||
JDIMENSION starting_row; /* row # of first row in current strip */
|
||||
JDIMENSION next_row; /* index of next row to fill/empty in strip */
|
||||
} my_post_controller;
|
||||
|
||||
typedef my_post_controller * my_post_ptr;
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(void) post_process_1pass
|
||||
JPP((j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail));
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
METHODDEF(void) post_process_prepass
|
||||
JPP((j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail));
|
||||
METHODDEF(void) post_process_2pass
|
||||
JPP((j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail));
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
|
||||
{
|
||||
my_post_ptr post = (my_post_ptr) cinfo->post;
|
||||
|
||||
switch (pass_mode) {
|
||||
case JBUF_PASS_THRU:
|
||||
if (cinfo->quantize_colors) {
|
||||
/* Single-pass processing with color quantization. */
|
||||
post->pub.post_process_data = post_process_1pass;
|
||||
/* We could be doing buffered-image output before starting a 2-pass
|
||||
* color quantization; in that case, jinit_d_post_controller did not
|
||||
* allocate a strip buffer. Use the virtual-array buffer as workspace.
|
||||
*/
|
||||
if (post->buffer == NULL) {
|
||||
post->buffer = (*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr) cinfo, post->whole_image,
|
||||
(JDIMENSION) 0, post->strip_height, TRUE);
|
||||
}
|
||||
} else {
|
||||
/* For single-pass processing without color quantization,
|
||||
* I have no work to do; just call the upsampler directly.
|
||||
*/
|
||||
post->pub.post_process_data = cinfo->upsample->upsample;
|
||||
}
|
||||
break;
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
case JBUF_SAVE_AND_PASS:
|
||||
/* First pass of 2-pass quantization */
|
||||
if (post->whole_image == NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
post->pub.post_process_data = post_process_prepass;
|
||||
break;
|
||||
case JBUF_CRANK_DEST:
|
||||
/* Second pass of 2-pass quantization */
|
||||
if (post->whole_image == NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
post->pub.post_process_data = post_process_2pass;
|
||||
break;
|
||||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
break;
|
||||
}
|
||||
post->starting_row = post->next_row = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data in the one-pass (strip buffer) case.
|
||||
* This is used for color precision reduction as well as one-pass quantization.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
post_process_1pass (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail)
|
||||
{
|
||||
my_post_ptr post = (my_post_ptr) cinfo->post;
|
||||
JDIMENSION num_rows, max_rows;
|
||||
|
||||
/* Fill the buffer, but not more than what we can dump out in one go. */
|
||||
/* Note we rely on the upsampler to detect bottom of image. */
|
||||
max_rows = out_rows_avail - *out_row_ctr;
|
||||
if (max_rows > post->strip_height)
|
||||
max_rows = post->strip_height;
|
||||
num_rows = 0;
|
||||
(*cinfo->upsample->upsample) (cinfo,
|
||||
input_buf, in_row_group_ctr, in_row_groups_avail,
|
||||
post->buffer, &num_rows, max_rows);
|
||||
/* Quantize and emit data. */
|
||||
(*cinfo->cquantize->color_quantize) (cinfo,
|
||||
post->buffer, output_buf + *out_row_ctr, (int) num_rows);
|
||||
*out_row_ctr += num_rows;
|
||||
}
|
||||
|
||||
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
|
||||
/*
|
||||
* Process some data in the first pass of 2-pass quantization.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
post_process_prepass (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION)
|
||||
{
|
||||
my_post_ptr post = (my_post_ptr) cinfo->post;
|
||||
JDIMENSION old_next_row, num_rows;
|
||||
|
||||
/* Reposition virtual buffer if at start of strip. */
|
||||
if (post->next_row == 0) {
|
||||
post->buffer = (*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr) cinfo, post->whole_image,
|
||||
post->starting_row, post->strip_height, TRUE);
|
||||
}
|
||||
|
||||
/* Upsample some data (up to a strip height's worth). */
|
||||
old_next_row = post->next_row;
|
||||
(*cinfo->upsample->upsample) (cinfo,
|
||||
input_buf, in_row_group_ctr, in_row_groups_avail,
|
||||
post->buffer, &post->next_row, post->strip_height);
|
||||
|
||||
/* Allow quantizer to scan new data. No data is emitted, */
|
||||
/* but we advance out_row_ctr so outer loop can tell when we're done. */
|
||||
if (post->next_row > old_next_row) {
|
||||
num_rows = post->next_row - old_next_row;
|
||||
(*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row,
|
||||
(JSAMPARRAY) NULL, (int) num_rows);
|
||||
*out_row_ctr += num_rows;
|
||||
}
|
||||
|
||||
/* Advance if we filled the strip. */
|
||||
if (post->next_row >= post->strip_height) {
|
||||
post->starting_row += post->strip_height;
|
||||
post->next_row = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data in the second pass of 2-pass quantization.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
post_process_2pass (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE, JDIMENSION *,
|
||||
JDIMENSION,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail)
|
||||
{
|
||||
my_post_ptr post = (my_post_ptr) cinfo->post;
|
||||
JDIMENSION num_rows, max_rows;
|
||||
|
||||
/* Reposition virtual buffer if at start of strip. */
|
||||
if (post->next_row == 0) {
|
||||
post->buffer = (*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr) cinfo, post->whole_image,
|
||||
post->starting_row, post->strip_height, FALSE);
|
||||
}
|
||||
|
||||
/* Determine number of rows to emit. */
|
||||
num_rows = post->strip_height - post->next_row; /* available in strip */
|
||||
max_rows = out_rows_avail - *out_row_ctr; /* available in output area */
|
||||
if (num_rows > max_rows)
|
||||
num_rows = max_rows;
|
||||
/* We have to check bottom of image here, can't depend on upsampler. */
|
||||
max_rows = cinfo->output_height - post->starting_row;
|
||||
if (num_rows > max_rows)
|
||||
num_rows = max_rows;
|
||||
|
||||
/* Quantize and emit data. */
|
||||
(*cinfo->cquantize->color_quantize) (cinfo,
|
||||
post->buffer + post->next_row, output_buf + *out_row_ctr,
|
||||
(int) num_rows);
|
||||
*out_row_ctr += num_rows;
|
||||
|
||||
/* Advance if we filled the strip. */
|
||||
post->next_row += num_rows;
|
||||
if (post->next_row >= post->strip_height) {
|
||||
post->starting_row += post->strip_height;
|
||||
post->next_row = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize postprocessing controller.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_post_ptr post;
|
||||
|
||||
post = (my_post_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_post_controller));
|
||||
cinfo->post = (struct jpeg_d_post_controller *) post;
|
||||
post->pub.start_pass = start_pass_dpost;
|
||||
post->whole_image = NULL; /* flag for no virtual arrays */
|
||||
post->buffer = NULL; /* flag for no strip buffer */
|
||||
|
||||
/* Create the quantization buffer, if needed */
|
||||
if (cinfo->quantize_colors) {
|
||||
/* The buffer strip height is max_v_samp_factor, which is typically
|
||||
* an efficient number of rows for upsampling to return.
|
||||
* (In the presence of output rescaling, we might want to be smarter?)
|
||||
*/
|
||||
post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
|
||||
if (need_full_buffer) {
|
||||
/* Two-pass color quantization: need full-image storage. */
|
||||
/* We round up the number of rows to a multiple of the strip height. */
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
post->whole_image = (*cinfo->mem->request_virt_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
|
||||
cinfo->output_width * cinfo->out_color_components,
|
||||
(JDIMENSION) jround_up((long) cinfo->output_height,
|
||||
(long) post->strip_height),
|
||||
post->strip_height);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
} else {
|
||||
/* One-pass color quantization: just make a strip buffer. */
|
||||
post->buffer = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
cinfo->output_width * cinfo->out_color_components,
|
||||
post->strip_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* jdpostct.c
|
||||
*
|
||||
* Copyright (C) 1994-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 the decompression postprocessing controller.
|
||||
* This controller manages the upsampling, color conversion, and color
|
||||
* quantization/reduction steps; specifically, it controls the buffering
|
||||
* between upsample/color conversion and color quantization/reduction.
|
||||
*
|
||||
* If no color quantization/reduction is required, then this module has no
|
||||
* work to do, and it just hands off to the upsample/color conversion code.
|
||||
* An integrated upsample/convert/quantize process would replace this module
|
||||
* entirely.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_d_post_controller pub; /* public fields */
|
||||
|
||||
/* Color quantization source buffer: this holds output data from
|
||||
* the upsample/color conversion step to be passed to the quantizer.
|
||||
* For two-pass color quantization, we need a full-image buffer;
|
||||
* for one-pass operation, a strip buffer is sufficient.
|
||||
*/
|
||||
jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */
|
||||
JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */
|
||||
JDIMENSION strip_height; /* buffer size in rows */
|
||||
/* for two-pass mode only: */
|
||||
JDIMENSION starting_row; /* row # of first row in current strip */
|
||||
JDIMENSION next_row; /* index of next row to fill/empty in strip */
|
||||
} my_post_controller;
|
||||
|
||||
typedef my_post_controller * my_post_ptr;
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(void) post_process_1pass
|
||||
JPP((j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail));
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
METHODDEF(void) post_process_prepass
|
||||
JPP((j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail));
|
||||
METHODDEF(void) post_process_2pass
|
||||
JPP((j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail));
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
|
||||
{
|
||||
my_post_ptr post = (my_post_ptr) cinfo->post;
|
||||
|
||||
switch (pass_mode) {
|
||||
case JBUF_PASS_THRU:
|
||||
if (cinfo->quantize_colors) {
|
||||
/* Single-pass processing with color quantization. */
|
||||
post->pub.post_process_data = post_process_1pass;
|
||||
/* We could be doing buffered-image output before starting a 2-pass
|
||||
* color quantization; in that case, jinit_d_post_controller did not
|
||||
* allocate a strip buffer. Use the virtual-array buffer as workspace.
|
||||
*/
|
||||
if (post->buffer == NULL) {
|
||||
post->buffer = (*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr) cinfo, post->whole_image,
|
||||
(JDIMENSION) 0, post->strip_height, TRUE);
|
||||
}
|
||||
} else {
|
||||
/* For single-pass processing without color quantization,
|
||||
* I have no work to do; just call the upsampler directly.
|
||||
*/
|
||||
post->pub.post_process_data = cinfo->upsample->upsample;
|
||||
}
|
||||
break;
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
case JBUF_SAVE_AND_PASS:
|
||||
/* First pass of 2-pass quantization */
|
||||
if (post->whole_image == NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
post->pub.post_process_data = post_process_prepass;
|
||||
break;
|
||||
case JBUF_CRANK_DEST:
|
||||
/* Second pass of 2-pass quantization */
|
||||
if (post->whole_image == NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
post->pub.post_process_data = post_process_2pass;
|
||||
break;
|
||||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
break;
|
||||
}
|
||||
post->starting_row = post->next_row = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data in the one-pass (strip buffer) case.
|
||||
* This is used for color precision reduction as well as one-pass quantization.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
post_process_1pass (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail)
|
||||
{
|
||||
my_post_ptr post = (my_post_ptr) cinfo->post;
|
||||
JDIMENSION num_rows, max_rows;
|
||||
|
||||
/* Fill the buffer, but not more than what we can dump out in one go. */
|
||||
/* Note we rely on the upsampler to detect bottom of image. */
|
||||
max_rows = out_rows_avail - *out_row_ctr;
|
||||
if (max_rows > post->strip_height)
|
||||
max_rows = post->strip_height;
|
||||
num_rows = 0;
|
||||
(*cinfo->upsample->upsample) (cinfo,
|
||||
input_buf, in_row_group_ctr, in_row_groups_avail,
|
||||
post->buffer, &num_rows, max_rows);
|
||||
/* Quantize and emit data. */
|
||||
(*cinfo->cquantize->color_quantize) (cinfo,
|
||||
post->buffer, output_buf + *out_row_ctr, (int) num_rows);
|
||||
*out_row_ctr += num_rows;
|
||||
}
|
||||
|
||||
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
|
||||
/*
|
||||
* Process some data in the first pass of 2-pass quantization.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
post_process_prepass (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION)
|
||||
{
|
||||
my_post_ptr post = (my_post_ptr) cinfo->post;
|
||||
JDIMENSION old_next_row, num_rows;
|
||||
|
||||
/* Reposition virtual buffer if at start of strip. */
|
||||
if (post->next_row == 0) {
|
||||
post->buffer = (*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr) cinfo, post->whole_image,
|
||||
post->starting_row, post->strip_height, TRUE);
|
||||
}
|
||||
|
||||
/* Upsample some data (up to a strip height's worth). */
|
||||
old_next_row = post->next_row;
|
||||
(*cinfo->upsample->upsample) (cinfo,
|
||||
input_buf, in_row_group_ctr, in_row_groups_avail,
|
||||
post->buffer, &post->next_row, post->strip_height);
|
||||
|
||||
/* Allow quantizer to scan new data. No data is emitted, */
|
||||
/* but we advance out_row_ctr so outer loop can tell when we're done. */
|
||||
if (post->next_row > old_next_row) {
|
||||
num_rows = post->next_row - old_next_row;
|
||||
(*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row,
|
||||
(JSAMPARRAY) NULL, (int) num_rows);
|
||||
*out_row_ctr += num_rows;
|
||||
}
|
||||
|
||||
/* Advance if we filled the strip. */
|
||||
if (post->next_row >= post->strip_height) {
|
||||
post->starting_row += post->strip_height;
|
||||
post->next_row = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process some data in the second pass of 2-pass quantization.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
post_process_2pass (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE, JDIMENSION *,
|
||||
JDIMENSION,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail)
|
||||
{
|
||||
my_post_ptr post = (my_post_ptr) cinfo->post;
|
||||
JDIMENSION num_rows, max_rows;
|
||||
|
||||
/* Reposition virtual buffer if at start of strip. */
|
||||
if (post->next_row == 0) {
|
||||
post->buffer = (*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr) cinfo, post->whole_image,
|
||||
post->starting_row, post->strip_height, FALSE);
|
||||
}
|
||||
|
||||
/* Determine number of rows to emit. */
|
||||
num_rows = post->strip_height - post->next_row; /* available in strip */
|
||||
max_rows = out_rows_avail - *out_row_ctr; /* available in output area */
|
||||
if (num_rows > max_rows)
|
||||
num_rows = max_rows;
|
||||
/* We have to check bottom of image here, can't depend on upsampler. */
|
||||
max_rows = cinfo->output_height - post->starting_row;
|
||||
if (num_rows > max_rows)
|
||||
num_rows = max_rows;
|
||||
|
||||
/* Quantize and emit data. */
|
||||
(*cinfo->cquantize->color_quantize) (cinfo,
|
||||
post->buffer + post->next_row, output_buf + *out_row_ctr,
|
||||
(int) num_rows);
|
||||
*out_row_ctr += num_rows;
|
||||
|
||||
/* Advance if we filled the strip. */
|
||||
post->next_row += num_rows;
|
||||
if (post->next_row >= post->strip_height) {
|
||||
post->starting_row += post->strip_height;
|
||||
post->next_row = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize postprocessing controller.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_post_ptr post;
|
||||
|
||||
post = (my_post_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_post_controller));
|
||||
cinfo->post = (struct jpeg_d_post_controller *) post;
|
||||
post->pub.start_pass = start_pass_dpost;
|
||||
post->whole_image = NULL; /* flag for no virtual arrays */
|
||||
post->buffer = NULL; /* flag for no strip buffer */
|
||||
|
||||
/* Create the quantization buffer, if needed */
|
||||
if (cinfo->quantize_colors) {
|
||||
/* The buffer strip height is max_v_samp_factor, which is typically
|
||||
* an efficient number of rows for upsampling to return.
|
||||
* (In the presence of output rescaling, we might want to be smarter?)
|
||||
*/
|
||||
post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
|
||||
if (need_full_buffer) {
|
||||
/* Two-pass color quantization: need full-image storage. */
|
||||
/* We round up the number of rows to a multiple of the strip height. */
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
post->whole_image = (*cinfo->mem->request_virt_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
|
||||
cinfo->output_width * cinfo->out_color_components,
|
||||
(JDIMENSION) jround_up((long) cinfo->output_height,
|
||||
(long) post->strip_height),
|
||||
post->strip_height);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
} else {
|
||||
/* One-pass color quantization: just make a strip buffer. */
|
||||
post->buffer = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
cinfo->output_width * cinfo->out_color_components,
|
||||
post->strip_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,478 +1,478 @@
|
||||
/*
|
||||
* jdsample.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 upsampling routines.
|
||||
*
|
||||
* Upsampling input data is counted in "row groups". A row group
|
||||
* is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
|
||||
* sample rows of each component. Upsampling will normally produce
|
||||
* max_v_samp_factor pixel rows from each row group (but this could vary
|
||||
* if the upsampler is applying a scale factor of its own).
|
||||
*
|
||||
* An excellent reference for image resampling is
|
||||
* Digital Image Warping, George Wolberg, 1990.
|
||||
* Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Pointer to routine to upsample a single component */
|
||||
typedef JMETHOD(void, upsample1_ptr,
|
||||
(j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
|
||||
|
||||
/* Private subobject */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_upsampler pub; /* public fields */
|
||||
|
||||
/* Color conversion buffer. When using separate upsampling and color
|
||||
* conversion steps, this buffer holds one upsampled row group until it
|
||||
* has been color converted and output.
|
||||
* Note: we do not allocate any storage for component(s) which are full-size,
|
||||
* ie do not need rescaling. The corresponding entry of color_buf[] is
|
||||
* simply set to point to the input data array, thereby avoiding copying.
|
||||
*/
|
||||
JSAMPARRAY color_buf[MAX_COMPONENTS];
|
||||
|
||||
/* Per-component upsampling method pointers */
|
||||
upsample1_ptr methods[MAX_COMPONENTS];
|
||||
|
||||
int next_row_out; /* counts rows emitted from color_buf */
|
||||
JDIMENSION rows_to_go; /* counts rows remaining in image */
|
||||
|
||||
/* Height of an input row group for each component. */
|
||||
int rowgroup_height[MAX_COMPONENTS];
|
||||
|
||||
/* These arrays save pixel expansion factors so that int_expand need not
|
||||
* recompute them each time. They are unused for other upsampling methods.
|
||||
*/
|
||||
UINT8 h_expand[MAX_COMPONENTS];
|
||||
UINT8 v_expand[MAX_COMPONENTS];
|
||||
} my_upsampler2;
|
||||
|
||||
typedef my_upsampler2 * my_upsample_ptr2;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for an upsampling pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_upsample (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_upsample_ptr2 upsample = (my_upsample_ptr2) cinfo->upsample;
|
||||
|
||||
/* Mark the conversion buffer empty */
|
||||
upsample->next_row_out = cinfo->max_v_samp_factor;
|
||||
/* Initialize total-height counter for detecting bottom of image */
|
||||
upsample->rows_to_go = cinfo->output_height;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Control routine to do upsampling (and color conversion).
|
||||
*
|
||||
* In this version we upsample each component independently.
|
||||
* We upsample one row group into the conversion buffer, then apply
|
||||
* color conversion a row at a time.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
sep_upsample (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail)
|
||||
{
|
||||
my_upsample_ptr2 upsample = (my_upsample_ptr2) cinfo->upsample;
|
||||
int ci;
|
||||
jpeg_component_info * compptr;
|
||||
JDIMENSION num_rows;
|
||||
|
||||
/* Fill the conversion buffer, if it's empty */
|
||||
if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Invoke per-component upsample method. Notice we pass a POINTER
|
||||
* to color_buf[ci], so that fullsize_upsample can change it.
|
||||
*/
|
||||
(*upsample->methods[ci]) (cinfo, compptr,
|
||||
input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
|
||||
upsample->color_buf + ci);
|
||||
}
|
||||
upsample->next_row_out = 0;
|
||||
}
|
||||
|
||||
/* Color-convert and emit rows */
|
||||
|
||||
/* How many we have in the buffer: */
|
||||
num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
|
||||
/* Not more than the distance to the end of the image. Need this test
|
||||
* in case the image height is not a multiple of max_v_samp_factor:
|
||||
*/
|
||||
if (num_rows > upsample->rows_to_go)
|
||||
num_rows = upsample->rows_to_go;
|
||||
/* And not more than what the client can accept: */
|
||||
out_rows_avail -= *out_row_ctr;
|
||||
if (num_rows > out_rows_avail)
|
||||
num_rows = out_rows_avail;
|
||||
|
||||
(*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
|
||||
(JDIMENSION) upsample->next_row_out,
|
||||
output_buf + *out_row_ctr,
|
||||
(int) num_rows);
|
||||
|
||||
/* Adjust counts */
|
||||
*out_row_ctr += num_rows;
|
||||
upsample->rows_to_go -= num_rows;
|
||||
upsample->next_row_out += num_rows;
|
||||
/* When the buffer is emptied, declare this input row group consumed */
|
||||
if (upsample->next_row_out >= cinfo->max_v_samp_factor)
|
||||
(*in_row_group_ctr)++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These are the routines invoked by sep_upsample to upsample pixel values
|
||||
* of a single component. One row group is processed per call.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* For full-size components, we just make color_buf[ci] point at the
|
||||
* input buffer, and thus avoid copying any data. Note that this is
|
||||
* safe only because sep_upsample doesn't declare the input row group
|
||||
* "consumed" until we are done color converting and emitting it.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
fullsize_upsample (j_decompress_ptr, jpeg_component_info *,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
*output_data_ptr = input_data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is a no-op version used for "uninteresting" components.
|
||||
* These components will not be referenced by color conversion.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
noop_upsample (j_decompress_ptr, jpeg_component_info *,
|
||||
JSAMPARRAY, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
*output_data_ptr = NULL; /* safety check */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This version handles any integral sampling ratios.
|
||||
* This is not used for typical JPEG files, so it need not be fast.
|
||||
* Nor, for that matter, is it particularly accurate: the algorithm is
|
||||
* simple replication of the input pixel onto the corresponding output
|
||||
* pixels. The hi-falutin sampling literature refers to this as a
|
||||
* "box filter". A box filter tends to introduce visible artifacts,
|
||||
* so if you are actually going to use 3:1 or 4:1 sampling ratios
|
||||
* you would be well advised to improve this code.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
my_upsample_ptr2 upsample = (my_upsample_ptr2) cinfo->upsample;
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr, outptr;
|
||||
JSAMPLE invalue;
|
||||
int h;
|
||||
JSAMPROW outend;
|
||||
int h_expand, v_expand;
|
||||
int inrow, outrow;
|
||||
|
||||
h_expand = upsample->h_expand[compptr->component_index];
|
||||
v_expand = upsample->v_expand[compptr->component_index];
|
||||
|
||||
inrow = outrow = 0;
|
||||
while (outrow < cinfo->max_v_samp_factor) {
|
||||
/* Generate one output row with proper horizontal expansion */
|
||||
inptr = input_data[inrow];
|
||||
outptr = output_data[outrow];
|
||||
outend = outptr + cinfo->output_width;
|
||||
while (outptr < outend) {
|
||||
invalue = *inptr++; /* don't need GETJSAMPLE() here */
|
||||
for (h = h_expand; h > 0; h--) {
|
||||
*outptr++ = invalue;
|
||||
}
|
||||
}
|
||||
/* Generate any additional output rows by duplicating the first one */
|
||||
if (v_expand > 1) {
|
||||
jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
|
||||
v_expand-1, cinfo->output_width);
|
||||
}
|
||||
inrow++;
|
||||
outrow += v_expand;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
|
||||
* It's still a box filter.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info *,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr, outptr;
|
||||
JSAMPLE invalue;
|
||||
JSAMPROW outend;
|
||||
int inrow;
|
||||
|
||||
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
|
||||
inptr = input_data[inrow];
|
||||
outptr = output_data[inrow];
|
||||
outend = outptr + cinfo->output_width;
|
||||
while (outptr < outend) {
|
||||
invalue = *inptr++; /* don't need GETJSAMPLE() here */
|
||||
*outptr++ = invalue;
|
||||
*outptr++ = invalue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
|
||||
* It's still a box filter.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info *,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr, outptr;
|
||||
JSAMPLE invalue;
|
||||
JSAMPROW outend;
|
||||
int inrow, outrow;
|
||||
|
||||
inrow = outrow = 0;
|
||||
while (outrow < cinfo->max_v_samp_factor) {
|
||||
inptr = input_data[inrow];
|
||||
outptr = output_data[outrow];
|
||||
outend = outptr + cinfo->output_width;
|
||||
while (outptr < outend) {
|
||||
invalue = *inptr++; /* don't need GETJSAMPLE() here */
|
||||
*outptr++ = invalue;
|
||||
*outptr++ = invalue;
|
||||
}
|
||||
jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
|
||||
1, cinfo->output_width);
|
||||
inrow++;
|
||||
outrow += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
|
||||
*
|
||||
* The upsampling algorithm is linear interpolation between pixel centers,
|
||||
* also known as a "triangle filter". This is a good compromise between
|
||||
* speed and visual quality. The centers of the output pixels are 1/4 and 3/4
|
||||
* of the way between input pixel centers.
|
||||
*
|
||||
* A note about the "bias" calculations: when rounding fractional values to
|
||||
* integer, we do not want to always round 0.5 up to the next integer.
|
||||
* If we did that, we'd introduce a noticeable bias towards larger values.
|
||||
* Instead, this code is arranged so that 0.5 will be rounded up or down at
|
||||
* alternate pixel locations (a simple ordered dither pattern).
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr, outptr;
|
||||
int invalue;
|
||||
JDIMENSION colctr;
|
||||
int inrow;
|
||||
|
||||
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
|
||||
inptr = input_data[inrow];
|
||||
outptr = output_data[inrow];
|
||||
/* Special case for first column */
|
||||
invalue = GETJSAMPLE(*inptr++);
|
||||
*outptr++ = (JSAMPLE) invalue;
|
||||
*outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
|
||||
|
||||
for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
|
||||
/* General case: 3/4 * nearer pixel + 1/4 * further pixel */
|
||||
invalue = GETJSAMPLE(*inptr++) * 3;
|
||||
*outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
|
||||
*outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
|
||||
}
|
||||
|
||||
/* Special case for last column */
|
||||
invalue = GETJSAMPLE(*inptr);
|
||||
*outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
|
||||
*outptr++ = (JSAMPLE) invalue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
|
||||
* Again a triangle filter; see comments for h2v1 case, above.
|
||||
*
|
||||
* It is OK for us to reference the adjacent input rows because we demanded
|
||||
* context from the main buffer controller (see initialization code).
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr0, inptr1, outptr;
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
int thiscolsum, lastcolsum, nextcolsum;
|
||||
#else
|
||||
INT32 thiscolsum, lastcolsum, nextcolsum;
|
||||
#endif
|
||||
JDIMENSION colctr;
|
||||
int inrow, outrow, v;
|
||||
|
||||
inrow = outrow = 0;
|
||||
while (outrow < cinfo->max_v_samp_factor) {
|
||||
for (v = 0; v < 2; v++) {
|
||||
/* inptr0 points to nearest input row, inptr1 points to next nearest */
|
||||
inptr0 = input_data[inrow];
|
||||
if (v == 0) /* next nearest is row above */
|
||||
inptr1 = input_data[inrow-1];
|
||||
else /* next nearest is row below */
|
||||
inptr1 = input_data[inrow+1];
|
||||
outptr = output_data[outrow++];
|
||||
|
||||
/* Special case for first column */
|
||||
thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
|
||||
lastcolsum = thiscolsum; thiscolsum = nextcolsum;
|
||||
|
||||
for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
|
||||
/* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
|
||||
/* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
|
||||
nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
|
||||
lastcolsum = thiscolsum; thiscolsum = nextcolsum;
|
||||
}
|
||||
|
||||
/* Special case for last column */
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
|
||||
}
|
||||
inrow++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for upsampling.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_upsampler (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_upsample_ptr2 upsample;
|
||||
int ci;
|
||||
jpeg_component_info * compptr;
|
||||
boolean need_buffer, do_fancy;
|
||||
int h_in_group, v_in_group, h_out_group, v_out_group;
|
||||
|
||||
upsample = (my_upsample_ptr2)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_upsampler2));
|
||||
cinfo->upsample = (struct jpeg_upsampler *) upsample;
|
||||
upsample->pub.start_pass = start_pass_upsample;
|
||||
upsample->pub.upsample = sep_upsample;
|
||||
upsample->pub.need_context_rows = FALSE; /* until we find out differently */
|
||||
|
||||
if (cinfo->CCIR601_sampling) /* this isn't supported */
|
||||
ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
|
||||
|
||||
/* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
|
||||
* so don't ask for it.
|
||||
*/
|
||||
do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
|
||||
|
||||
/* Verify we can handle the sampling factors, select per-component methods,
|
||||
* and create storage as needed.
|
||||
*/
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Compute size of an "input group" after IDCT scaling. This many samples
|
||||
* are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
|
||||
*/
|
||||
h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
|
||||
cinfo->min_DCT_scaled_size;
|
||||
v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
|
||||
cinfo->min_DCT_scaled_size;
|
||||
h_out_group = cinfo->max_h_samp_factor;
|
||||
v_out_group = cinfo->max_v_samp_factor;
|
||||
upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
|
||||
need_buffer = TRUE;
|
||||
if (! compptr->component_needed) {
|
||||
/* Don't bother to upsample an uninteresting component. */
|
||||
upsample->methods[ci] = noop_upsample;
|
||||
need_buffer = FALSE;
|
||||
} else if (h_in_group == h_out_group && v_in_group == v_out_group) {
|
||||
/* Fullsize components can be processed without any work. */
|
||||
upsample->methods[ci] = fullsize_upsample;
|
||||
need_buffer = FALSE;
|
||||
} else if (h_in_group * 2 == h_out_group &&
|
||||
v_in_group == v_out_group) {
|
||||
/* Special cases for 2h1v upsampling */
|
||||
if (do_fancy && compptr->downsampled_width > 2)
|
||||
upsample->methods[ci] = h2v1_fancy_upsample;
|
||||
else
|
||||
upsample->methods[ci] = h2v1_upsample;
|
||||
} else if (h_in_group * 2 == h_out_group &&
|
||||
v_in_group * 2 == v_out_group) {
|
||||
/* Special cases for 2h2v upsampling */
|
||||
if (do_fancy && compptr->downsampled_width > 2) {
|
||||
upsample->methods[ci] = h2v2_fancy_upsample;
|
||||
upsample->pub.need_context_rows = TRUE;
|
||||
} else
|
||||
upsample->methods[ci] = h2v2_upsample;
|
||||
} else if ((h_out_group % h_in_group) == 0 &&
|
||||
(v_out_group % v_in_group) == 0) {
|
||||
/* Generic integral-factors upsampling method */
|
||||
upsample->methods[ci] = int_upsample;
|
||||
upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
|
||||
upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
|
||||
if (need_buffer) {
|
||||
upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION) jround_up((long) cinfo->output_width,
|
||||
(long) cinfo->max_h_samp_factor),
|
||||
(JDIMENSION) cinfo->max_v_samp_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* jdsample.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 upsampling routines.
|
||||
*
|
||||
* Upsampling input data is counted in "row groups". A row group
|
||||
* is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
|
||||
* sample rows of each component. Upsampling will normally produce
|
||||
* max_v_samp_factor pixel rows from each row group (but this could vary
|
||||
* if the upsampler is applying a scale factor of its own).
|
||||
*
|
||||
* An excellent reference for image resampling is
|
||||
* Digital Image Warping, George Wolberg, 1990.
|
||||
* Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Pointer to routine to upsample a single component */
|
||||
typedef JMETHOD(void, upsample1_ptr,
|
||||
(j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
|
||||
|
||||
/* Private subobject */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_upsampler pub; /* public fields */
|
||||
|
||||
/* Color conversion buffer. When using separate upsampling and color
|
||||
* conversion steps, this buffer holds one upsampled row group until it
|
||||
* has been color converted and output.
|
||||
* Note: we do not allocate any storage for component(s) which are full-size,
|
||||
* ie do not need rescaling. The corresponding entry of color_buf[] is
|
||||
* simply set to point to the input data array, thereby avoiding copying.
|
||||
*/
|
||||
JSAMPARRAY color_buf[MAX_COMPONENTS];
|
||||
|
||||
/* Per-component upsampling method pointers */
|
||||
upsample1_ptr methods[MAX_COMPONENTS];
|
||||
|
||||
int next_row_out; /* counts rows emitted from color_buf */
|
||||
JDIMENSION rows_to_go; /* counts rows remaining in image */
|
||||
|
||||
/* Height of an input row group for each component. */
|
||||
int rowgroup_height[MAX_COMPONENTS];
|
||||
|
||||
/* These arrays save pixel expansion factors so that int_expand need not
|
||||
* recompute them each time. They are unused for other upsampling methods.
|
||||
*/
|
||||
UINT8 h_expand[MAX_COMPONENTS];
|
||||
UINT8 v_expand[MAX_COMPONENTS];
|
||||
} my_upsampler2;
|
||||
|
||||
typedef my_upsampler2 * my_upsample_ptr2;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for an upsampling pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_upsample (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_upsample_ptr2 upsample = (my_upsample_ptr2) cinfo->upsample;
|
||||
|
||||
/* Mark the conversion buffer empty */
|
||||
upsample->next_row_out = cinfo->max_v_samp_factor;
|
||||
/* Initialize total-height counter for detecting bottom of image */
|
||||
upsample->rows_to_go = cinfo->output_height;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Control routine to do upsampling (and color conversion).
|
||||
*
|
||||
* In this version we upsample each component independently.
|
||||
* We upsample one row group into the conversion buffer, then apply
|
||||
* color conversion a row at a time.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
sep_upsample (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail)
|
||||
{
|
||||
my_upsample_ptr2 upsample = (my_upsample_ptr2) cinfo->upsample;
|
||||
int ci;
|
||||
jpeg_component_info * compptr;
|
||||
JDIMENSION num_rows;
|
||||
|
||||
/* Fill the conversion buffer, if it's empty */
|
||||
if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Invoke per-component upsample method. Notice we pass a POINTER
|
||||
* to color_buf[ci], so that fullsize_upsample can change it.
|
||||
*/
|
||||
(*upsample->methods[ci]) (cinfo, compptr,
|
||||
input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
|
||||
upsample->color_buf + ci);
|
||||
}
|
||||
upsample->next_row_out = 0;
|
||||
}
|
||||
|
||||
/* Color-convert and emit rows */
|
||||
|
||||
/* How many we have in the buffer: */
|
||||
num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
|
||||
/* Not more than the distance to the end of the image. Need this test
|
||||
* in case the image height is not a multiple of max_v_samp_factor:
|
||||
*/
|
||||
if (num_rows > upsample->rows_to_go)
|
||||
num_rows = upsample->rows_to_go;
|
||||
/* And not more than what the client can accept: */
|
||||
out_rows_avail -= *out_row_ctr;
|
||||
if (num_rows > out_rows_avail)
|
||||
num_rows = out_rows_avail;
|
||||
|
||||
(*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
|
||||
(JDIMENSION) upsample->next_row_out,
|
||||
output_buf + *out_row_ctr,
|
||||
(int) num_rows);
|
||||
|
||||
/* Adjust counts */
|
||||
*out_row_ctr += num_rows;
|
||||
upsample->rows_to_go -= num_rows;
|
||||
upsample->next_row_out += num_rows;
|
||||
/* When the buffer is emptied, declare this input row group consumed */
|
||||
if (upsample->next_row_out >= cinfo->max_v_samp_factor)
|
||||
(*in_row_group_ctr)++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These are the routines invoked by sep_upsample to upsample pixel values
|
||||
* of a single component. One row group is processed per call.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* For full-size components, we just make color_buf[ci] point at the
|
||||
* input buffer, and thus avoid copying any data. Note that this is
|
||||
* safe only because sep_upsample doesn't declare the input row group
|
||||
* "consumed" until we are done color converting and emitting it.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
fullsize_upsample (j_decompress_ptr, jpeg_component_info *,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
*output_data_ptr = input_data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is a no-op version used for "uninteresting" components.
|
||||
* These components will not be referenced by color conversion.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
noop_upsample (j_decompress_ptr, jpeg_component_info *,
|
||||
JSAMPARRAY, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
*output_data_ptr = NULL; /* safety check */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This version handles any integral sampling ratios.
|
||||
* This is not used for typical JPEG files, so it need not be fast.
|
||||
* Nor, for that matter, is it particularly accurate: the algorithm is
|
||||
* simple replication of the input pixel onto the corresponding output
|
||||
* pixels. The hi-falutin sampling literature refers to this as a
|
||||
* "box filter". A box filter tends to introduce visible artifacts,
|
||||
* so if you are actually going to use 3:1 or 4:1 sampling ratios
|
||||
* you would be well advised to improve this code.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
my_upsample_ptr2 upsample = (my_upsample_ptr2) cinfo->upsample;
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr, outptr;
|
||||
JSAMPLE invalue;
|
||||
int h;
|
||||
JSAMPROW outend;
|
||||
int h_expand, v_expand;
|
||||
int inrow, outrow;
|
||||
|
||||
h_expand = upsample->h_expand[compptr->component_index];
|
||||
v_expand = upsample->v_expand[compptr->component_index];
|
||||
|
||||
inrow = outrow = 0;
|
||||
while (outrow < cinfo->max_v_samp_factor) {
|
||||
/* Generate one output row with proper horizontal expansion */
|
||||
inptr = input_data[inrow];
|
||||
outptr = output_data[outrow];
|
||||
outend = outptr + cinfo->output_width;
|
||||
while (outptr < outend) {
|
||||
invalue = *inptr++; /* don't need GETJSAMPLE() here */
|
||||
for (h = h_expand; h > 0; h--) {
|
||||
*outptr++ = invalue;
|
||||
}
|
||||
}
|
||||
/* Generate any additional output rows by duplicating the first one */
|
||||
if (v_expand > 1) {
|
||||
jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
|
||||
v_expand-1, cinfo->output_width);
|
||||
}
|
||||
inrow++;
|
||||
outrow += v_expand;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
|
||||
* It's still a box filter.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info *,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr, outptr;
|
||||
JSAMPLE invalue;
|
||||
JSAMPROW outend;
|
||||
int inrow;
|
||||
|
||||
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
|
||||
inptr = input_data[inrow];
|
||||
outptr = output_data[inrow];
|
||||
outend = outptr + cinfo->output_width;
|
||||
while (outptr < outend) {
|
||||
invalue = *inptr++; /* don't need GETJSAMPLE() here */
|
||||
*outptr++ = invalue;
|
||||
*outptr++ = invalue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
|
||||
* It's still a box filter.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info *,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr, outptr;
|
||||
JSAMPLE invalue;
|
||||
JSAMPROW outend;
|
||||
int inrow, outrow;
|
||||
|
||||
inrow = outrow = 0;
|
||||
while (outrow < cinfo->max_v_samp_factor) {
|
||||
inptr = input_data[inrow];
|
||||
outptr = output_data[outrow];
|
||||
outend = outptr + cinfo->output_width;
|
||||
while (outptr < outend) {
|
||||
invalue = *inptr++; /* don't need GETJSAMPLE() here */
|
||||
*outptr++ = invalue;
|
||||
*outptr++ = invalue;
|
||||
}
|
||||
jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
|
||||
1, cinfo->output_width);
|
||||
inrow++;
|
||||
outrow += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
|
||||
*
|
||||
* The upsampling algorithm is linear interpolation between pixel centers,
|
||||
* also known as a "triangle filter". This is a good compromise between
|
||||
* speed and visual quality. The centers of the output pixels are 1/4 and 3/4
|
||||
* of the way between input pixel centers.
|
||||
*
|
||||
* A note about the "bias" calculations: when rounding fractional values to
|
||||
* integer, we do not want to always round 0.5 up to the next integer.
|
||||
* If we did that, we'd introduce a noticeable bias towards larger values.
|
||||
* Instead, this code is arranged so that 0.5 will be rounded up or down at
|
||||
* alternate pixel locations (a simple ordered dither pattern).
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr, outptr;
|
||||
int invalue;
|
||||
JDIMENSION colctr;
|
||||
int inrow;
|
||||
|
||||
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
|
||||
inptr = input_data[inrow];
|
||||
outptr = output_data[inrow];
|
||||
/* Special case for first column */
|
||||
invalue = GETJSAMPLE(*inptr++);
|
||||
*outptr++ = (JSAMPLE) invalue;
|
||||
*outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
|
||||
|
||||
for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
|
||||
/* General case: 3/4 * nearer pixel + 1/4 * further pixel */
|
||||
invalue = GETJSAMPLE(*inptr++) * 3;
|
||||
*outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
|
||||
*outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
|
||||
}
|
||||
|
||||
/* Special case for last column */
|
||||
invalue = GETJSAMPLE(*inptr);
|
||||
*outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
|
||||
*outptr++ = (JSAMPLE) invalue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
|
||||
* Again a triangle filter; see comments for h2v1 case, above.
|
||||
*
|
||||
* It is OK for us to reference the adjacent input rows because we demanded
|
||||
* context from the main buffer controller (see initialization code).
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr0, inptr1, outptr;
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
int thiscolsum, lastcolsum, nextcolsum;
|
||||
#else
|
||||
INT32 thiscolsum, lastcolsum, nextcolsum;
|
||||
#endif
|
||||
JDIMENSION colctr;
|
||||
int inrow, outrow, v;
|
||||
|
||||
inrow = outrow = 0;
|
||||
while (outrow < cinfo->max_v_samp_factor) {
|
||||
for (v = 0; v < 2; v++) {
|
||||
/* inptr0 points to nearest input row, inptr1 points to next nearest */
|
||||
inptr0 = input_data[inrow];
|
||||
if (v == 0) /* next nearest is row above */
|
||||
inptr1 = input_data[inrow-1];
|
||||
else /* next nearest is row below */
|
||||
inptr1 = input_data[inrow+1];
|
||||
outptr = output_data[outrow++];
|
||||
|
||||
/* Special case for first column */
|
||||
thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
|
||||
lastcolsum = thiscolsum; thiscolsum = nextcolsum;
|
||||
|
||||
for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
|
||||
/* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
|
||||
/* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
|
||||
nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
|
||||
lastcolsum = thiscolsum; thiscolsum = nextcolsum;
|
||||
}
|
||||
|
||||
/* Special case for last column */
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
|
||||
}
|
||||
inrow++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for upsampling.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_upsampler (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_upsample_ptr2 upsample;
|
||||
int ci;
|
||||
jpeg_component_info * compptr;
|
||||
boolean need_buffer, do_fancy;
|
||||
int h_in_group, v_in_group, h_out_group, v_out_group;
|
||||
|
||||
upsample = (my_upsample_ptr2)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(my_upsampler2));
|
||||
cinfo->upsample = (struct jpeg_upsampler *) upsample;
|
||||
upsample->pub.start_pass = start_pass_upsample;
|
||||
upsample->pub.upsample = sep_upsample;
|
||||
upsample->pub.need_context_rows = FALSE; /* until we find out differently */
|
||||
|
||||
if (cinfo->CCIR601_sampling) /* this isn't supported */
|
||||
ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
|
||||
|
||||
/* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
|
||||
* so don't ask for it.
|
||||
*/
|
||||
do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
|
||||
|
||||
/* Verify we can handle the sampling factors, select per-component methods,
|
||||
* and create storage as needed.
|
||||
*/
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Compute size of an "input group" after IDCT scaling. This many samples
|
||||
* are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
|
||||
*/
|
||||
h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
|
||||
cinfo->min_DCT_scaled_size;
|
||||
v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
|
||||
cinfo->min_DCT_scaled_size;
|
||||
h_out_group = cinfo->max_h_samp_factor;
|
||||
v_out_group = cinfo->max_v_samp_factor;
|
||||
upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
|
||||
need_buffer = TRUE;
|
||||
if (! compptr->component_needed) {
|
||||
/* Don't bother to upsample an uninteresting component. */
|
||||
upsample->methods[ci] = noop_upsample;
|
||||
need_buffer = FALSE;
|
||||
} else if (h_in_group == h_out_group && v_in_group == v_out_group) {
|
||||
/* Fullsize components can be processed without any work. */
|
||||
upsample->methods[ci] = fullsize_upsample;
|
||||
need_buffer = FALSE;
|
||||
} else if (h_in_group * 2 == h_out_group &&
|
||||
v_in_group == v_out_group) {
|
||||
/* Special cases for 2h1v upsampling */
|
||||
if (do_fancy && compptr->downsampled_width > 2)
|
||||
upsample->methods[ci] = h2v1_fancy_upsample;
|
||||
else
|
||||
upsample->methods[ci] = h2v1_upsample;
|
||||
} else if (h_in_group * 2 == h_out_group &&
|
||||
v_in_group * 2 == v_out_group) {
|
||||
/* Special cases for 2h2v upsampling */
|
||||
if (do_fancy && compptr->downsampled_width > 2) {
|
||||
upsample->methods[ci] = h2v2_fancy_upsample;
|
||||
upsample->pub.need_context_rows = TRUE;
|
||||
} else
|
||||
upsample->methods[ci] = h2v2_upsample;
|
||||
} else if ((h_out_group % h_in_group) == 0 &&
|
||||
(v_out_group % v_in_group) == 0) {
|
||||
/* Generic integral-factors upsampling method */
|
||||
upsample->methods[ci] = int_upsample;
|
||||
upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
|
||||
upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
|
||||
if (need_buffer) {
|
||||
upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION) jround_up((long) cinfo->output_width,
|
||||
(long) cinfo->max_h_samp_factor),
|
||||
(JDIMENSION) cinfo->max_v_samp_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,143 +1,143 @@
|
||||
/*
|
||||
* jdtrans.c
|
||||
*
|
||||
* Copyright (C) 1995-1997, 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 library routines for transcoding decompression,
|
||||
* that is, reading raw DCT coefficient arrays from an input JPEG file.
|
||||
* The routines in jdapimin.c will also be needed by a transcoder.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo));
|
||||
|
||||
|
||||
/*
|
||||
* Read the coefficient arrays from a JPEG file.
|
||||
* jpeg_read_header must be completed before calling this.
|
||||
*
|
||||
* The entire image is read into a set of virtual coefficient-block arrays,
|
||||
* one per component. The return value is a pointer to the array of
|
||||
* virtual-array descriptors. These can be manipulated directly via the
|
||||
* JPEG memory manager, or handed off to jpeg_write_coefficients().
|
||||
* To release the memory occupied by the virtual arrays, call
|
||||
* jpeg_finish_decompress() when done with the data.
|
||||
*
|
||||
* An alternative usage is to simply obtain access to the coefficient arrays
|
||||
* during a buffered-image-mode decompression operation. This is allowed
|
||||
* after any jpeg_finish_output() call. The arrays can be accessed until
|
||||
* jpeg_finish_decompress() is called. (Note that any call to the library
|
||||
* may reposition the arrays, so don't rely on access_virt_barray() results
|
||||
* to stay valid across library calls.)
|
||||
*
|
||||
* Returns NULL if suspended. This case need be checked only if
|
||||
* a suspending data source is used.
|
||||
*/
|
||||
|
||||
GLOBAL(jvirt_barray_ptr *)
|
||||
jpeg_read_coefficients (j_decompress_ptr cinfo)
|
||||
{
|
||||
if (cinfo->global_state == DSTATE_READY) {
|
||||
/* First call: initialize active modules */
|
||||
transdecode_master_selection(cinfo);
|
||||
cinfo->global_state = DSTATE_RDCOEFS;
|
||||
}
|
||||
if (cinfo->global_state == DSTATE_RDCOEFS) {
|
||||
/* Absorb whole file into the coef buffer */
|
||||
for (;;) {
|
||||
int retcode;
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL)
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
/* Absorb some more input */
|
||||
retcode = (*cinfo->inputctl->consume_input) (cinfo);
|
||||
if (retcode == JPEG_SUSPENDED)
|
||||
return NULL;
|
||||
if (retcode == JPEG_REACHED_EOI)
|
||||
break;
|
||||
/* Advance progress counter if appropriate */
|
||||
if (cinfo->progress != NULL &&
|
||||
(retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
|
||||
if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
|
||||
/* startup underestimated number of scans; ratchet up one scan */
|
||||
cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Set state so that jpeg_finish_decompress does the right thing */
|
||||
cinfo->global_state = DSTATE_STOPPING;
|
||||
}
|
||||
/* At this point we should be in state DSTATE_STOPPING if being used
|
||||
* standalone, or in state DSTATE_BUFIMAGE if being invoked to get access
|
||||
* to the coefficients during a full buffered-image-mode decompression.
|
||||
*/
|
||||
if ((cinfo->global_state == DSTATE_STOPPING ||
|
||||
cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) {
|
||||
return cinfo->coef->coef_arrays;
|
||||
}
|
||||
/* Oops, improper usage */
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
return NULL; /* keep compiler happy */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Master selection of decompression modules for transcoding.
|
||||
* This substitutes for jdmaster.c's initialization of the full decompressor.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
transdecode_master_selection (j_decompress_ptr cinfo)
|
||||
{
|
||||
/* This is effectively a buffered-image operation. */
|
||||
cinfo->buffered_image = TRUE;
|
||||
|
||||
/* Entropy decoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
} else {
|
||||
if (cinfo->progressive_mode) {
|
||||
#ifdef D_PROGRESSIVE_SUPPORTED
|
||||
jinit_phuff_decoder(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else
|
||||
jinit_huff_decoder(cinfo);
|
||||
}
|
||||
|
||||
/* Always get a full-image coefficient buffer. */
|
||||
jinit_d_coef_controller(cinfo, TRUE);
|
||||
|
||||
/* We can now tell the memory manager to allocate virtual arrays. */
|
||||
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
|
||||
|
||||
/* Initialize input side of decompressor to consume first scan. */
|
||||
(*cinfo->inputctl->start_input_pass) (cinfo);
|
||||
|
||||
/* Initialize progress monitoring. */
|
||||
if (cinfo->progress != NULL) {
|
||||
int nscans;
|
||||
/* Estimate number of scans to set pass_limit. */
|
||||
if (cinfo->progressive_mode) {
|
||||
/* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
|
||||
nscans = 2 + 3 * cinfo->num_components;
|
||||
} else if (cinfo->inputctl->has_multiple_scans) {
|
||||
/* For a nonprogressive multiscan file, estimate 1 scan per component. */
|
||||
nscans = cinfo->num_components;
|
||||
} else {
|
||||
nscans = 1;
|
||||
}
|
||||
cinfo->progress->pass_counter = 0L;
|
||||
cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
|
||||
cinfo->progress->completed_passes = 0;
|
||||
cinfo->progress->total_passes = 1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* jdtrans.c
|
||||
*
|
||||
* Copyright (C) 1995-1997, 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 library routines for transcoding decompression,
|
||||
* that is, reading raw DCT coefficient arrays from an input JPEG file.
|
||||
* The routines in jdapimin.c will also be needed by a transcoder.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo));
|
||||
|
||||
|
||||
/*
|
||||
* Read the coefficient arrays from a JPEG file.
|
||||
* jpeg_read_header must be completed before calling this.
|
||||
*
|
||||
* The entire image is read into a set of virtual coefficient-block arrays,
|
||||
* one per component. The return value is a pointer to the array of
|
||||
* virtual-array descriptors. These can be manipulated directly via the
|
||||
* JPEG memory manager, or handed off to jpeg_write_coefficients().
|
||||
* To release the memory occupied by the virtual arrays, call
|
||||
* jpeg_finish_decompress() when done with the data.
|
||||
*
|
||||
* An alternative usage is to simply obtain access to the coefficient arrays
|
||||
* during a buffered-image-mode decompression operation. This is allowed
|
||||
* after any jpeg_finish_output() call. The arrays can be accessed until
|
||||
* jpeg_finish_decompress() is called. (Note that any call to the library
|
||||
* may reposition the arrays, so don't rely on access_virt_barray() results
|
||||
* to stay valid across library calls.)
|
||||
*
|
||||
* Returns NULL if suspended. This case need be checked only if
|
||||
* a suspending data source is used.
|
||||
*/
|
||||
|
||||
GLOBAL(jvirt_barray_ptr *)
|
||||
jpeg_read_coefficients (j_decompress_ptr cinfo)
|
||||
{
|
||||
if (cinfo->global_state == DSTATE_READY) {
|
||||
/* First call: initialize active modules */
|
||||
transdecode_master_selection(cinfo);
|
||||
cinfo->global_state = DSTATE_RDCOEFS;
|
||||
}
|
||||
if (cinfo->global_state == DSTATE_RDCOEFS) {
|
||||
/* Absorb whole file into the coef buffer */
|
||||
for (;;) {
|
||||
int retcode;
|
||||
/* Call progress monitor hook if present */
|
||||
if (cinfo->progress != NULL)
|
||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
||||
/* Absorb some more input */
|
||||
retcode = (*cinfo->inputctl->consume_input) (cinfo);
|
||||
if (retcode == JPEG_SUSPENDED)
|
||||
return NULL;
|
||||
if (retcode == JPEG_REACHED_EOI)
|
||||
break;
|
||||
/* Advance progress counter if appropriate */
|
||||
if (cinfo->progress != NULL &&
|
||||
(retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
|
||||
if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
|
||||
/* startup underestimated number of scans; ratchet up one scan */
|
||||
cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Set state so that jpeg_finish_decompress does the right thing */
|
||||
cinfo->global_state = DSTATE_STOPPING;
|
||||
}
|
||||
/* At this point we should be in state DSTATE_STOPPING if being used
|
||||
* standalone, or in state DSTATE_BUFIMAGE if being invoked to get access
|
||||
* to the coefficients during a full buffered-image-mode decompression.
|
||||
*/
|
||||
if ((cinfo->global_state == DSTATE_STOPPING ||
|
||||
cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) {
|
||||
return cinfo->coef->coef_arrays;
|
||||
}
|
||||
/* Oops, improper usage */
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
return NULL; /* keep compiler happy */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Master selection of decompression modules for transcoding.
|
||||
* This substitutes for jdmaster.c's initialization of the full decompressor.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
transdecode_master_selection (j_decompress_ptr cinfo)
|
||||
{
|
||||
/* This is effectively a buffered-image operation. */
|
||||
cinfo->buffered_image = TRUE;
|
||||
|
||||
/* Entropy decoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
} else {
|
||||
if (cinfo->progressive_mode) {
|
||||
#ifdef D_PROGRESSIVE_SUPPORTED
|
||||
jinit_phuff_decoder(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else
|
||||
jinit_huff_decoder(cinfo);
|
||||
}
|
||||
|
||||
/* Always get a full-image coefficient buffer. */
|
||||
jinit_d_coef_controller(cinfo, TRUE);
|
||||
|
||||
/* We can now tell the memory manager to allocate virtual arrays. */
|
||||
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
|
||||
|
||||
/* Initialize input side of decompressor to consume first scan. */
|
||||
(*cinfo->inputctl->start_input_pass) (cinfo);
|
||||
|
||||
/* Initialize progress monitoring. */
|
||||
if (cinfo->progress != NULL) {
|
||||
int nscans;
|
||||
/* Estimate number of scans to set pass_limit. */
|
||||
if (cinfo->progressive_mode) {
|
||||
/* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
|
||||
nscans = 2 + 3 * cinfo->num_components;
|
||||
} else if (cinfo->inputctl->has_multiple_scans) {
|
||||
/* For a nonprogressive multiscan file, estimate 1 scan per component. */
|
||||
nscans = cinfo->num_components;
|
||||
} else {
|
||||
nscans = 1;
|
||||
}
|
||||
cinfo->progress->pass_counter = 0L;
|
||||
cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
|
||||
cinfo->progress->completed_passes = 0;
|
||||
cinfo->progress->total_passes = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,252 +1,252 @@
|
||||
/*
|
||||
* jerror.c
|
||||
*
|
||||
* Copyright (C) 1991-1998, 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 simple error-reporting and trace-message routines.
|
||||
* These are suitable for Unix-like systems and others where writing to
|
||||
* stderr is the right thing to do. Many applications will want to replace
|
||||
* some or all of these routines.
|
||||
*
|
||||
* If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
|
||||
* you get a Windows-specific hack to display error messages in a dialog box.
|
||||
* It ain't much, but it beats dropping error messages into the bit bucket,
|
||||
* which is what happens to output to stderr under most Windows C compilers.
|
||||
*
|
||||
* These routines are used by both the compression and decompression code.
|
||||
*/
|
||||
|
||||
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jversion.h"
|
||||
#include "jerror.h"
|
||||
|
||||
#ifdef USE_WINDOWS_MESSAGEBOX
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
|
||||
#define EXIT_FAILURE 1
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Create the message string table.
|
||||
* We do this from the master message list in jerror.h by re-reading
|
||||
* jerror.h with a suitable definition for macro JMESSAGE.
|
||||
* The message table is made an external symbol just in case any applications
|
||||
* want to refer to it directly.
|
||||
*/
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jpeg_std_message_table jMsgTable
|
||||
#endif
|
||||
|
||||
#define JMESSAGE(code,string) string ,
|
||||
|
||||
const char * const jpeg_std_message_table[] = {
|
||||
#include "jerror.h"
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Error exit handler: must not return to caller.
|
||||
*
|
||||
* Applications may override this if they want to get control back after
|
||||
* an error. Typically one would longjmp somewhere instead of exiting.
|
||||
* The setjmp buffer can be made a private field within an expanded error
|
||||
* handler object. Note that the info needed to generate an error message
|
||||
* is stored in the error object, so you can generate the message now or
|
||||
* later, at your convenience.
|
||||
* You should make sure that the JPEG object is cleaned up (with jpeg_abort
|
||||
* or jpeg_destroy) at some point.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
error_exit (j_common_ptr cinfo)
|
||||
{
|
||||
/* Always display the message */
|
||||
(*cinfo->err->output_message) (cinfo);
|
||||
|
||||
/* Let the memory manager delete any temp files before we die */
|
||||
jpeg_destroy(cinfo);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Actual output of an error or trace message.
|
||||
* Applications may override this method to send JPEG messages somewhere
|
||||
* other than stderr.
|
||||
*
|
||||
* On Windows, printing to stderr is generally completely useless,
|
||||
* so we provide optional code to produce an error-dialog popup.
|
||||
* Most Windows applications will still prefer to override this routine,
|
||||
* but if they don't, it'll do something at least marginally useful.
|
||||
*
|
||||
* NOTE: to use the library in an environment that doesn't support the
|
||||
* C stdio library, you may have to delete the call to fprintf() entirely,
|
||||
* not just not use this routine.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
output_message (j_common_ptr cinfo)
|
||||
{
|
||||
char buffer[JMSG_LENGTH_MAX];
|
||||
|
||||
/* Create the message */
|
||||
(*cinfo->err->format_message) (cinfo, buffer);
|
||||
|
||||
#ifdef USE_WINDOWS_MESSAGEBOX
|
||||
/* Display it in a message dialog box */
|
||||
MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
|
||||
MB_OK | MB_ICONERROR);
|
||||
#else
|
||||
/* Send it to stderr, adding a newline */
|
||||
fprintf(stderr, "%s\n", buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Decide whether to emit a trace or warning message.
|
||||
* msg_level is one of:
|
||||
* -1: recoverable corrupt-data warning, may want to abort.
|
||||
* 0: important advisory messages (always display to user).
|
||||
* 1: first level of tracing detail.
|
||||
* 2,3,...: successively more detailed tracing messages.
|
||||
* An application might override this method if it wanted to abort on warnings
|
||||
* or change the policy about which messages to display.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
emit_message (j_common_ptr cinfo, int msg_level)
|
||||
{
|
||||
struct jpeg_error_mgr * err = cinfo->err;
|
||||
|
||||
if (msg_level < 0) {
|
||||
/* It's a warning message. Since corrupt files may generate many warnings,
|
||||
* the policy implemented here is to show only the first warning,
|
||||
* unless trace_level >= 3.
|
||||
*/
|
||||
if (err->num_warnings == 0 || err->trace_level >= 3)
|
||||
(*err->output_message) (cinfo);
|
||||
/* Always count warnings in num_warnings. */
|
||||
err->num_warnings++;
|
||||
} else {
|
||||
/* It's a trace message. Show it if trace_level >= msg_level. */
|
||||
if (err->trace_level >= msg_level)
|
||||
(*err->output_message) (cinfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Format a message string for the most recent JPEG error or message.
|
||||
* The message is stored into buffer, which should be at least JMSG_LENGTH_MAX
|
||||
* characters. Note that no '\n' character is added to the string.
|
||||
* Few applications should need to override this method.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
format_message (j_common_ptr cinfo, char * buffer)
|
||||
{
|
||||
struct jpeg_error_mgr * err = cinfo->err;
|
||||
int msg_code = err->msg_code;
|
||||
const char * msgtext = NULL;
|
||||
const char * msgptr;
|
||||
char ch;
|
||||
boolean isstring;
|
||||
|
||||
/* Look up message string in proper table */
|
||||
if (msg_code > 0 && msg_code <= err->last_jpeg_message) {
|
||||
msgtext = err->jpeg_message_table[msg_code];
|
||||
} else if (err->addon_message_table != NULL &&
|
||||
msg_code >= err->first_addon_message &&
|
||||
msg_code <= err->last_addon_message) {
|
||||
msgtext = err->addon_message_table[msg_code - err->first_addon_message];
|
||||
}
|
||||
|
||||
/* Defend against bogus message number */
|
||||
if (msgtext == NULL) {
|
||||
err->msg_parm.i[0] = msg_code;
|
||||
msgtext = err->jpeg_message_table[0];
|
||||
}
|
||||
|
||||
/* Check for string parameter, as indicated by %s in the message text */
|
||||
isstring = FALSE;
|
||||
msgptr = msgtext;
|
||||
while ((ch = *msgptr++) != '\0') {
|
||||
if (ch == '%') {
|
||||
if (*msgptr == 's') isstring = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Format the message into the passed buffer */
|
||||
if (isstring)
|
||||
sprintf(buffer, msgtext, err->msg_parm.s);
|
||||
else
|
||||
sprintf(buffer, msgtext,
|
||||
err->msg_parm.i[0], err->msg_parm.i[1],
|
||||
err->msg_parm.i[2], err->msg_parm.i[3],
|
||||
err->msg_parm.i[4], err->msg_parm.i[5],
|
||||
err->msg_parm.i[6], err->msg_parm.i[7]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reset error state variables at start of a new image.
|
||||
* This is called during compression startup to reset trace/error
|
||||
* processing to default state, without losing any application-specific
|
||||
* method pointers. An application might possibly want to override
|
||||
* this method if it has additional error processing state.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
reset_error_mgr (j_common_ptr cinfo)
|
||||
{
|
||||
cinfo->err->num_warnings = 0;
|
||||
/* trace_level is not reset since it is an application-supplied parameter */
|
||||
cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fill in the standard error-handling methods in a jpeg_error_mgr object.
|
||||
* Typical call is:
|
||||
* struct jpeg_compress_struct cinfo;
|
||||
* struct jpeg_error_mgr err;
|
||||
*
|
||||
* cinfo.err = jpeg_std_error(&err);
|
||||
* after which the application may override some of the methods.
|
||||
*/
|
||||
|
||||
GLOBAL(struct jpeg_error_mgr *)
|
||||
jpeg_std_error (struct jpeg_error_mgr * err)
|
||||
{
|
||||
err->error_exit = error_exit;
|
||||
err->emit_message = emit_message;
|
||||
err->output_message = output_message;
|
||||
err->format_message = format_message;
|
||||
err->reset_error_mgr = reset_error_mgr;
|
||||
|
||||
err->trace_level = 0; /* default = no tracing */
|
||||
err->num_warnings = 0; /* no warnings emitted yet */
|
||||
err->msg_code = 0; /* may be useful as a flag for "no error" */
|
||||
|
||||
/* Initialize message table pointers */
|
||||
err->jpeg_message_table = jpeg_std_message_table;
|
||||
err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1;
|
||||
|
||||
err->addon_message_table = NULL;
|
||||
err->first_addon_message = 0; /* for safety */
|
||||
err->last_addon_message = 0;
|
||||
|
||||
return err;
|
||||
}
|
||||
/*
|
||||
* jerror.c
|
||||
*
|
||||
* Copyright (C) 1991-1998, 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 simple error-reporting and trace-message routines.
|
||||
* These are suitable for Unix-like systems and others where writing to
|
||||
* stderr is the right thing to do. Many applications will want to replace
|
||||
* some or all of these routines.
|
||||
*
|
||||
* If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
|
||||
* you get a Windows-specific hack to display error messages in a dialog box.
|
||||
* It ain't much, but it beats dropping error messages into the bit bucket,
|
||||
* which is what happens to output to stderr under most Windows C compilers.
|
||||
*
|
||||
* These routines are used by both the compression and decompression code.
|
||||
*/
|
||||
|
||||
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jversion.h"
|
||||
#include "jerror.h"
|
||||
|
||||
#ifdef USE_WINDOWS_MESSAGEBOX
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
|
||||
#define EXIT_FAILURE 1
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Create the message string table.
|
||||
* We do this from the master message list in jerror.h by re-reading
|
||||
* jerror.h with a suitable definition for macro JMESSAGE.
|
||||
* The message table is made an external symbol just in case any applications
|
||||
* want to refer to it directly.
|
||||
*/
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jpeg_std_message_table jMsgTable
|
||||
#endif
|
||||
|
||||
#define JMESSAGE(code,string) string ,
|
||||
|
||||
const char * const jpeg_std_message_table[] = {
|
||||
#include "jerror.h"
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Error exit handler: must not return to caller.
|
||||
*
|
||||
* Applications may override this if they want to get control back after
|
||||
* an error. Typically one would longjmp somewhere instead of exiting.
|
||||
* The setjmp buffer can be made a private field within an expanded error
|
||||
* handler object. Note that the info needed to generate an error message
|
||||
* is stored in the error object, so you can generate the message now or
|
||||
* later, at your convenience.
|
||||
* You should make sure that the JPEG object is cleaned up (with jpeg_abort
|
||||
* or jpeg_destroy) at some point.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
error_exit (j_common_ptr cinfo)
|
||||
{
|
||||
/* Always display the message */
|
||||
(*cinfo->err->output_message) (cinfo);
|
||||
|
||||
/* Let the memory manager delete any temp files before we die */
|
||||
jpeg_destroy(cinfo);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Actual output of an error or trace message.
|
||||
* Applications may override this method to send JPEG messages somewhere
|
||||
* other than stderr.
|
||||
*
|
||||
* On Windows, printing to stderr is generally completely useless,
|
||||
* so we provide optional code to produce an error-dialog popup.
|
||||
* Most Windows applications will still prefer to override this routine,
|
||||
* but if they don't, it'll do something at least marginally useful.
|
||||
*
|
||||
* NOTE: to use the library in an environment that doesn't support the
|
||||
* C stdio library, you may have to delete the call to fprintf() entirely,
|
||||
* not just not use this routine.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
output_message (j_common_ptr cinfo)
|
||||
{
|
||||
char buffer[JMSG_LENGTH_MAX];
|
||||
|
||||
/* Create the message */
|
||||
(*cinfo->err->format_message) (cinfo, buffer);
|
||||
|
||||
#ifdef USE_WINDOWS_MESSAGEBOX
|
||||
/* Display it in a message dialog box */
|
||||
MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
|
||||
MB_OK | MB_ICONERROR);
|
||||
#else
|
||||
/* Send it to stderr, adding a newline */
|
||||
fprintf(stderr, "%s\n", buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Decide whether to emit a trace or warning message.
|
||||
* msg_level is one of:
|
||||
* -1: recoverable corrupt-data warning, may want to abort.
|
||||
* 0: important advisory messages (always display to user).
|
||||
* 1: first level of tracing detail.
|
||||
* 2,3,...: successively more detailed tracing messages.
|
||||
* An application might override this method if it wanted to abort on warnings
|
||||
* or change the policy about which messages to display.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
emit_message (j_common_ptr cinfo, int msg_level)
|
||||
{
|
||||
struct jpeg_error_mgr * err = cinfo->err;
|
||||
|
||||
if (msg_level < 0) {
|
||||
/* It's a warning message. Since corrupt files may generate many warnings,
|
||||
* the policy implemented here is to show only the first warning,
|
||||
* unless trace_level >= 3.
|
||||
*/
|
||||
if (err->num_warnings == 0 || err->trace_level >= 3)
|
||||
(*err->output_message) (cinfo);
|
||||
/* Always count warnings in num_warnings. */
|
||||
err->num_warnings++;
|
||||
} else {
|
||||
/* It's a trace message. Show it if trace_level >= msg_level. */
|
||||
if (err->trace_level >= msg_level)
|
||||
(*err->output_message) (cinfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Format a message string for the most recent JPEG error or message.
|
||||
* The message is stored into buffer, which should be at least JMSG_LENGTH_MAX
|
||||
* characters. Note that no '\n' character is added to the string.
|
||||
* Few applications should need to override this method.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
format_message (j_common_ptr cinfo, char * buffer)
|
||||
{
|
||||
struct jpeg_error_mgr * err = cinfo->err;
|
||||
int msg_code = err->msg_code;
|
||||
const char * msgtext = NULL;
|
||||
const char * msgptr;
|
||||
char ch;
|
||||
boolean isstring;
|
||||
|
||||
/* Look up message string in proper table */
|
||||
if (msg_code > 0 && msg_code <= err->last_jpeg_message) {
|
||||
msgtext = err->jpeg_message_table[msg_code];
|
||||
} else if (err->addon_message_table != NULL &&
|
||||
msg_code >= err->first_addon_message &&
|
||||
msg_code <= err->last_addon_message) {
|
||||
msgtext = err->addon_message_table[msg_code - err->first_addon_message];
|
||||
}
|
||||
|
||||
/* Defend against bogus message number */
|
||||
if (msgtext == NULL) {
|
||||
err->msg_parm.i[0] = msg_code;
|
||||
msgtext = err->jpeg_message_table[0];
|
||||
}
|
||||
|
||||
/* Check for string parameter, as indicated by %s in the message text */
|
||||
isstring = FALSE;
|
||||
msgptr = msgtext;
|
||||
while ((ch = *msgptr++) != '\0') {
|
||||
if (ch == '%') {
|
||||
if (*msgptr == 's') isstring = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Format the message into the passed buffer */
|
||||
if (isstring)
|
||||
sprintf(buffer, msgtext, err->msg_parm.s);
|
||||
else
|
||||
sprintf(buffer, msgtext,
|
||||
err->msg_parm.i[0], err->msg_parm.i[1],
|
||||
err->msg_parm.i[2], err->msg_parm.i[3],
|
||||
err->msg_parm.i[4], err->msg_parm.i[5],
|
||||
err->msg_parm.i[6], err->msg_parm.i[7]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reset error state variables at start of a new image.
|
||||
* This is called during compression startup to reset trace/error
|
||||
* processing to default state, without losing any application-specific
|
||||
* method pointers. An application might possibly want to override
|
||||
* this method if it has additional error processing state.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
reset_error_mgr (j_common_ptr cinfo)
|
||||
{
|
||||
cinfo->err->num_warnings = 0;
|
||||
/* trace_level is not reset since it is an application-supplied parameter */
|
||||
cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fill in the standard error-handling methods in a jpeg_error_mgr object.
|
||||
* Typical call is:
|
||||
* struct jpeg_compress_struct cinfo;
|
||||
* struct jpeg_error_mgr err;
|
||||
*
|
||||
* cinfo.err = jpeg_std_error(&err);
|
||||
* after which the application may override some of the methods.
|
||||
*/
|
||||
|
||||
GLOBAL(struct jpeg_error_mgr *)
|
||||
jpeg_std_error (struct jpeg_error_mgr * err)
|
||||
{
|
||||
err->error_exit = error_exit;
|
||||
err->emit_message = emit_message;
|
||||
err->output_message = output_message;
|
||||
err->format_message = format_message;
|
||||
err->reset_error_mgr = reset_error_mgr;
|
||||
|
||||
err->trace_level = 0; /* default = no tracing */
|
||||
err->num_warnings = 0; /* no warnings emitted yet */
|
||||
err->msg_code = 0; /* may be useful as a flag for "no error" */
|
||||
|
||||
/* Initialize message table pointers */
|
||||
err->jpeg_message_table = jpeg_std_message_table;
|
||||
err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1;
|
||||
|
||||
err->addon_message_table = NULL;
|
||||
err->first_addon_message = 0; /* for safety */
|
||||
err->last_addon_message = 0;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -1,291 +1,291 @@
|
||||
/*
|
||||
* jerror.h
|
||||
*
|
||||
* Copyright (C) 1994-1997, 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 defines the error and message codes for the JPEG library.
|
||||
* Edit this file to add new codes, or to translate the message strings to
|
||||
* some other language.
|
||||
* A set of error-reporting macros are defined too. Some applications using
|
||||
* the JPEG library may wish to include this file to get the error codes
|
||||
* and/or the macros.
|
||||
*/
|
||||
|
||||
/*
|
||||
* To define the enum list of message codes, include this file without
|
||||
* defining macro JMESSAGE. To create a message string table, include it
|
||||
* again with a suitable JMESSAGE definition (see jerror.c for an example).
|
||||
*/
|
||||
#ifndef JMESSAGE
|
||||
#ifndef JERROR_H
|
||||
/* First time through, define the enum list */
|
||||
#define JMAKE_ENUM_LIST
|
||||
#else
|
||||
/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
|
||||
#define JMESSAGE(code,string)
|
||||
#endif /* JERROR_H */
|
||||
#endif /* JMESSAGE */
|
||||
|
||||
#ifdef JMAKE_ENUM_LIST
|
||||
|
||||
typedef enum {
|
||||
|
||||
#define JMESSAGE(code,string) code ,
|
||||
|
||||
#endif /* JMAKE_ENUM_LIST */
|
||||
|
||||
JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
|
||||
|
||||
/* For maintenance convenience, list is alphabetical by message code name */
|
||||
JMESSAGE(JERR_ARITH_NOTIMPL,
|
||||
"Sorry, there are legal restrictions on arithmetic coding")
|
||||
JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
|
||||
JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
|
||||
JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
|
||||
JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
|
||||
JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
|
||||
JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
|
||||
JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
|
||||
JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
|
||||
JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
|
||||
JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
|
||||
JMESSAGE(JERR_BAD_LIB_VERSION,
|
||||
"Wrong JPEG library version: library is %d, caller expects %d")
|
||||
JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
|
||||
JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
|
||||
JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
|
||||
JMESSAGE(JERR_BAD_PROGRESSION,
|
||||
"Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
|
||||
JMESSAGE(JERR_BAD_PROG_SCRIPT,
|
||||
"Invalid progressive parameters at scan script entry %d")
|
||||
JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
|
||||
JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
|
||||
JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
|
||||
JMESSAGE(JERR_BAD_STRUCT_SIZE,
|
||||
"JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
|
||||
JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
|
||||
JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
|
||||
JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
|
||||
JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
|
||||
JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
|
||||
JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
|
||||
JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
|
||||
JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
|
||||
JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
|
||||
JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
|
||||
JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
|
||||
JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
|
||||
JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
|
||||
JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
|
||||
JMESSAGE(JERR_FILE_READ, "Input file read error")
|
||||
JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
|
||||
JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
|
||||
JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
|
||||
JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
|
||||
JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
|
||||
JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
|
||||
JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
|
||||
JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
|
||||
"Cannot transcode due to multiple use of quantization table %d")
|
||||
JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
|
||||
JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
|
||||
JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
|
||||
JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
|
||||
JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
|
||||
JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
|
||||
JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
|
||||
JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")
|
||||
JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
|
||||
JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
|
||||
JMESSAGE(JERR_QUANT_COMPONENTS,
|
||||
"Cannot quantize more than %d color components")
|
||||
JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
|
||||
JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
|
||||
JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
|
||||
JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
|
||||
JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
|
||||
JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
|
||||
JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
|
||||
JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
|
||||
JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
|
||||
JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
|
||||
JMESSAGE(JERR_TFILE_WRITE,
|
||||
"Write failed on temporary file --- out of disk space?")
|
||||
JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
|
||||
JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
|
||||
JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
|
||||
JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
|
||||
JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
|
||||
JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
|
||||
JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
|
||||
JMESSAGE(JMSG_VERSION, JVERSION)
|
||||
JMESSAGE(JTRC_16BIT_TABLES,
|
||||
"Caution: quantization tables are too coarse for baseline JPEG")
|
||||
JMESSAGE(JTRC_ADOBE,
|
||||
"Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
|
||||
JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
|
||||
JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
|
||||
JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
|
||||
JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
|
||||
JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d")
|
||||
JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
|
||||
JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
|
||||
JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
|
||||
JMESSAGE(JTRC_EOI, "End Of Image")
|
||||
JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d")
|
||||
JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d")
|
||||
JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
|
||||
"Warning: thumbnail image size does not match data length %u")
|
||||
JMESSAGE(JTRC_JFIF_EXTENSION,
|
||||
"JFIF extension marker: type 0x%02x, length %u")
|
||||
JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image")
|
||||
JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
|
||||
JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
|
||||
JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u")
|
||||
JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
|
||||
JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors")
|
||||
JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization")
|
||||
JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
|
||||
JMESSAGE(JTRC_RST, "RST%d")
|
||||
JMESSAGE(JTRC_SMOOTH_NOTIMPL,
|
||||
"Smoothing not supported with nonstandard sampling ratios")
|
||||
JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
|
||||
JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d")
|
||||
JMESSAGE(JTRC_SOI, "Start of Image")
|
||||
JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
|
||||
JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d")
|
||||
JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d")
|
||||
JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
|
||||
JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
|
||||
JMESSAGE(JTRC_THUMB_JPEG,
|
||||
"JFIF extension marker: JPEG-compressed thumbnail image, length %u")
|
||||
JMESSAGE(JTRC_THUMB_PALETTE,
|
||||
"JFIF extension marker: palette thumbnail image, length %u")
|
||||
JMESSAGE(JTRC_THUMB_RGB,
|
||||
"JFIF extension marker: RGB thumbnail image, length %u")
|
||||
JMESSAGE(JTRC_UNKNOWN_IDS,
|
||||
"Unrecognized component IDs %d %d %d, assuming YCbCr")
|
||||
JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
|
||||
JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
|
||||
JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
|
||||
JMESSAGE(JWRN_BOGUS_PROGRESSION,
|
||||
"Inconsistent progression sequence for component %d coefficient %d")
|
||||
JMESSAGE(JWRN_EXTRANEOUS_DATA,
|
||||
"Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
|
||||
JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
|
||||
JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
|
||||
JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
|
||||
JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
|
||||
JMESSAGE(JWRN_MUST_RESYNC,
|
||||
"Corrupt JPEG data: found marker 0x%02x instead of RST%d")
|
||||
JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
|
||||
JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
|
||||
|
||||
#ifdef JMAKE_ENUM_LIST
|
||||
|
||||
JMSG_LASTMSGCODE
|
||||
} J_MESSAGE_CODE;
|
||||
|
||||
#undef JMAKE_ENUM_LIST
|
||||
#endif /* JMAKE_ENUM_LIST */
|
||||
|
||||
/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
|
||||
#undef JMESSAGE
|
||||
|
||||
|
||||
#ifndef JERROR_H
|
||||
#define JERROR_H
|
||||
|
||||
/* Macros to simplify using the error and trace message stuff */
|
||||
/* The first parameter is either type of cinfo pointer */
|
||||
|
||||
/* Fatal errors (print message and exit) */
|
||||
#define ERREXIT(cinfo,code) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
#define ERREXIT1(cinfo,code,p1) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
#define ERREXIT2(cinfo,code,p1,p2) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
#define ERREXIT3(cinfo,code,p1,p2,p3) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
||||
(cinfo)->err->msg_parm.i[2] = (p3), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
||||
(cinfo)->err->msg_parm.i[2] = (p3), \
|
||||
(cinfo)->err->msg_parm.i[3] = (p4), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
#define ERREXITS(cinfo,code,str) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
|
||||
#define MAKESTMT(stuff) do { stuff } while (0)
|
||||
|
||||
/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
|
||||
#define WARNMS(cinfo,code) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
|
||||
#define WARNMS1(cinfo,code,p1) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
|
||||
#define WARNMS2(cinfo,code,p1,p2) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
|
||||
|
||||
/* Informational/debugging messages */
|
||||
#define TRACEMS(cinfo,lvl,code) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
||||
#define TRACEMS1(cinfo,lvl,code,p1) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
||||
#define TRACEMS2(cinfo,lvl,code,p1,p2) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
||||
#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \
|
||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
|
||||
(cinfo)->err->msg_code = (code); \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
||||
#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \
|
||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
||||
(cinfo)->err->msg_code = (code); \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
||||
#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \
|
||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
||||
_mp[4] = (p5); \
|
||||
(cinfo)->err->msg_code = (code); \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
||||
#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \
|
||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
||||
_mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
|
||||
(cinfo)->err->msg_code = (code); \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
||||
#define TRACEMSS(cinfo,lvl,code,str) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
||||
|
||||
#endif /* JERROR_H */
|
||||
/*
|
||||
* jerror.h
|
||||
*
|
||||
* Copyright (C) 1994-1997, 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 defines the error and message codes for the JPEG library.
|
||||
* Edit this file to add new codes, or to translate the message strings to
|
||||
* some other language.
|
||||
* A set of error-reporting macros are defined too. Some applications using
|
||||
* the JPEG library may wish to include this file to get the error codes
|
||||
* and/or the macros.
|
||||
*/
|
||||
|
||||
/*
|
||||
* To define the enum list of message codes, include this file without
|
||||
* defining macro JMESSAGE. To create a message string table, include it
|
||||
* again with a suitable JMESSAGE definition (see jerror.c for an example).
|
||||
*/
|
||||
#ifndef JMESSAGE
|
||||
#ifndef JERROR_H
|
||||
/* First time through, define the enum list */
|
||||
#define JMAKE_ENUM_LIST
|
||||
#else
|
||||
/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
|
||||
#define JMESSAGE(code,string)
|
||||
#endif /* JERROR_H */
|
||||
#endif /* JMESSAGE */
|
||||
|
||||
#ifdef JMAKE_ENUM_LIST
|
||||
|
||||
typedef enum {
|
||||
|
||||
#define JMESSAGE(code,string) code ,
|
||||
|
||||
#endif /* JMAKE_ENUM_LIST */
|
||||
|
||||
JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
|
||||
|
||||
/* For maintenance convenience, list is alphabetical by message code name */
|
||||
JMESSAGE(JERR_ARITH_NOTIMPL,
|
||||
"Sorry, there are legal restrictions on arithmetic coding")
|
||||
JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
|
||||
JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
|
||||
JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
|
||||
JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
|
||||
JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
|
||||
JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
|
||||
JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
|
||||
JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
|
||||
JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
|
||||
JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
|
||||
JMESSAGE(JERR_BAD_LIB_VERSION,
|
||||
"Wrong JPEG library version: library is %d, caller expects %d")
|
||||
JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
|
||||
JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
|
||||
JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
|
||||
JMESSAGE(JERR_BAD_PROGRESSION,
|
||||
"Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
|
||||
JMESSAGE(JERR_BAD_PROG_SCRIPT,
|
||||
"Invalid progressive parameters at scan script entry %d")
|
||||
JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
|
||||
JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
|
||||
JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
|
||||
JMESSAGE(JERR_BAD_STRUCT_SIZE,
|
||||
"JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
|
||||
JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
|
||||
JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
|
||||
JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
|
||||
JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
|
||||
JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
|
||||
JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
|
||||
JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
|
||||
JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
|
||||
JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
|
||||
JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
|
||||
JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
|
||||
JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
|
||||
JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
|
||||
JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
|
||||
JMESSAGE(JERR_FILE_READ, "Input file read error")
|
||||
JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
|
||||
JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
|
||||
JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
|
||||
JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
|
||||
JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
|
||||
JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
|
||||
JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
|
||||
JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
|
||||
"Cannot transcode due to multiple use of quantization table %d")
|
||||
JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
|
||||
JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
|
||||
JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
|
||||
JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
|
||||
JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
|
||||
JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
|
||||
JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
|
||||
JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")
|
||||
JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
|
||||
JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
|
||||
JMESSAGE(JERR_QUANT_COMPONENTS,
|
||||
"Cannot quantize more than %d color components")
|
||||
JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
|
||||
JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
|
||||
JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
|
||||
JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
|
||||
JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
|
||||
JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
|
||||
JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
|
||||
JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
|
||||
JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
|
||||
JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
|
||||
JMESSAGE(JERR_TFILE_WRITE,
|
||||
"Write failed on temporary file --- out of disk space?")
|
||||
JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
|
||||
JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
|
||||
JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
|
||||
JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
|
||||
JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
|
||||
JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
|
||||
JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
|
||||
JMESSAGE(JMSG_VERSION, JVERSION)
|
||||
JMESSAGE(JTRC_16BIT_TABLES,
|
||||
"Caution: quantization tables are too coarse for baseline JPEG")
|
||||
JMESSAGE(JTRC_ADOBE,
|
||||
"Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
|
||||
JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
|
||||
JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
|
||||
JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
|
||||
JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
|
||||
JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d")
|
||||
JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
|
||||
JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
|
||||
JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
|
||||
JMESSAGE(JTRC_EOI, "End Of Image")
|
||||
JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d")
|
||||
JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d")
|
||||
JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
|
||||
"Warning: thumbnail image size does not match data length %u")
|
||||
JMESSAGE(JTRC_JFIF_EXTENSION,
|
||||
"JFIF extension marker: type 0x%02x, length %u")
|
||||
JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image")
|
||||
JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
|
||||
JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
|
||||
JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u")
|
||||
JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
|
||||
JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors")
|
||||
JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization")
|
||||
JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
|
||||
JMESSAGE(JTRC_RST, "RST%d")
|
||||
JMESSAGE(JTRC_SMOOTH_NOTIMPL,
|
||||
"Smoothing not supported with nonstandard sampling ratios")
|
||||
JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
|
||||
JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d")
|
||||
JMESSAGE(JTRC_SOI, "Start of Image")
|
||||
JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
|
||||
JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d")
|
||||
JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d")
|
||||
JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
|
||||
JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
|
||||
JMESSAGE(JTRC_THUMB_JPEG,
|
||||
"JFIF extension marker: JPEG-compressed thumbnail image, length %u")
|
||||
JMESSAGE(JTRC_THUMB_PALETTE,
|
||||
"JFIF extension marker: palette thumbnail image, length %u")
|
||||
JMESSAGE(JTRC_THUMB_RGB,
|
||||
"JFIF extension marker: RGB thumbnail image, length %u")
|
||||
JMESSAGE(JTRC_UNKNOWN_IDS,
|
||||
"Unrecognized component IDs %d %d %d, assuming YCbCr")
|
||||
JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
|
||||
JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
|
||||
JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
|
||||
JMESSAGE(JWRN_BOGUS_PROGRESSION,
|
||||
"Inconsistent progression sequence for component %d coefficient %d")
|
||||
JMESSAGE(JWRN_EXTRANEOUS_DATA,
|
||||
"Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
|
||||
JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
|
||||
JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
|
||||
JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
|
||||
JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
|
||||
JMESSAGE(JWRN_MUST_RESYNC,
|
||||
"Corrupt JPEG data: found marker 0x%02x instead of RST%d")
|
||||
JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
|
||||
JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
|
||||
|
||||
#ifdef JMAKE_ENUM_LIST
|
||||
|
||||
JMSG_LASTMSGCODE
|
||||
} J_MESSAGE_CODE;
|
||||
|
||||
#undef JMAKE_ENUM_LIST
|
||||
#endif /* JMAKE_ENUM_LIST */
|
||||
|
||||
/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
|
||||
#undef JMESSAGE
|
||||
|
||||
|
||||
#ifndef JERROR_H
|
||||
#define JERROR_H
|
||||
|
||||
/* Macros to simplify using the error and trace message stuff */
|
||||
/* The first parameter is either type of cinfo pointer */
|
||||
|
||||
/* Fatal errors (print message and exit) */
|
||||
#define ERREXIT(cinfo,code) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
#define ERREXIT1(cinfo,code,p1) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
#define ERREXIT2(cinfo,code,p1,p2) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
#define ERREXIT3(cinfo,code,p1,p2,p3) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
||||
(cinfo)->err->msg_parm.i[2] = (p3), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
||||
(cinfo)->err->msg_parm.i[2] = (p3), \
|
||||
(cinfo)->err->msg_parm.i[3] = (p4), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
#define ERREXITS(cinfo,code,str) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
|
||||
#define MAKESTMT(stuff) do { stuff } while (0)
|
||||
|
||||
/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
|
||||
#define WARNMS(cinfo,code) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
|
||||
#define WARNMS1(cinfo,code,p1) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
|
||||
#define WARNMS2(cinfo,code,p1,p2) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
|
||||
|
||||
/* Informational/debugging messages */
|
||||
#define TRACEMS(cinfo,lvl,code) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
||||
#define TRACEMS1(cinfo,lvl,code,p1) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
||||
#define TRACEMS2(cinfo,lvl,code,p1,p2) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
||||
#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \
|
||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
|
||||
(cinfo)->err->msg_code = (code); \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
||||
#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \
|
||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
||||
(cinfo)->err->msg_code = (code); \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
||||
#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \
|
||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
||||
_mp[4] = (p5); \
|
||||
(cinfo)->err->msg_code = (code); \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
||||
#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \
|
||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
||||
_mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
|
||||
(cinfo)->err->msg_code = (code); \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
||||
#define TRACEMSS(cinfo,lvl,code,str) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
|
||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
||||
|
||||
#endif /* JERROR_H */
|
||||
|
@ -1,168 +1,168 @@
|
||||
/*
|
||||
* jfdctflt.c
|
||||
*
|
||||
* Copyright (C) 1994-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 a floating-point implementation of the
|
||||
* forward DCT (Discrete Cosine Transform).
|
||||
*
|
||||
* This implementation should be more accurate than either of the integer
|
||||
* DCT implementations. However, it may not give the same results on all
|
||||
* machines because of differences in roundoff behavior. Speed will depend
|
||||
* on the hardware's floating point capacity.
|
||||
*
|
||||
* A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
|
||||
* on each column. Direct algorithms are also available, but they are
|
||||
* much more complex and seem not to be any faster when reduced to code.
|
||||
*
|
||||
* This implementation is based on Arai, Agui, and Nakajima's algorithm for
|
||||
* scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
|
||||
* Japanese, but the algorithm is described in the Pennebaker & Mitchell
|
||||
* JPEG textbook (see REFERENCES section in file README). The following code
|
||||
* is based directly on figure 4-8 in P&M.
|
||||
* While an 8-point DCT cannot be done in less than 11 multiplies, it is
|
||||
* possible to arrange the computation so that many of the multiplies are
|
||||
* simple scalings of the final outputs. These multiplies can then be
|
||||
* folded into the multiplications or divisions by the JPEG quantization
|
||||
* table entries. The AA&N method leaves only 5 multiplies and 29 adds
|
||||
* to be done in the DCT itself.
|
||||
* The primary disadvantage of this method is that with a fixed-point
|
||||
* implementation, accuracy is lost due to imprecise representation of the
|
||||
* scaled quantization values. However, that problem does not arise if
|
||||
* we use floating point arithmetic.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Perform the forward DCT on one block of samples.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_fdct_float (FAST_FLOAT * data)
|
||||
{
|
||||
FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
|
||||
FAST_FLOAT z1, z2, z3, z4, z5, z11, z13;
|
||||
FAST_FLOAT *dataptr;
|
||||
int ctr;
|
||||
|
||||
/* Pass 1: process rows. */
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[0] + dataptr[7];
|
||||
tmp7 = dataptr[0] - dataptr[7];
|
||||
tmp1 = dataptr[1] + dataptr[6];
|
||||
tmp6 = dataptr[1] - dataptr[6];
|
||||
tmp2 = dataptr[2] + dataptr[5];
|
||||
tmp5 = dataptr[2] - dataptr[5];
|
||||
tmp3 = dataptr[3] + dataptr[4];
|
||||
tmp4 = dataptr[3] - dataptr[4];
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = tmp0 + tmp3; /* phase 2 */
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[0] = tmp10 + tmp11; /* phase 3 */
|
||||
dataptr[4] = tmp10 - tmp11;
|
||||
|
||||
z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
|
||||
dataptr[2] = tmp13 + z1; /* phase 5 */
|
||||
dataptr[6] = tmp13 - z1;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp10 = tmp4 + tmp5; /* phase 2 */
|
||||
tmp11 = tmp5 + tmp6;
|
||||
tmp12 = tmp6 + tmp7;
|
||||
|
||||
/* The rotator is modified from fig 4-8 to avoid extra negations. */
|
||||
z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
|
||||
z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
|
||||
z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
|
||||
z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
|
||||
|
||||
z11 = tmp7 + z3; /* phase 5 */
|
||||
z13 = tmp7 - z3;
|
||||
|
||||
dataptr[5] = z13 + z2; /* phase 6 */
|
||||
dataptr[3] = z13 - z2;
|
||||
dataptr[1] = z11 + z4;
|
||||
dataptr[7] = z11 - z4;
|
||||
|
||||
dataptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
|
||||
/* Pass 2: process columns. */
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
|
||||
tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
|
||||
tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
|
||||
tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
|
||||
tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
|
||||
tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
|
||||
tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
|
||||
tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = tmp0 + tmp3; /* phase 2 */
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
|
||||
dataptr[DCTSIZE*4] = tmp10 - tmp11;
|
||||
|
||||
z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
|
||||
dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
|
||||
dataptr[DCTSIZE*6] = tmp13 - z1;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp10 = tmp4 + tmp5; /* phase 2 */
|
||||
tmp11 = tmp5 + tmp6;
|
||||
tmp12 = tmp6 + tmp7;
|
||||
|
||||
/* The rotator is modified from fig 4-8 to avoid extra negations. */
|
||||
z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
|
||||
z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
|
||||
z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
|
||||
z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
|
||||
|
||||
z11 = tmp7 + z3; /* phase 5 */
|
||||
z13 = tmp7 - z3;
|
||||
|
||||
dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
|
||||
dataptr[DCTSIZE*3] = z13 - z2;
|
||||
dataptr[DCTSIZE*1] = z11 + z4;
|
||||
dataptr[DCTSIZE*7] = z11 - z4;
|
||||
|
||||
dataptr++; /* advance pointer to next column */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_FLOAT_SUPPORTED */
|
||||
/*
|
||||
* jfdctflt.c
|
||||
*
|
||||
* Copyright (C) 1994-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 a floating-point implementation of the
|
||||
* forward DCT (Discrete Cosine Transform).
|
||||
*
|
||||
* This implementation should be more accurate than either of the integer
|
||||
* DCT implementations. However, it may not give the same results on all
|
||||
* machines because of differences in roundoff behavior. Speed will depend
|
||||
* on the hardware's floating point capacity.
|
||||
*
|
||||
* A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
|
||||
* on each column. Direct algorithms are also available, but they are
|
||||
* much more complex and seem not to be any faster when reduced to code.
|
||||
*
|
||||
* This implementation is based on Arai, Agui, and Nakajima's algorithm for
|
||||
* scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
|
||||
* Japanese, but the algorithm is described in the Pennebaker & Mitchell
|
||||
* JPEG textbook (see REFERENCES section in file README). The following code
|
||||
* is based directly on figure 4-8 in P&M.
|
||||
* While an 8-point DCT cannot be done in less than 11 multiplies, it is
|
||||
* possible to arrange the computation so that many of the multiplies are
|
||||
* simple scalings of the final outputs. These multiplies can then be
|
||||
* folded into the multiplications or divisions by the JPEG quantization
|
||||
* table entries. The AA&N method leaves only 5 multiplies and 29 adds
|
||||
* to be done in the DCT itself.
|
||||
* The primary disadvantage of this method is that with a fixed-point
|
||||
* implementation, accuracy is lost due to imprecise representation of the
|
||||
* scaled quantization values. However, that problem does not arise if
|
||||
* we use floating point arithmetic.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Perform the forward DCT on one block of samples.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_fdct_float (FAST_FLOAT * data)
|
||||
{
|
||||
FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
|
||||
FAST_FLOAT z1, z2, z3, z4, z5, z11, z13;
|
||||
FAST_FLOAT *dataptr;
|
||||
int ctr;
|
||||
|
||||
/* Pass 1: process rows. */
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[0] + dataptr[7];
|
||||
tmp7 = dataptr[0] - dataptr[7];
|
||||
tmp1 = dataptr[1] + dataptr[6];
|
||||
tmp6 = dataptr[1] - dataptr[6];
|
||||
tmp2 = dataptr[2] + dataptr[5];
|
||||
tmp5 = dataptr[2] - dataptr[5];
|
||||
tmp3 = dataptr[3] + dataptr[4];
|
||||
tmp4 = dataptr[3] - dataptr[4];
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = tmp0 + tmp3; /* phase 2 */
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[0] = tmp10 + tmp11; /* phase 3 */
|
||||
dataptr[4] = tmp10 - tmp11;
|
||||
|
||||
z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
|
||||
dataptr[2] = tmp13 + z1; /* phase 5 */
|
||||
dataptr[6] = tmp13 - z1;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp10 = tmp4 + tmp5; /* phase 2 */
|
||||
tmp11 = tmp5 + tmp6;
|
||||
tmp12 = tmp6 + tmp7;
|
||||
|
||||
/* The rotator is modified from fig 4-8 to avoid extra negations. */
|
||||
z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
|
||||
z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
|
||||
z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
|
||||
z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
|
||||
|
||||
z11 = tmp7 + z3; /* phase 5 */
|
||||
z13 = tmp7 - z3;
|
||||
|
||||
dataptr[5] = z13 + z2; /* phase 6 */
|
||||
dataptr[3] = z13 - z2;
|
||||
dataptr[1] = z11 + z4;
|
||||
dataptr[7] = z11 - z4;
|
||||
|
||||
dataptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
|
||||
/* Pass 2: process columns. */
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
|
||||
tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
|
||||
tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
|
||||
tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
|
||||
tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
|
||||
tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
|
||||
tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
|
||||
tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = tmp0 + tmp3; /* phase 2 */
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
|
||||
dataptr[DCTSIZE*4] = tmp10 - tmp11;
|
||||
|
||||
z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
|
||||
dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
|
||||
dataptr[DCTSIZE*6] = tmp13 - z1;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp10 = tmp4 + tmp5; /* phase 2 */
|
||||
tmp11 = tmp5 + tmp6;
|
||||
tmp12 = tmp6 + tmp7;
|
||||
|
||||
/* The rotator is modified from fig 4-8 to avoid extra negations. */
|
||||
z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
|
||||
z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
|
||||
z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
|
||||
z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
|
||||
|
||||
z11 = tmp7 + z3; /* phase 5 */
|
||||
z13 = tmp7 - z3;
|
||||
|
||||
dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
|
||||
dataptr[DCTSIZE*3] = z13 - z2;
|
||||
dataptr[DCTSIZE*1] = z11 + z4;
|
||||
dataptr[DCTSIZE*7] = z11 - z4;
|
||||
|
||||
dataptr++; /* advance pointer to next column */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_FLOAT_SUPPORTED */
|
||||
|
@ -1,224 +1,224 @@
|
||||
/*
|
||||
* jfdctfst.c
|
||||
*
|
||||
* Copyright (C) 1994-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 a fast, not so accurate integer implementation of the
|
||||
* forward DCT (Discrete Cosine Transform).
|
||||
*
|
||||
* A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
|
||||
* on each column. Direct algorithms are also available, but they are
|
||||
* much more complex and seem not to be any faster when reduced to code.
|
||||
*
|
||||
* This implementation is based on Arai, Agui, and Nakajima's algorithm for
|
||||
* scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
|
||||
* Japanese, but the algorithm is described in the Pennebaker & Mitchell
|
||||
* JPEG textbook (see REFERENCES section in file README). The following code
|
||||
* is based directly on figure 4-8 in P&M.
|
||||
* While an 8-point DCT cannot be done in less than 11 multiplies, it is
|
||||
* possible to arrange the computation so that many of the multiplies are
|
||||
* simple scalings of the final outputs. These multiplies can then be
|
||||
* folded into the multiplications or divisions by the JPEG quantization
|
||||
* table entries. The AA&N method leaves only 5 multiplies and 29 adds
|
||||
* to be done in the DCT itself.
|
||||
* The primary disadvantage of this method is that with fixed-point math,
|
||||
* accuracy is lost due to imprecise representation of the scaled
|
||||
* quantization values. The smaller the quantization table entry, the less
|
||||
* precise the scaled value, so this implementation does worse with high-
|
||||
* quality-setting files than with low-quality ones.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/* Scaling decisions are generally the same as in the LL&M algorithm;
|
||||
* see jfdctint.c for more details. However, we choose to descale
|
||||
* (right shift) multiplication products as soon as they are formed,
|
||||
* rather than carrying additional fractional bits into subsequent additions.
|
||||
* This compromises accuracy slightly, but it lets us save a few shifts.
|
||||
* More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
|
||||
* everywhere except in the multiplications proper; this saves a good deal
|
||||
* of work on 16-bit-int machines.
|
||||
*
|
||||
* Again to save a few shifts, the intermediate results between pass 1 and
|
||||
* pass 2 are not upscaled, but are represented only to integral precision.
|
||||
*
|
||||
* A final compromise is to represent the multiplicative constants to only
|
||||
* 8 fractional bits, rather than 13. This saves some shifting work on some
|
||||
* machines, and may also reduce the cost of multiplication (since there
|
||||
* are fewer one-bits in the constants).
|
||||
*/
|
||||
|
||||
#define CONST_BITS 8
|
||||
|
||||
|
||||
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
|
||||
* causing a lot of useless floating-point operations at run time.
|
||||
* To get around this we use the following pre-calculated constants.
|
||||
* If you change CONST_BITS you may want to add appropriate values.
|
||||
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
|
||||
*/
|
||||
|
||||
#if CONST_BITS == 8
|
||||
#define FIX_0_382683433 ((INT32) 98) /* FIX(0.382683433) */
|
||||
#define FIX_0_541196100 ((INT32) 139) /* FIX(0.541196100) */
|
||||
#define FIX_0_707106781 ((INT32) 181) /* FIX(0.707106781) */
|
||||
#define FIX_1_306562965 ((INT32) 334) /* FIX(1.306562965) */
|
||||
#else
|
||||
#define FIX_0_382683433 FIX(0.382683433)
|
||||
#define FIX_0_541196100 FIX(0.541196100)
|
||||
#define FIX_0_707106781 FIX(0.707106781)
|
||||
#define FIX_1_306562965 FIX(1.306562965)
|
||||
#endif
|
||||
|
||||
|
||||
/* We can gain a little more speed, with a further compromise in accuracy,
|
||||
* by omitting the addition in a descaling shift. This yields an incorrectly
|
||||
* rounded result half the time...
|
||||
*/
|
||||
|
||||
#ifndef USE_ACCURATE_ROUNDING
|
||||
#undef DESCALE
|
||||
#define DESCALE(x,n) RIGHT_SHIFT(x, n)
|
||||
#endif
|
||||
|
||||
|
||||
/* Multiply a DCTELEM variable by an INT32 constant, and immediately
|
||||
* descale to yield a DCTELEM result.
|
||||
*/
|
||||
|
||||
#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
|
||||
|
||||
|
||||
/*
|
||||
* Perform the forward DCT on one block of samples.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_fdct_ifast (DCTELEM * data)
|
||||
{
|
||||
DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
DCTELEM tmp10, tmp11, tmp12, tmp13;
|
||||
DCTELEM z1, z2, z3, z4, z5, z11, z13;
|
||||
DCTELEM *dataptr;
|
||||
int ctr;
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process rows. */
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[0] + dataptr[7];
|
||||
tmp7 = dataptr[0] - dataptr[7];
|
||||
tmp1 = dataptr[1] + dataptr[6];
|
||||
tmp6 = dataptr[1] - dataptr[6];
|
||||
tmp2 = dataptr[2] + dataptr[5];
|
||||
tmp5 = dataptr[2] - dataptr[5];
|
||||
tmp3 = dataptr[3] + dataptr[4];
|
||||
tmp4 = dataptr[3] - dataptr[4];
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = tmp0 + tmp3; /* phase 2 */
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[0] = tmp10 + tmp11; /* phase 3 */
|
||||
dataptr[4] = tmp10 - tmp11;
|
||||
|
||||
z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
|
||||
dataptr[2] = tmp13 + z1; /* phase 5 */
|
||||
dataptr[6] = tmp13 - z1;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp10 = tmp4 + tmp5; /* phase 2 */
|
||||
tmp11 = tmp5 + tmp6;
|
||||
tmp12 = tmp6 + tmp7;
|
||||
|
||||
/* The rotator is modified from fig 4-8 to avoid extra negations. */
|
||||
z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
|
||||
z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
|
||||
z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
|
||||
z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
|
||||
|
||||
z11 = tmp7 + z3; /* phase 5 */
|
||||
z13 = tmp7 - z3;
|
||||
|
||||
dataptr[5] = z13 + z2; /* phase 6 */
|
||||
dataptr[3] = z13 - z2;
|
||||
dataptr[1] = z11 + z4;
|
||||
dataptr[7] = z11 - z4;
|
||||
|
||||
dataptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
|
||||
/* Pass 2: process columns. */
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
|
||||
tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
|
||||
tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
|
||||
tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
|
||||
tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
|
||||
tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
|
||||
tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
|
||||
tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = tmp0 + tmp3; /* phase 2 */
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
|
||||
dataptr[DCTSIZE*4] = tmp10 - tmp11;
|
||||
|
||||
z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
|
||||
dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
|
||||
dataptr[DCTSIZE*6] = tmp13 - z1;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp10 = tmp4 + tmp5; /* phase 2 */
|
||||
tmp11 = tmp5 + tmp6;
|
||||
tmp12 = tmp6 + tmp7;
|
||||
|
||||
/* The rotator is modified from fig 4-8 to avoid extra negations. */
|
||||
z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
|
||||
z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
|
||||
z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
|
||||
z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
|
||||
|
||||
z11 = tmp7 + z3; /* phase 5 */
|
||||
z13 = tmp7 - z3;
|
||||
|
||||
dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
|
||||
dataptr[DCTSIZE*3] = z13 - z2;
|
||||
dataptr[DCTSIZE*1] = z11 + z4;
|
||||
dataptr[DCTSIZE*7] = z11 - z4;
|
||||
|
||||
dataptr++; /* advance pointer to next column */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_IFAST_SUPPORTED */
|
||||
/*
|
||||
* jfdctfst.c
|
||||
*
|
||||
* Copyright (C) 1994-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 a fast, not so accurate integer implementation of the
|
||||
* forward DCT (Discrete Cosine Transform).
|
||||
*
|
||||
* A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
|
||||
* on each column. Direct algorithms are also available, but they are
|
||||
* much more complex and seem not to be any faster when reduced to code.
|
||||
*
|
||||
* This implementation is based on Arai, Agui, and Nakajima's algorithm for
|
||||
* scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
|
||||
* Japanese, but the algorithm is described in the Pennebaker & Mitchell
|
||||
* JPEG textbook (see REFERENCES section in file README). The following code
|
||||
* is based directly on figure 4-8 in P&M.
|
||||
* While an 8-point DCT cannot be done in less than 11 multiplies, it is
|
||||
* possible to arrange the computation so that many of the multiplies are
|
||||
* simple scalings of the final outputs. These multiplies can then be
|
||||
* folded into the multiplications or divisions by the JPEG quantization
|
||||
* table entries. The AA&N method leaves only 5 multiplies and 29 adds
|
||||
* to be done in the DCT itself.
|
||||
* The primary disadvantage of this method is that with fixed-point math,
|
||||
* accuracy is lost due to imprecise representation of the scaled
|
||||
* quantization values. The smaller the quantization table entry, the less
|
||||
* precise the scaled value, so this implementation does worse with high-
|
||||
* quality-setting files than with low-quality ones.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/* Scaling decisions are generally the same as in the LL&M algorithm;
|
||||
* see jfdctint.c for more details. However, we choose to descale
|
||||
* (right shift) multiplication products as soon as they are formed,
|
||||
* rather than carrying additional fractional bits into subsequent additions.
|
||||
* This compromises accuracy slightly, but it lets us save a few shifts.
|
||||
* More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
|
||||
* everywhere except in the multiplications proper; this saves a good deal
|
||||
* of work on 16-bit-int machines.
|
||||
*
|
||||
* Again to save a few shifts, the intermediate results between pass 1 and
|
||||
* pass 2 are not upscaled, but are represented only to integral precision.
|
||||
*
|
||||
* A final compromise is to represent the multiplicative constants to only
|
||||
* 8 fractional bits, rather than 13. This saves some shifting work on some
|
||||
* machines, and may also reduce the cost of multiplication (since there
|
||||
* are fewer one-bits in the constants).
|
||||
*/
|
||||
|
||||
#define CONST_BITS 8
|
||||
|
||||
|
||||
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
|
||||
* causing a lot of useless floating-point operations at run time.
|
||||
* To get around this we use the following pre-calculated constants.
|
||||
* If you change CONST_BITS you may want to add appropriate values.
|
||||
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
|
||||
*/
|
||||
|
||||
#if CONST_BITS == 8
|
||||
#define FIX_0_382683433 ((INT32) 98) /* FIX(0.382683433) */
|
||||
#define FIX_0_541196100 ((INT32) 139) /* FIX(0.541196100) */
|
||||
#define FIX_0_707106781 ((INT32) 181) /* FIX(0.707106781) */
|
||||
#define FIX_1_306562965 ((INT32) 334) /* FIX(1.306562965) */
|
||||
#else
|
||||
#define FIX_0_382683433 FIX(0.382683433)
|
||||
#define FIX_0_541196100 FIX(0.541196100)
|
||||
#define FIX_0_707106781 FIX(0.707106781)
|
||||
#define FIX_1_306562965 FIX(1.306562965)
|
||||
#endif
|
||||
|
||||
|
||||
/* We can gain a little more speed, with a further compromise in accuracy,
|
||||
* by omitting the addition in a descaling shift. This yields an incorrectly
|
||||
* rounded result half the time...
|
||||
*/
|
||||
|
||||
#ifndef USE_ACCURATE_ROUNDING
|
||||
#undef DESCALE
|
||||
#define DESCALE(x,n) RIGHT_SHIFT(x, n)
|
||||
#endif
|
||||
|
||||
|
||||
/* Multiply a DCTELEM variable by an INT32 constant, and immediately
|
||||
* descale to yield a DCTELEM result.
|
||||
*/
|
||||
|
||||
#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
|
||||
|
||||
|
||||
/*
|
||||
* Perform the forward DCT on one block of samples.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_fdct_ifast (DCTELEM * data)
|
||||
{
|
||||
DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
DCTELEM tmp10, tmp11, tmp12, tmp13;
|
||||
DCTELEM z1, z2, z3, z4, z5, z11, z13;
|
||||
DCTELEM *dataptr;
|
||||
int ctr;
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process rows. */
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[0] + dataptr[7];
|
||||
tmp7 = dataptr[0] - dataptr[7];
|
||||
tmp1 = dataptr[1] + dataptr[6];
|
||||
tmp6 = dataptr[1] - dataptr[6];
|
||||
tmp2 = dataptr[2] + dataptr[5];
|
||||
tmp5 = dataptr[2] - dataptr[5];
|
||||
tmp3 = dataptr[3] + dataptr[4];
|
||||
tmp4 = dataptr[3] - dataptr[4];
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = tmp0 + tmp3; /* phase 2 */
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[0] = tmp10 + tmp11; /* phase 3 */
|
||||
dataptr[4] = tmp10 - tmp11;
|
||||
|
||||
z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
|
||||
dataptr[2] = tmp13 + z1; /* phase 5 */
|
||||
dataptr[6] = tmp13 - z1;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp10 = tmp4 + tmp5; /* phase 2 */
|
||||
tmp11 = tmp5 + tmp6;
|
||||
tmp12 = tmp6 + tmp7;
|
||||
|
||||
/* The rotator is modified from fig 4-8 to avoid extra negations. */
|
||||
z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
|
||||
z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
|
||||
z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
|
||||
z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
|
||||
|
||||
z11 = tmp7 + z3; /* phase 5 */
|
||||
z13 = tmp7 - z3;
|
||||
|
||||
dataptr[5] = z13 + z2; /* phase 6 */
|
||||
dataptr[3] = z13 - z2;
|
||||
dataptr[1] = z11 + z4;
|
||||
dataptr[7] = z11 - z4;
|
||||
|
||||
dataptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
|
||||
/* Pass 2: process columns. */
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
|
||||
tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
|
||||
tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
|
||||
tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
|
||||
tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
|
||||
tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
|
||||
tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
|
||||
tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = tmp0 + tmp3; /* phase 2 */
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
|
||||
dataptr[DCTSIZE*4] = tmp10 - tmp11;
|
||||
|
||||
z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
|
||||
dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
|
||||
dataptr[DCTSIZE*6] = tmp13 - z1;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp10 = tmp4 + tmp5; /* phase 2 */
|
||||
tmp11 = tmp5 + tmp6;
|
||||
tmp12 = tmp6 + tmp7;
|
||||
|
||||
/* The rotator is modified from fig 4-8 to avoid extra negations. */
|
||||
z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
|
||||
z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
|
||||
z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
|
||||
z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
|
||||
|
||||
z11 = tmp7 + z3; /* phase 5 */
|
||||
z13 = tmp7 - z3;
|
||||
|
||||
dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
|
||||
dataptr[DCTSIZE*3] = z13 - z2;
|
||||
dataptr[DCTSIZE*1] = z11 + z4;
|
||||
dataptr[DCTSIZE*7] = z11 - z4;
|
||||
|
||||
dataptr++; /* advance pointer to next column */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_IFAST_SUPPORTED */
|
||||
|
@ -1,283 +1,283 @@
|
||||
/*
|
||||
* jfdctint.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 a slow-but-accurate integer implementation of the
|
||||
* forward DCT (Discrete Cosine Transform).
|
||||
*
|
||||
* A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
|
||||
* on each column. Direct algorithms are also available, but they are
|
||||
* much more complex and seem not to be any faster when reduced to code.
|
||||
*
|
||||
* This implementation is based on an algorithm described in
|
||||
* C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
|
||||
* Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
|
||||
* Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
|
||||
* The primary algorithm described there uses 11 multiplies and 29 adds.
|
||||
* We use their alternate method with 12 multiplies and 32 adds.
|
||||
* The advantage of this method is that no data path contains more than one
|
||||
* multiplication; this allows a very simple and accurate implementation in
|
||||
* scaled fixed-point arithmetic, with a minimal number of shifts.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* The poop on this scaling stuff is as follows:
|
||||
*
|
||||
* Each 1-D DCT step produces outputs which are a factor of sqrt(N)
|
||||
* larger than the true DCT outputs. The final outputs are therefore
|
||||
* a factor of N larger than desired; since N=8 this can be cured by
|
||||
* a simple right shift at the end of the algorithm. The advantage of
|
||||
* this arrangement is that we save two multiplications per 1-D DCT,
|
||||
* because the y0 and y4 outputs need not be divided by sqrt(N).
|
||||
* In the IJG code, this factor of 8 is removed by the quantization step
|
||||
* (in jcdctmgr.c), NOT in this module.
|
||||
*
|
||||
* We have to do addition and subtraction of the integer inputs, which
|
||||
* is no problem, and multiplication by fractional constants, which is
|
||||
* a problem to do in integer arithmetic. We multiply all the constants
|
||||
* by CONST_SCALE and convert them to integer constants (thus retaining
|
||||
* CONST_BITS bits of precision in the constants). After doing a
|
||||
* multiplication we have to divide the product by CONST_SCALE, with proper
|
||||
* rounding, to produce the correct output. This division can be done
|
||||
* cheaply as a right shift of CONST_BITS bits. We postpone shifting
|
||||
* as long as possible so that partial sums can be added together with
|
||||
* full fractional precision.
|
||||
*
|
||||
* The outputs of the first pass are scaled up by PASS1_BITS bits so that
|
||||
* they are represented to better-than-integral precision. These outputs
|
||||
* require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
|
||||
* with the recommended scaling. (For 12-bit sample data, the intermediate
|
||||
* array is INT32 anyway.)
|
||||
*
|
||||
* To avoid overflow of the 32-bit intermediate results in pass 2, we must
|
||||
* have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
|
||||
* shows that the values given below are the most effective.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 2
|
||||
#else
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
|
||||
#endif
|
||||
|
||||
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
|
||||
* causing a lot of useless floating-point operations at run time.
|
||||
* To get around this we use the following pre-calculated constants.
|
||||
* If you change CONST_BITS you may want to add appropriate values.
|
||||
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
|
||||
*/
|
||||
|
||||
#if CONST_BITS == 13
|
||||
#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */
|
||||
#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
|
||||
#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */
|
||||
#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
|
||||
#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
|
||||
#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */
|
||||
#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */
|
||||
#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
|
||||
#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */
|
||||
#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */
|
||||
#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
|
||||
#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */
|
||||
#else
|
||||
#define FIX_0_298631336 FIX(0.298631336)
|
||||
#define FIX_0_390180644 FIX(0.390180644)
|
||||
#define FIX_0_541196100 FIX(0.541196100)
|
||||
#define FIX_0_765366865 FIX(0.765366865)
|
||||
#define FIX_0_899976223 FIX(0.899976223)
|
||||
#define FIX_1_175875602 FIX(1.175875602)
|
||||
#define FIX_1_501321110 FIX(1.501321110)
|
||||
#define FIX_1_847759065 FIX(1.847759065)
|
||||
#define FIX_1_961570560 FIX(1.961570560)
|
||||
#define FIX_2_053119869 FIX(2.053119869)
|
||||
#define FIX_2_562915447 FIX(2.562915447)
|
||||
#define FIX_3_072711026 FIX(3.072711026)
|
||||
#endif
|
||||
|
||||
|
||||
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
|
||||
* For 8-bit samples with the recommended scaling, all the variable
|
||||
* and constant values involved are no more than 16 bits wide, so a
|
||||
* 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
|
||||
* For 12-bit samples, a full 32-bit multiplication will be needed.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
|
||||
#else
|
||||
#define MULTIPLY(var,const) ((var) * (const))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Perform the forward DCT on one block of samples.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_fdct_islow (DCTELEM * data)
|
||||
{
|
||||
INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
INT32 tmp10, tmp11, tmp12, tmp13;
|
||||
INT32 z1, z2, z3, z4, z5;
|
||||
DCTELEM *dataptr;
|
||||
int ctr;
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process rows. */
|
||||
/* Note results are scaled up by sqrt(8) compared to a true DCT; */
|
||||
/* furthermore, we scale the results by 2**PASS1_BITS. */
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[0] + dataptr[7];
|
||||
tmp7 = dataptr[0] - dataptr[7];
|
||||
tmp1 = dataptr[1] + dataptr[6];
|
||||
tmp6 = dataptr[1] - dataptr[6];
|
||||
tmp2 = dataptr[2] + dataptr[5];
|
||||
tmp5 = dataptr[2] - dataptr[5];
|
||||
tmp3 = dataptr[3] + dataptr[4];
|
||||
tmp4 = dataptr[3] - dataptr[4];
|
||||
|
||||
/* Even part per LL&M figure 1 --- note that published figure is faulty;
|
||||
* rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
|
||||
*/
|
||||
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS);
|
||||
dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
|
||||
|
||||
z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
|
||||
dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
|
||||
CONST_BITS-PASS1_BITS);
|
||||
dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
|
||||
CONST_BITS-PASS1_BITS);
|
||||
|
||||
/* Odd part per figure 8 --- note paper omits factor of sqrt(2).
|
||||
* cK represents cos(K*pi/16).
|
||||
* i0..i3 in the paper are tmp4..tmp7 here.
|
||||
*/
|
||||
|
||||
z1 = tmp4 + tmp7;
|
||||
z2 = tmp5 + tmp6;
|
||||
z3 = tmp4 + tmp6;
|
||||
z4 = tmp5 + tmp7;
|
||||
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
|
||||
|
||||
tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
|
||||
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
|
||||
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
|
||||
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
|
||||
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
|
||||
dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
|
||||
dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
|
||||
dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
|
||||
dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
|
||||
|
||||
dataptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
|
||||
/* Pass 2: process columns.
|
||||
* We remove the PASS1_BITS scaling, but leave the results scaled up
|
||||
* by an overall factor of 8.
|
||||
*/
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
|
||||
tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
|
||||
tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
|
||||
tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
|
||||
tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
|
||||
tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
|
||||
tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
|
||||
tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
|
||||
|
||||
/* Even part per LL&M figure 1 --- note that published figure is faulty;
|
||||
* rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
|
||||
*/
|
||||
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS);
|
||||
dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS);
|
||||
|
||||
z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
|
||||
dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
|
||||
CONST_BITS+PASS1_BITS);
|
||||
dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
|
||||
CONST_BITS+PASS1_BITS);
|
||||
|
||||
/* Odd part per figure 8 --- note paper omits factor of sqrt(2).
|
||||
* cK represents cos(K*pi/16).
|
||||
* i0..i3 in the paper are tmp4..tmp7 here.
|
||||
*/
|
||||
|
||||
z1 = tmp4 + tmp7;
|
||||
z2 = tmp5 + tmp6;
|
||||
z3 = tmp4 + tmp6;
|
||||
z4 = tmp5 + tmp7;
|
||||
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
|
||||
|
||||
tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
|
||||
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
|
||||
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
|
||||
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
|
||||
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
|
||||
dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3,
|
||||
CONST_BITS+PASS1_BITS);
|
||||
dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4,
|
||||
CONST_BITS+PASS1_BITS);
|
||||
dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3,
|
||||
CONST_BITS+PASS1_BITS);
|
||||
dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4,
|
||||
CONST_BITS+PASS1_BITS);
|
||||
|
||||
dataptr++; /* advance pointer to next column */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_ISLOW_SUPPORTED */
|
||||
/*
|
||||
* jfdctint.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 a slow-but-accurate integer implementation of the
|
||||
* forward DCT (Discrete Cosine Transform).
|
||||
*
|
||||
* A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
|
||||
* on each column. Direct algorithms are also available, but they are
|
||||
* much more complex and seem not to be any faster when reduced to code.
|
||||
*
|
||||
* This implementation is based on an algorithm described in
|
||||
* C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
|
||||
* Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
|
||||
* Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
|
||||
* The primary algorithm described there uses 11 multiplies and 29 adds.
|
||||
* We use their alternate method with 12 multiplies and 32 adds.
|
||||
* The advantage of this method is that no data path contains more than one
|
||||
* multiplication; this allows a very simple and accurate implementation in
|
||||
* scaled fixed-point arithmetic, with a minimal number of shifts.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* The poop on this scaling stuff is as follows:
|
||||
*
|
||||
* Each 1-D DCT step produces outputs which are a factor of sqrt(N)
|
||||
* larger than the true DCT outputs. The final outputs are therefore
|
||||
* a factor of N larger than desired; since N=8 this can be cured by
|
||||
* a simple right shift at the end of the algorithm. The advantage of
|
||||
* this arrangement is that we save two multiplications per 1-D DCT,
|
||||
* because the y0 and y4 outputs need not be divided by sqrt(N).
|
||||
* In the IJG code, this factor of 8 is removed by the quantization step
|
||||
* (in jcdctmgr.c), NOT in this module.
|
||||
*
|
||||
* We have to do addition and subtraction of the integer inputs, which
|
||||
* is no problem, and multiplication by fractional constants, which is
|
||||
* a problem to do in integer arithmetic. We multiply all the constants
|
||||
* by CONST_SCALE and convert them to integer constants (thus retaining
|
||||
* CONST_BITS bits of precision in the constants). After doing a
|
||||
* multiplication we have to divide the product by CONST_SCALE, with proper
|
||||
* rounding, to produce the correct output. This division can be done
|
||||
* cheaply as a right shift of CONST_BITS bits. We postpone shifting
|
||||
* as long as possible so that partial sums can be added together with
|
||||
* full fractional precision.
|
||||
*
|
||||
* The outputs of the first pass are scaled up by PASS1_BITS bits so that
|
||||
* they are represented to better-than-integral precision. These outputs
|
||||
* require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
|
||||
* with the recommended scaling. (For 12-bit sample data, the intermediate
|
||||
* array is INT32 anyway.)
|
||||
*
|
||||
* To avoid overflow of the 32-bit intermediate results in pass 2, we must
|
||||
* have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
|
||||
* shows that the values given below are the most effective.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 2
|
||||
#else
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
|
||||
#endif
|
||||
|
||||
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
|
||||
* causing a lot of useless floating-point operations at run time.
|
||||
* To get around this we use the following pre-calculated constants.
|
||||
* If you change CONST_BITS you may want to add appropriate values.
|
||||
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
|
||||
*/
|
||||
|
||||
#if CONST_BITS == 13
|
||||
#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */
|
||||
#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
|
||||
#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */
|
||||
#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
|
||||
#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
|
||||
#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */
|
||||
#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */
|
||||
#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
|
||||
#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */
|
||||
#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */
|
||||
#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
|
||||
#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */
|
||||
#else
|
||||
#define FIX_0_298631336 FIX(0.298631336)
|
||||
#define FIX_0_390180644 FIX(0.390180644)
|
||||
#define FIX_0_541196100 FIX(0.541196100)
|
||||
#define FIX_0_765366865 FIX(0.765366865)
|
||||
#define FIX_0_899976223 FIX(0.899976223)
|
||||
#define FIX_1_175875602 FIX(1.175875602)
|
||||
#define FIX_1_501321110 FIX(1.501321110)
|
||||
#define FIX_1_847759065 FIX(1.847759065)
|
||||
#define FIX_1_961570560 FIX(1.961570560)
|
||||
#define FIX_2_053119869 FIX(2.053119869)
|
||||
#define FIX_2_562915447 FIX(2.562915447)
|
||||
#define FIX_3_072711026 FIX(3.072711026)
|
||||
#endif
|
||||
|
||||
|
||||
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
|
||||
* For 8-bit samples with the recommended scaling, all the variable
|
||||
* and constant values involved are no more than 16 bits wide, so a
|
||||
* 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
|
||||
* For 12-bit samples, a full 32-bit multiplication will be needed.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
|
||||
#else
|
||||
#define MULTIPLY(var,const) ((var) * (const))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Perform the forward DCT on one block of samples.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_fdct_islow (DCTELEM * data)
|
||||
{
|
||||
INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
INT32 tmp10, tmp11, tmp12, tmp13;
|
||||
INT32 z1, z2, z3, z4, z5;
|
||||
DCTELEM *dataptr;
|
||||
int ctr;
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process rows. */
|
||||
/* Note results are scaled up by sqrt(8) compared to a true DCT; */
|
||||
/* furthermore, we scale the results by 2**PASS1_BITS. */
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[0] + dataptr[7];
|
||||
tmp7 = dataptr[0] - dataptr[7];
|
||||
tmp1 = dataptr[1] + dataptr[6];
|
||||
tmp6 = dataptr[1] - dataptr[6];
|
||||
tmp2 = dataptr[2] + dataptr[5];
|
||||
tmp5 = dataptr[2] - dataptr[5];
|
||||
tmp3 = dataptr[3] + dataptr[4];
|
||||
tmp4 = dataptr[3] - dataptr[4];
|
||||
|
||||
/* Even part per LL&M figure 1 --- note that published figure is faulty;
|
||||
* rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
|
||||
*/
|
||||
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS);
|
||||
dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
|
||||
|
||||
z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
|
||||
dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
|
||||
CONST_BITS-PASS1_BITS);
|
||||
dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
|
||||
CONST_BITS-PASS1_BITS);
|
||||
|
||||
/* Odd part per figure 8 --- note paper omits factor of sqrt(2).
|
||||
* cK represents cos(K*pi/16).
|
||||
* i0..i3 in the paper are tmp4..tmp7 here.
|
||||
*/
|
||||
|
||||
z1 = tmp4 + tmp7;
|
||||
z2 = tmp5 + tmp6;
|
||||
z3 = tmp4 + tmp6;
|
||||
z4 = tmp5 + tmp7;
|
||||
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
|
||||
|
||||
tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
|
||||
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
|
||||
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
|
||||
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
|
||||
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
|
||||
dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
|
||||
dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
|
||||
dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
|
||||
dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
|
||||
|
||||
dataptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
|
||||
/* Pass 2: process columns.
|
||||
* We remove the PASS1_BITS scaling, but leave the results scaled up
|
||||
* by an overall factor of 8.
|
||||
*/
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
|
||||
tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
|
||||
tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
|
||||
tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
|
||||
tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
|
||||
tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
|
||||
tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
|
||||
tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
|
||||
|
||||
/* Even part per LL&M figure 1 --- note that published figure is faulty;
|
||||
* rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
|
||||
*/
|
||||
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS);
|
||||
dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS);
|
||||
|
||||
z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
|
||||
dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
|
||||
CONST_BITS+PASS1_BITS);
|
||||
dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
|
||||
CONST_BITS+PASS1_BITS);
|
||||
|
||||
/* Odd part per figure 8 --- note paper omits factor of sqrt(2).
|
||||
* cK represents cos(K*pi/16).
|
||||
* i0..i3 in the paper are tmp4..tmp7 here.
|
||||
*/
|
||||
|
||||
z1 = tmp4 + tmp7;
|
||||
z2 = tmp5 + tmp6;
|
||||
z3 = tmp4 + tmp6;
|
||||
z4 = tmp5 + tmp7;
|
||||
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
|
||||
|
||||
tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
|
||||
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
|
||||
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
|
||||
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
|
||||
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
|
||||
dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3,
|
||||
CONST_BITS+PASS1_BITS);
|
||||
dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4,
|
||||
CONST_BITS+PASS1_BITS);
|
||||
dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3,
|
||||
CONST_BITS+PASS1_BITS);
|
||||
dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4,
|
||||
CONST_BITS+PASS1_BITS);
|
||||
|
||||
dataptr++; /* advance pointer to next column */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_ISLOW_SUPPORTED */
|
||||
|
@ -1,242 +1,242 @@
|
||||
/*
|
||||
* jidctflt.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, 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 a floating-point implementation of the
|
||||
* inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
|
||||
* must also perform dequantization of the input coefficients.
|
||||
*
|
||||
* This implementation should be more accurate than either of the integer
|
||||
* IDCT implementations. However, it may not give the same results on all
|
||||
* machines because of differences in roundoff behavior. Speed will depend
|
||||
* on the hardware's floating point capacity.
|
||||
*
|
||||
* A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
|
||||
* on each row (or vice versa, but it's more convenient to emit a row at
|
||||
* a time). Direct algorithms are also available, but they are much more
|
||||
* complex and seem not to be any faster when reduced to code.
|
||||
*
|
||||
* This implementation is based on Arai, Agui, and Nakajima's algorithm for
|
||||
* scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
|
||||
* Japanese, but the algorithm is described in the Pennebaker & Mitchell
|
||||
* JPEG textbook (see REFERENCES section in file README). The following code
|
||||
* is based directly on figure 4-8 in P&M.
|
||||
* While an 8-point DCT cannot be done in less than 11 multiplies, it is
|
||||
* possible to arrange the computation so that many of the multiplies are
|
||||
* simple scalings of the final outputs. These multiplies can then be
|
||||
* folded into the multiplications or divisions by the JPEG quantization
|
||||
* table entries. The AA&N method leaves only 5 multiplies and 29 adds
|
||||
* to be done in the DCT itself.
|
||||
* The primary disadvantage of this method is that with a fixed-point
|
||||
* implementation, accuracy is lost due to imprecise representation of the
|
||||
* scaled quantization values. However, that problem does not arise if
|
||||
* we use floating point arithmetic.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/* Dequantize a coefficient by multiplying it by the multiplier-table
|
||||
* entry; produce a float result.
|
||||
*/
|
||||
|
||||
#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval))
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
|
||||
FAST_FLOAT z5, z10, z11, z12, z13;
|
||||
JCOEFPTR inptr;
|
||||
FLOAT_MULT_TYPE * quantptr;
|
||||
FAST_FLOAT * wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process columns from input, store into work array. */
|
||||
|
||||
inptr = coef_block;
|
||||
quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table;
|
||||
wsptr = workspace;
|
||||
for (ctr = DCTSIZE; ctr > 0; ctr--) {
|
||||
/* Due to quantization, we will usually find that many of the input
|
||||
* coefficients are zero, especially the AC terms. We can exploit this
|
||||
* by short-circuiting the IDCT calculation for any column in which all
|
||||
* the AC terms are zero. In that case each output is equal to the
|
||||
* DC coefficient (with scale factor as needed).
|
||||
* With typical images and quantization tables, half or more of the
|
||||
* column DCT calculations can be simplified this way.
|
||||
*/
|
||||
|
||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
|
||||
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
|
||||
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
|
||||
inptr[DCTSIZE*7] == 0) {
|
||||
/* AC terms all zero */
|
||||
FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
|
||||
wsptr[DCTSIZE*0] = dcval;
|
||||
wsptr[DCTSIZE*1] = dcval;
|
||||
wsptr[DCTSIZE*2] = dcval;
|
||||
wsptr[DCTSIZE*3] = dcval;
|
||||
wsptr[DCTSIZE*4] = dcval;
|
||||
wsptr[DCTSIZE*5] = dcval;
|
||||
wsptr[DCTSIZE*6] = dcval;
|
||||
wsptr[DCTSIZE*7] = dcval;
|
||||
|
||||
inptr++; /* advance pointers to next column */
|
||||
quantptr++;
|
||||
wsptr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
|
||||
tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
|
||||
tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
|
||||
|
||||
tmp10 = tmp0 + tmp2; /* phase 3 */
|
||||
tmp11 = tmp0 - tmp2;
|
||||
|
||||
tmp13 = tmp1 + tmp3; /* phases 5-3 */
|
||||
tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */
|
||||
|
||||
tmp0 = tmp10 + tmp13; /* phase 2 */
|
||||
tmp3 = tmp10 - tmp13;
|
||||
tmp1 = tmp11 + tmp12;
|
||||
tmp2 = tmp11 - tmp12;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
||||
tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
||||
tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
||||
tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
||||
|
||||
z13 = tmp6 + tmp5; /* phase 6 */
|
||||
z10 = tmp6 - tmp5;
|
||||
z11 = tmp4 + tmp7;
|
||||
z12 = tmp4 - tmp7;
|
||||
|
||||
tmp7 = z11 + z13; /* phase 5 */
|
||||
tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
|
||||
|
||||
z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
|
||||
tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
|
||||
tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
|
||||
|
||||
tmp6 = tmp12 - tmp7; /* phase 2 */
|
||||
tmp5 = tmp11 - tmp6;
|
||||
tmp4 = tmp10 + tmp5;
|
||||
|
||||
wsptr[DCTSIZE*0] = tmp0 + tmp7;
|
||||
wsptr[DCTSIZE*7] = tmp0 - tmp7;
|
||||
wsptr[DCTSIZE*1] = tmp1 + tmp6;
|
||||
wsptr[DCTSIZE*6] = tmp1 - tmp6;
|
||||
wsptr[DCTSIZE*2] = tmp2 + tmp5;
|
||||
wsptr[DCTSIZE*5] = tmp2 - tmp5;
|
||||
wsptr[DCTSIZE*4] = tmp3 + tmp4;
|
||||
wsptr[DCTSIZE*3] = tmp3 - tmp4;
|
||||
|
||||
inptr++; /* advance pointers to next column */
|
||||
quantptr++;
|
||||
wsptr++;
|
||||
}
|
||||
|
||||
/* Pass 2: process rows from work array, store into output array. */
|
||||
/* Note that we must descale the results by a factor of 8 == 2**3. */
|
||||
|
||||
wsptr = workspace;
|
||||
for (ctr = 0; ctr < DCTSIZE; ctr++) {
|
||||
outptr = output_buf[ctr] + output_col;
|
||||
/* Rows of zeroes can be exploited in the same way as we did with columns.
|
||||
* However, the column calculation has created many nonzero AC terms, so
|
||||
* the simplification applies less often (typically 5% to 10% of the time).
|
||||
* And testing floats for zero is relatively expensive, so we don't bother.
|
||||
*/
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = wsptr[0] + wsptr[4];
|
||||
tmp11 = wsptr[0] - wsptr[4];
|
||||
|
||||
tmp13 = wsptr[2] + wsptr[6];
|
||||
tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
|
||||
|
||||
tmp0 = tmp10 + tmp13;
|
||||
tmp3 = tmp10 - tmp13;
|
||||
tmp1 = tmp11 + tmp12;
|
||||
tmp2 = tmp11 - tmp12;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z13 = wsptr[5] + wsptr[3];
|
||||
z10 = wsptr[5] - wsptr[3];
|
||||
z11 = wsptr[1] + wsptr[7];
|
||||
z12 = wsptr[1] - wsptr[7];
|
||||
|
||||
tmp7 = z11 + z13;
|
||||
tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
|
||||
|
||||
z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
|
||||
tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
|
||||
tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
|
||||
|
||||
tmp6 = tmp12 - tmp7;
|
||||
tmp5 = tmp11 - tmp6;
|
||||
tmp4 = tmp10 + tmp5;
|
||||
|
||||
/* Final output stage: scale down by a factor of 8 and range-limit */
|
||||
|
||||
outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3)
|
||||
& RANGE_MASK];
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_FLOAT_SUPPORTED */
|
||||
/*
|
||||
* jidctflt.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, 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 a floating-point implementation of the
|
||||
* inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
|
||||
* must also perform dequantization of the input coefficients.
|
||||
*
|
||||
* This implementation should be more accurate than either of the integer
|
||||
* IDCT implementations. However, it may not give the same results on all
|
||||
* machines because of differences in roundoff behavior. Speed will depend
|
||||
* on the hardware's floating point capacity.
|
||||
*
|
||||
* A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
|
||||
* on each row (or vice versa, but it's more convenient to emit a row at
|
||||
* a time). Direct algorithms are also available, but they are much more
|
||||
* complex and seem not to be any faster when reduced to code.
|
||||
*
|
||||
* This implementation is based on Arai, Agui, and Nakajima's algorithm for
|
||||
* scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
|
||||
* Japanese, but the algorithm is described in the Pennebaker & Mitchell
|
||||
* JPEG textbook (see REFERENCES section in file README). The following code
|
||||
* is based directly on figure 4-8 in P&M.
|
||||
* While an 8-point DCT cannot be done in less than 11 multiplies, it is
|
||||
* possible to arrange the computation so that many of the multiplies are
|
||||
* simple scalings of the final outputs. These multiplies can then be
|
||||
* folded into the multiplications or divisions by the JPEG quantization
|
||||
* table entries. The AA&N method leaves only 5 multiplies and 29 adds
|
||||
* to be done in the DCT itself.
|
||||
* The primary disadvantage of this method is that with a fixed-point
|
||||
* implementation, accuracy is lost due to imprecise representation of the
|
||||
* scaled quantization values. However, that problem does not arise if
|
||||
* we use floating point arithmetic.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/* Dequantize a coefficient by multiplying it by the multiplier-table
|
||||
* entry; produce a float result.
|
||||
*/
|
||||
|
||||
#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval))
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
|
||||
FAST_FLOAT z5, z10, z11, z12, z13;
|
||||
JCOEFPTR inptr;
|
||||
FLOAT_MULT_TYPE * quantptr;
|
||||
FAST_FLOAT * wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process columns from input, store into work array. */
|
||||
|
||||
inptr = coef_block;
|
||||
quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table;
|
||||
wsptr = workspace;
|
||||
for (ctr = DCTSIZE; ctr > 0; ctr--) {
|
||||
/* Due to quantization, we will usually find that many of the input
|
||||
* coefficients are zero, especially the AC terms. We can exploit this
|
||||
* by short-circuiting the IDCT calculation for any column in which all
|
||||
* the AC terms are zero. In that case each output is equal to the
|
||||
* DC coefficient (with scale factor as needed).
|
||||
* With typical images and quantization tables, half or more of the
|
||||
* column DCT calculations can be simplified this way.
|
||||
*/
|
||||
|
||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
|
||||
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
|
||||
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
|
||||
inptr[DCTSIZE*7] == 0) {
|
||||
/* AC terms all zero */
|
||||
FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
|
||||
wsptr[DCTSIZE*0] = dcval;
|
||||
wsptr[DCTSIZE*1] = dcval;
|
||||
wsptr[DCTSIZE*2] = dcval;
|
||||
wsptr[DCTSIZE*3] = dcval;
|
||||
wsptr[DCTSIZE*4] = dcval;
|
||||
wsptr[DCTSIZE*5] = dcval;
|
||||
wsptr[DCTSIZE*6] = dcval;
|
||||
wsptr[DCTSIZE*7] = dcval;
|
||||
|
||||
inptr++; /* advance pointers to next column */
|
||||
quantptr++;
|
||||
wsptr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
|
||||
tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
|
||||
tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
|
||||
|
||||
tmp10 = tmp0 + tmp2; /* phase 3 */
|
||||
tmp11 = tmp0 - tmp2;
|
||||
|
||||
tmp13 = tmp1 + tmp3; /* phases 5-3 */
|
||||
tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */
|
||||
|
||||
tmp0 = tmp10 + tmp13; /* phase 2 */
|
||||
tmp3 = tmp10 - tmp13;
|
||||
tmp1 = tmp11 + tmp12;
|
||||
tmp2 = tmp11 - tmp12;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
||||
tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
||||
tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
||||
tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
||||
|
||||
z13 = tmp6 + tmp5; /* phase 6 */
|
||||
z10 = tmp6 - tmp5;
|
||||
z11 = tmp4 + tmp7;
|
||||
z12 = tmp4 - tmp7;
|
||||
|
||||
tmp7 = z11 + z13; /* phase 5 */
|
||||
tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
|
||||
|
||||
z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
|
||||
tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
|
||||
tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
|
||||
|
||||
tmp6 = tmp12 - tmp7; /* phase 2 */
|
||||
tmp5 = tmp11 - tmp6;
|
||||
tmp4 = tmp10 + tmp5;
|
||||
|
||||
wsptr[DCTSIZE*0] = tmp0 + tmp7;
|
||||
wsptr[DCTSIZE*7] = tmp0 - tmp7;
|
||||
wsptr[DCTSIZE*1] = tmp1 + tmp6;
|
||||
wsptr[DCTSIZE*6] = tmp1 - tmp6;
|
||||
wsptr[DCTSIZE*2] = tmp2 + tmp5;
|
||||
wsptr[DCTSIZE*5] = tmp2 - tmp5;
|
||||
wsptr[DCTSIZE*4] = tmp3 + tmp4;
|
||||
wsptr[DCTSIZE*3] = tmp3 - tmp4;
|
||||
|
||||
inptr++; /* advance pointers to next column */
|
||||
quantptr++;
|
||||
wsptr++;
|
||||
}
|
||||
|
||||
/* Pass 2: process rows from work array, store into output array. */
|
||||
/* Note that we must descale the results by a factor of 8 == 2**3. */
|
||||
|
||||
wsptr = workspace;
|
||||
for (ctr = 0; ctr < DCTSIZE; ctr++) {
|
||||
outptr = output_buf[ctr] + output_col;
|
||||
/* Rows of zeroes can be exploited in the same way as we did with columns.
|
||||
* However, the column calculation has created many nonzero AC terms, so
|
||||
* the simplification applies less often (typically 5% to 10% of the time).
|
||||
* And testing floats for zero is relatively expensive, so we don't bother.
|
||||
*/
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = wsptr[0] + wsptr[4];
|
||||
tmp11 = wsptr[0] - wsptr[4];
|
||||
|
||||
tmp13 = wsptr[2] + wsptr[6];
|
||||
tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
|
||||
|
||||
tmp0 = tmp10 + tmp13;
|
||||
tmp3 = tmp10 - tmp13;
|
||||
tmp1 = tmp11 + tmp12;
|
||||
tmp2 = tmp11 - tmp12;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z13 = wsptr[5] + wsptr[3];
|
||||
z10 = wsptr[5] - wsptr[3];
|
||||
z11 = wsptr[1] + wsptr[7];
|
||||
z12 = wsptr[1] - wsptr[7];
|
||||
|
||||
tmp7 = z11 + z13;
|
||||
tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
|
||||
|
||||
z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
|
||||
tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
|
||||
tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
|
||||
|
||||
tmp6 = tmp12 - tmp7;
|
||||
tmp5 = tmp11 - tmp6;
|
||||
tmp4 = tmp10 + tmp5;
|
||||
|
||||
/* Final output stage: scale down by a factor of 8 and range-limit */
|
||||
|
||||
outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3)
|
||||
& RANGE_MASK];
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_FLOAT_SUPPORTED */
|
||||
|
@ -1,368 +1,368 @@
|
||||
/*
|
||||
* jidctfst.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, 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 a fast, not so accurate integer implementation of the
|
||||
* inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
|
||||
* must also perform dequantization of the input coefficients.
|
||||
*
|
||||
* A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
|
||||
* on each row (or vice versa, but it's more convenient to emit a row at
|
||||
* a time). Direct algorithms are also available, but they are much more
|
||||
* complex and seem not to be any faster when reduced to code.
|
||||
*
|
||||
* This implementation is based on Arai, Agui, and Nakajima's algorithm for
|
||||
* scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
|
||||
* Japanese, but the algorithm is described in the Pennebaker & Mitchell
|
||||
* JPEG textbook (see REFERENCES section in file README). The following code
|
||||
* is based directly on figure 4-8 in P&M.
|
||||
* While an 8-point DCT cannot be done in less than 11 multiplies, it is
|
||||
* possible to arrange the computation so that many of the multiplies are
|
||||
* simple scalings of the final outputs. These multiplies can then be
|
||||
* folded into the multiplications or divisions by the JPEG quantization
|
||||
* table entries. The AA&N method leaves only 5 multiplies and 29 adds
|
||||
* to be done in the DCT itself.
|
||||
* The primary disadvantage of this method is that with fixed-point math,
|
||||
* accuracy is lost due to imprecise representation of the scaled
|
||||
* quantization values. The smaller the quantization table entry, the less
|
||||
* precise the scaled value, so this implementation does worse with high-
|
||||
* quality-setting files than with low-quality ones.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/* Scaling decisions are generally the same as in the LL&M algorithm;
|
||||
* see jidctint.c for more details. However, we choose to descale
|
||||
* (right shift) multiplication products as soon as they are formed,
|
||||
* rather than carrying additional fractional bits into subsequent additions.
|
||||
* This compromises accuracy slightly, but it lets us save a few shifts.
|
||||
* More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
|
||||
* everywhere except in the multiplications proper; this saves a good deal
|
||||
* of work on 16-bit-int machines.
|
||||
*
|
||||
* The dequantized coefficients are not integers because the AA&N scaling
|
||||
* factors have been incorporated. We represent them scaled up by PASS1_BITS,
|
||||
* so that the first and second IDCT rounds have the same input scaling.
|
||||
* For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to
|
||||
* avoid a descaling shift; this compromises accuracy rather drastically
|
||||
* for small quantization table entries, but it saves a lot of shifts.
|
||||
* For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway,
|
||||
* so we use a much larger scaling factor to preserve accuracy.
|
||||
*
|
||||
* A final compromise is to represent the multiplicative constants to only
|
||||
* 8 fractional bits, rather than 13. This saves some shifting work on some
|
||||
* machines, and may also reduce the cost of multiplication (since there
|
||||
* are fewer one-bits in the constants).
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define CONST_BITS 8
|
||||
#define PASS1_BITS 2
|
||||
#else
|
||||
#define CONST_BITS 8
|
||||
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
|
||||
#endif
|
||||
|
||||
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
|
||||
* causing a lot of useless floating-point operations at run time.
|
||||
* To get around this we use the following pre-calculated constants.
|
||||
* If you change CONST_BITS you may want to add appropriate values.
|
||||
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
|
||||
*/
|
||||
|
||||
#if CONST_BITS == 8
|
||||
#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */
|
||||
#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */
|
||||
#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */
|
||||
#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */
|
||||
#else
|
||||
#define FIX_1_082392200 FIX(1.082392200)
|
||||
#define FIX_1_414213562 FIX(1.414213562)
|
||||
#define FIX_1_847759065 FIX(1.847759065)
|
||||
#define FIX_2_613125930 FIX(2.613125930)
|
||||
#endif
|
||||
|
||||
|
||||
/* We can gain a little more speed, with a further compromise in accuracy,
|
||||
* by omitting the addition in a descaling shift. This yields an incorrectly
|
||||
* rounded result half the time...
|
||||
*/
|
||||
|
||||
#ifndef USE_ACCURATE_ROUNDING
|
||||
#undef DESCALE
|
||||
#define DESCALE(x,n) RIGHT_SHIFT(x, n)
|
||||
#endif
|
||||
|
||||
|
||||
/* Multiply a DCTELEM variable by an INT32 constant, and immediately
|
||||
* descale to yield a DCTELEM result.
|
||||
*/
|
||||
|
||||
#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
|
||||
|
||||
|
||||
/* Dequantize a coefficient by multiplying it by the multiplier-table
|
||||
* entry; produce a DCTELEM result. For 8-bit data a 16x16->16
|
||||
* multiplication will do. For 12-bit data, the multiplier table is
|
||||
* declared INT32, so a 32-bit multiply will be used.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval))
|
||||
#else
|
||||
#define DEQUANTIZE(coef,quantval) \
|
||||
DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS)
|
||||
#endif
|
||||
|
||||
|
||||
/* Like DESCALE, but applies to a DCTELEM and produces an int.
|
||||
* We assume that int right shift is unsigned if INT32 right shift is.
|
||||
*/
|
||||
|
||||
#ifdef RIGHT_SHIFT_IS_UNSIGNED
|
||||
#define ISHIFT_TEMPS DCTELEM ishift_temp;
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */
|
||||
#else
|
||||
#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */
|
||||
#endif
|
||||
#define IRIGHT_SHIFT(x,shft) \
|
||||
((ishift_temp = (x)) < 0 ? \
|
||||
(ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \
|
||||
(ishift_temp >> (shft)))
|
||||
#else
|
||||
#define ISHIFT_TEMPS
|
||||
#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
|
||||
#endif
|
||||
|
||||
#ifdef USE_ACCURATE_ROUNDING
|
||||
#define IDESCALE(x,n) ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n))
|
||||
#else
|
||||
#define IDESCALE(x,n) ((int) IRIGHT_SHIFT(x, n))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
DCTELEM tmp10, tmp11, tmp12, tmp13;
|
||||
DCTELEM z5, z10, z11, z12, z13;
|
||||
JCOEFPTR inptr;
|
||||
IFAST_MULT_TYPE * quantptr;
|
||||
int * wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE2]; /* buffers data between passes */
|
||||
SHIFT_TEMPS /* for DESCALE */
|
||||
ISHIFT_TEMPS /* for IDESCALE */
|
||||
|
||||
/* Pass 1: process columns from input, store into work array. */
|
||||
|
||||
inptr = coef_block;
|
||||
quantptr = (IFAST_MULT_TYPE *) compptr->dct_table;
|
||||
wsptr = workspace;
|
||||
for (ctr = DCTSIZE; ctr > 0; ctr--) {
|
||||
/* Due to quantization, we will usually find that many of the input
|
||||
* coefficients are zero, especially the AC terms. We can exploit this
|
||||
* by short-circuiting the IDCT calculation for any column in which all
|
||||
* the AC terms are zero. In that case each output is equal to the
|
||||
* DC coefficient (with scale factor as needed).
|
||||
* With typical images and quantization tables, half or more of the
|
||||
* column DCT calculations can be simplified this way.
|
||||
*/
|
||||
|
||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
|
||||
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
|
||||
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
|
||||
inptr[DCTSIZE*7] == 0) {
|
||||
/* AC terms all zero */
|
||||
int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
|
||||
wsptr[DCTSIZE*0] = dcval;
|
||||
wsptr[DCTSIZE*1] = dcval;
|
||||
wsptr[DCTSIZE*2] = dcval;
|
||||
wsptr[DCTSIZE*3] = dcval;
|
||||
wsptr[DCTSIZE*4] = dcval;
|
||||
wsptr[DCTSIZE*5] = dcval;
|
||||
wsptr[DCTSIZE*6] = dcval;
|
||||
wsptr[DCTSIZE*7] = dcval;
|
||||
|
||||
inptr++; /* advance pointers to next column */
|
||||
quantptr++;
|
||||
wsptr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
|
||||
tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
|
||||
tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
|
||||
|
||||
tmp10 = tmp0 + tmp2; /* phase 3 */
|
||||
tmp11 = tmp0 - tmp2;
|
||||
|
||||
tmp13 = tmp1 + tmp3; /* phases 5-3 */
|
||||
tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
|
||||
|
||||
tmp0 = tmp10 + tmp13; /* phase 2 */
|
||||
tmp3 = tmp10 - tmp13;
|
||||
tmp1 = tmp11 + tmp12;
|
||||
tmp2 = tmp11 - tmp12;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
||||
tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
||||
tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
||||
tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
||||
|
||||
z13 = tmp6 + tmp5; /* phase 6 */
|
||||
z10 = tmp6 - tmp5;
|
||||
z11 = tmp4 + tmp7;
|
||||
z12 = tmp4 - tmp7;
|
||||
|
||||
tmp7 = z11 + z13; /* phase 5 */
|
||||
tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
|
||||
|
||||
z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
|
||||
tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
|
||||
tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
|
||||
|
||||
tmp6 = tmp12 - tmp7; /* phase 2 */
|
||||
tmp5 = tmp11 - tmp6;
|
||||
tmp4 = tmp10 + tmp5;
|
||||
|
||||
wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
|
||||
wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
|
||||
wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
|
||||
wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
|
||||
wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
|
||||
wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
|
||||
wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
|
||||
wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
|
||||
|
||||
inptr++; /* advance pointers to next column */
|
||||
quantptr++;
|
||||
wsptr++;
|
||||
}
|
||||
|
||||
/* Pass 2: process rows from work array, store into output array. */
|
||||
/* Note that we must descale the results by a factor of 8 == 2**3, */
|
||||
/* and also undo the PASS1_BITS scaling. */
|
||||
|
||||
wsptr = workspace;
|
||||
for (ctr = 0; ctr < DCTSIZE; ctr++) {
|
||||
outptr = output_buf[ctr] + output_col;
|
||||
/* Rows of zeroes can be exploited in the same way as we did with columns.
|
||||
* However, the column calculation has created many nonzero AC terms, so
|
||||
* the simplification applies less often (typically 5% to 10% of the time).
|
||||
* On machines with very fast multiplication, it's possible that the
|
||||
* test takes more time than it's worth. In that case this section
|
||||
* may be commented out.
|
||||
*/
|
||||
|
||||
#ifndef NO_ZERO_ROW_TEST
|
||||
if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
|
||||
wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
|
||||
/* AC terms all zero */
|
||||
JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
outptr[1] = dcval;
|
||||
outptr[2] = dcval;
|
||||
outptr[3] = dcval;
|
||||
outptr[4] = dcval;
|
||||
outptr[5] = dcval;
|
||||
outptr[6] = dcval;
|
||||
outptr[7] = dcval;
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
|
||||
tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
|
||||
|
||||
tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
|
||||
tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562)
|
||||
- tmp13;
|
||||
|
||||
tmp0 = tmp10 + tmp13;
|
||||
tmp3 = tmp10 - tmp13;
|
||||
tmp1 = tmp11 + tmp12;
|
||||
tmp2 = tmp11 - tmp12;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
|
||||
z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
|
||||
z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
|
||||
z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
|
||||
|
||||
tmp7 = z11 + z13; /* phase 5 */
|
||||
tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
|
||||
|
||||
z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
|
||||
tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
|
||||
tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
|
||||
|
||||
tmp6 = tmp12 - tmp7; /* phase 2 */
|
||||
tmp5 = tmp11 - tmp6;
|
||||
tmp4 = tmp10 + tmp5;
|
||||
|
||||
/* Final output stage: scale down by a factor of 8 and range-limit */
|
||||
|
||||
outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_IFAST_SUPPORTED */
|
||||
/*
|
||||
* jidctfst.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, 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 a fast, not so accurate integer implementation of the
|
||||
* inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
|
||||
* must also perform dequantization of the input coefficients.
|
||||
*
|
||||
* A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
|
||||
* on each row (or vice versa, but it's more convenient to emit a row at
|
||||
* a time). Direct algorithms are also available, but they are much more
|
||||
* complex and seem not to be any faster when reduced to code.
|
||||
*
|
||||
* This implementation is based on Arai, Agui, and Nakajima's algorithm for
|
||||
* scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
|
||||
* Japanese, but the algorithm is described in the Pennebaker & Mitchell
|
||||
* JPEG textbook (see REFERENCES section in file README). The following code
|
||||
* is based directly on figure 4-8 in P&M.
|
||||
* While an 8-point DCT cannot be done in less than 11 multiplies, it is
|
||||
* possible to arrange the computation so that many of the multiplies are
|
||||
* simple scalings of the final outputs. These multiplies can then be
|
||||
* folded into the multiplications or divisions by the JPEG quantization
|
||||
* table entries. The AA&N method leaves only 5 multiplies and 29 adds
|
||||
* to be done in the DCT itself.
|
||||
* The primary disadvantage of this method is that with fixed-point math,
|
||||
* accuracy is lost due to imprecise representation of the scaled
|
||||
* quantization values. The smaller the quantization table entry, the less
|
||||
* precise the scaled value, so this implementation does worse with high-
|
||||
* quality-setting files than with low-quality ones.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/* Scaling decisions are generally the same as in the LL&M algorithm;
|
||||
* see jidctint.c for more details. However, we choose to descale
|
||||
* (right shift) multiplication products as soon as they are formed,
|
||||
* rather than carrying additional fractional bits into subsequent additions.
|
||||
* This compromises accuracy slightly, but it lets us save a few shifts.
|
||||
* More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
|
||||
* everywhere except in the multiplications proper; this saves a good deal
|
||||
* of work on 16-bit-int machines.
|
||||
*
|
||||
* The dequantized coefficients are not integers because the AA&N scaling
|
||||
* factors have been incorporated. We represent them scaled up by PASS1_BITS,
|
||||
* so that the first and second IDCT rounds have the same input scaling.
|
||||
* For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to
|
||||
* avoid a descaling shift; this compromises accuracy rather drastically
|
||||
* for small quantization table entries, but it saves a lot of shifts.
|
||||
* For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway,
|
||||
* so we use a much larger scaling factor to preserve accuracy.
|
||||
*
|
||||
* A final compromise is to represent the multiplicative constants to only
|
||||
* 8 fractional bits, rather than 13. This saves some shifting work on some
|
||||
* machines, and may also reduce the cost of multiplication (since there
|
||||
* are fewer one-bits in the constants).
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define CONST_BITS 8
|
||||
#define PASS1_BITS 2
|
||||
#else
|
||||
#define CONST_BITS 8
|
||||
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
|
||||
#endif
|
||||
|
||||
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
|
||||
* causing a lot of useless floating-point operations at run time.
|
||||
* To get around this we use the following pre-calculated constants.
|
||||
* If you change CONST_BITS you may want to add appropriate values.
|
||||
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
|
||||
*/
|
||||
|
||||
#if CONST_BITS == 8
|
||||
#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */
|
||||
#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */
|
||||
#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */
|
||||
#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */
|
||||
#else
|
||||
#define FIX_1_082392200 FIX(1.082392200)
|
||||
#define FIX_1_414213562 FIX(1.414213562)
|
||||
#define FIX_1_847759065 FIX(1.847759065)
|
||||
#define FIX_2_613125930 FIX(2.613125930)
|
||||
#endif
|
||||
|
||||
|
||||
/* We can gain a little more speed, with a further compromise in accuracy,
|
||||
* by omitting the addition in a descaling shift. This yields an incorrectly
|
||||
* rounded result half the time...
|
||||
*/
|
||||
|
||||
#ifndef USE_ACCURATE_ROUNDING
|
||||
#undef DESCALE
|
||||
#define DESCALE(x,n) RIGHT_SHIFT(x, n)
|
||||
#endif
|
||||
|
||||
|
||||
/* Multiply a DCTELEM variable by an INT32 constant, and immediately
|
||||
* descale to yield a DCTELEM result.
|
||||
*/
|
||||
|
||||
#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
|
||||
|
||||
|
||||
/* Dequantize a coefficient by multiplying it by the multiplier-table
|
||||
* entry; produce a DCTELEM result. For 8-bit data a 16x16->16
|
||||
* multiplication will do. For 12-bit data, the multiplier table is
|
||||
* declared INT32, so a 32-bit multiply will be used.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval))
|
||||
#else
|
||||
#define DEQUANTIZE(coef,quantval) \
|
||||
DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS)
|
||||
#endif
|
||||
|
||||
|
||||
/* Like DESCALE, but applies to a DCTELEM and produces an int.
|
||||
* We assume that int right shift is unsigned if INT32 right shift is.
|
||||
*/
|
||||
|
||||
#ifdef RIGHT_SHIFT_IS_UNSIGNED
|
||||
#define ISHIFT_TEMPS DCTELEM ishift_temp;
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */
|
||||
#else
|
||||
#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */
|
||||
#endif
|
||||
#define IRIGHT_SHIFT(x,shft) \
|
||||
((ishift_temp = (x)) < 0 ? \
|
||||
(ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \
|
||||
(ishift_temp >> (shft)))
|
||||
#else
|
||||
#define ISHIFT_TEMPS
|
||||
#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
|
||||
#endif
|
||||
|
||||
#ifdef USE_ACCURATE_ROUNDING
|
||||
#define IDESCALE(x,n) ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n))
|
||||
#else
|
||||
#define IDESCALE(x,n) ((int) IRIGHT_SHIFT(x, n))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
DCTELEM tmp10, tmp11, tmp12, tmp13;
|
||||
DCTELEM z5, z10, z11, z12, z13;
|
||||
JCOEFPTR inptr;
|
||||
IFAST_MULT_TYPE * quantptr;
|
||||
int * wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE2]; /* buffers data between passes */
|
||||
SHIFT_TEMPS /* for DESCALE */
|
||||
ISHIFT_TEMPS /* for IDESCALE */
|
||||
|
||||
/* Pass 1: process columns from input, store into work array. */
|
||||
|
||||
inptr = coef_block;
|
||||
quantptr = (IFAST_MULT_TYPE *) compptr->dct_table;
|
||||
wsptr = workspace;
|
||||
for (ctr = DCTSIZE; ctr > 0; ctr--) {
|
||||
/* Due to quantization, we will usually find that many of the input
|
||||
* coefficients are zero, especially the AC terms. We can exploit this
|
||||
* by short-circuiting the IDCT calculation for any column in which all
|
||||
* the AC terms are zero. In that case each output is equal to the
|
||||
* DC coefficient (with scale factor as needed).
|
||||
* With typical images and quantization tables, half or more of the
|
||||
* column DCT calculations can be simplified this way.
|
||||
*/
|
||||
|
||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
|
||||
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
|
||||
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
|
||||
inptr[DCTSIZE*7] == 0) {
|
||||
/* AC terms all zero */
|
||||
int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
|
||||
wsptr[DCTSIZE*0] = dcval;
|
||||
wsptr[DCTSIZE*1] = dcval;
|
||||
wsptr[DCTSIZE*2] = dcval;
|
||||
wsptr[DCTSIZE*3] = dcval;
|
||||
wsptr[DCTSIZE*4] = dcval;
|
||||
wsptr[DCTSIZE*5] = dcval;
|
||||
wsptr[DCTSIZE*6] = dcval;
|
||||
wsptr[DCTSIZE*7] = dcval;
|
||||
|
||||
inptr++; /* advance pointers to next column */
|
||||
quantptr++;
|
||||
wsptr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
|
||||
tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
|
||||
tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
|
||||
|
||||
tmp10 = tmp0 + tmp2; /* phase 3 */
|
||||
tmp11 = tmp0 - tmp2;
|
||||
|
||||
tmp13 = tmp1 + tmp3; /* phases 5-3 */
|
||||
tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
|
||||
|
||||
tmp0 = tmp10 + tmp13; /* phase 2 */
|
||||
tmp3 = tmp10 - tmp13;
|
||||
tmp1 = tmp11 + tmp12;
|
||||
tmp2 = tmp11 - tmp12;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
||||
tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
||||
tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
||||
tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
||||
|
||||
z13 = tmp6 + tmp5; /* phase 6 */
|
||||
z10 = tmp6 - tmp5;
|
||||
z11 = tmp4 + tmp7;
|
||||
z12 = tmp4 - tmp7;
|
||||
|
||||
tmp7 = z11 + z13; /* phase 5 */
|
||||
tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
|
||||
|
||||
z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
|
||||
tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
|
||||
tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
|
||||
|
||||
tmp6 = tmp12 - tmp7; /* phase 2 */
|
||||
tmp5 = tmp11 - tmp6;
|
||||
tmp4 = tmp10 + tmp5;
|
||||
|
||||
wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
|
||||
wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
|
||||
wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
|
||||
wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
|
||||
wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
|
||||
wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
|
||||
wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
|
||||
wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
|
||||
|
||||
inptr++; /* advance pointers to next column */
|
||||
quantptr++;
|
||||
wsptr++;
|
||||
}
|
||||
|
||||
/* Pass 2: process rows from work array, store into output array. */
|
||||
/* Note that we must descale the results by a factor of 8 == 2**3, */
|
||||
/* and also undo the PASS1_BITS scaling. */
|
||||
|
||||
wsptr = workspace;
|
||||
for (ctr = 0; ctr < DCTSIZE; ctr++) {
|
||||
outptr = output_buf[ctr] + output_col;
|
||||
/* Rows of zeroes can be exploited in the same way as we did with columns.
|
||||
* However, the column calculation has created many nonzero AC terms, so
|
||||
* the simplification applies less often (typically 5% to 10% of the time).
|
||||
* On machines with very fast multiplication, it's possible that the
|
||||
* test takes more time than it's worth. In that case this section
|
||||
* may be commented out.
|
||||
*/
|
||||
|
||||
#ifndef NO_ZERO_ROW_TEST
|
||||
if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
|
||||
wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
|
||||
/* AC terms all zero */
|
||||
JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
outptr[1] = dcval;
|
||||
outptr[2] = dcval;
|
||||
outptr[3] = dcval;
|
||||
outptr[4] = dcval;
|
||||
outptr[5] = dcval;
|
||||
outptr[6] = dcval;
|
||||
outptr[7] = dcval;
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
|
||||
tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
|
||||
|
||||
tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
|
||||
tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562)
|
||||
- tmp13;
|
||||
|
||||
tmp0 = tmp10 + tmp13;
|
||||
tmp3 = tmp10 - tmp13;
|
||||
tmp1 = tmp11 + tmp12;
|
||||
tmp2 = tmp11 - tmp12;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
|
||||
z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
|
||||
z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
|
||||
z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
|
||||
|
||||
tmp7 = z11 + z13; /* phase 5 */
|
||||
tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
|
||||
|
||||
z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
|
||||
tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
|
||||
tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
|
||||
|
||||
tmp6 = tmp12 - tmp7; /* phase 2 */
|
||||
tmp5 = tmp11 - tmp6;
|
||||
tmp4 = tmp10 + tmp5;
|
||||
|
||||
/* Final output stage: scale down by a factor of 8 and range-limit */
|
||||
|
||||
outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_IFAST_SUPPORTED */
|
||||
|
@ -1,389 +1,389 @@
|
||||
/*
|
||||
* jidctint.c
|
||||
*
|
||||
* Copyright (C) 1991-1998, 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 a slow-but-accurate integer implementation of the
|
||||
* inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
|
||||
* must also perform dequantization of the input coefficients.
|
||||
*
|
||||
* A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
|
||||
* on each row (or vice versa, but it's more convenient to emit a row at
|
||||
* a time). Direct algorithms are also available, but they are much more
|
||||
* complex and seem not to be any faster when reduced to code.
|
||||
*
|
||||
* This implementation is based on an algorithm described in
|
||||
* C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
|
||||
* Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
|
||||
* Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
|
||||
* The primary algorithm described there uses 11 multiplies and 29 adds.
|
||||
* We use their alternate method with 12 multiplies and 32 adds.
|
||||
* The advantage of this method is that no data path contains more than one
|
||||
* multiplication; this allows a very simple and accurate implementation in
|
||||
* scaled fixed-point arithmetic, with a minimal number of shifts.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* The poop on this scaling stuff is as follows:
|
||||
*
|
||||
* Each 1-D IDCT step produces outputs which are a factor of sqrt(N)
|
||||
* larger than the true IDCT outputs. The final outputs are therefore
|
||||
* a factor of N larger than desired; since N=8 this can be cured by
|
||||
* a simple right shift at the end of the algorithm. The advantage of
|
||||
* this arrangement is that we save two multiplications per 1-D IDCT,
|
||||
* because the y0 and y4 inputs need not be divided by sqrt(N).
|
||||
*
|
||||
* We have to do addition and subtraction of the integer inputs, which
|
||||
* is no problem, and multiplication by fractional constants, which is
|
||||
* a problem to do in integer arithmetic. We multiply all the constants
|
||||
* by CONST_SCALE and convert them to integer constants (thus retaining
|
||||
* CONST_BITS bits of precision in the constants). After doing a
|
||||
* multiplication we have to divide the product by CONST_SCALE, with proper
|
||||
* rounding, to produce the correct output. This division can be done
|
||||
* cheaply as a right shift of CONST_BITS bits. We postpone shifting
|
||||
* as long as possible so that partial sums can be added together with
|
||||
* full fractional precision.
|
||||
*
|
||||
* The outputs of the first pass are scaled up by PASS1_BITS bits so that
|
||||
* they are represented to better-than-integral precision. These outputs
|
||||
* require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
|
||||
* with the recommended scaling. (To scale up 12-bit sample data further, an
|
||||
* intermediate INT32 array would be needed.)
|
||||
*
|
||||
* To avoid overflow of the 32-bit intermediate results in pass 2, we must
|
||||
* have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
|
||||
* shows that the values given below are the most effective.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 2
|
||||
#else
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
|
||||
#endif
|
||||
|
||||
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
|
||||
* causing a lot of useless floating-point operations at run time.
|
||||
* To get around this we use the following pre-calculated constants.
|
||||
* If you change CONST_BITS you may want to add appropriate values.
|
||||
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
|
||||
*/
|
||||
|
||||
#if CONST_BITS == 13
|
||||
#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */
|
||||
#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
|
||||
#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */
|
||||
#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
|
||||
#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
|
||||
#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */
|
||||
#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */
|
||||
#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
|
||||
#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */
|
||||
#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */
|
||||
#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
|
||||
#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */
|
||||
#else
|
||||
#define FIX_0_298631336 FIX(0.298631336)
|
||||
#define FIX_0_390180644 FIX(0.390180644)
|
||||
#define FIX_0_541196100 FIX(0.541196100)
|
||||
#define FIX_0_765366865 FIX(0.765366865)
|
||||
#define FIX_0_899976223 FIX(0.899976223)
|
||||
#define FIX_1_175875602 FIX(1.175875602)
|
||||
#define FIX_1_501321110 FIX(1.501321110)
|
||||
#define FIX_1_847759065 FIX(1.847759065)
|
||||
#define FIX_1_961570560 FIX(1.961570560)
|
||||
#define FIX_2_053119869 FIX(2.053119869)
|
||||
#define FIX_2_562915447 FIX(2.562915447)
|
||||
#define FIX_3_072711026 FIX(3.072711026)
|
||||
#endif
|
||||
|
||||
|
||||
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
|
||||
* For 8-bit samples with the recommended scaling, all the variable
|
||||
* and constant values involved are no more than 16 bits wide, so a
|
||||
* 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
|
||||
* For 12-bit samples, a full 32-bit multiplication will be needed.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
|
||||
#else
|
||||
#define MULTIPLY(var,const) ((var) * (const))
|
||||
#endif
|
||||
|
||||
|
||||
/* Dequantize a coefficient by multiplying it by the multiplier-table
|
||||
* entry; produce an int result. In this module, both inputs and result
|
||||
* are 16 bits or less, so either int or short multiply will work.
|
||||
*/
|
||||
|
||||
#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval))
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
INT32 tmp0, tmp1, tmp2, tmp3;
|
||||
INT32 tmp10, tmp11, tmp12, tmp13;
|
||||
INT32 z1, z2, z3, z4, z5;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE * quantptr;
|
||||
int * wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE2]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process columns from input, store into work array. */
|
||||
/* Note results are scaled up by sqrt(8) compared to a true IDCT; */
|
||||
/* furthermore, we scale the results by 2**PASS1_BITS. */
|
||||
|
||||
inptr = coef_block;
|
||||
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
||||
wsptr = workspace;
|
||||
for (ctr = DCTSIZE; ctr > 0; ctr--) {
|
||||
/* Due to quantization, we will usually find that many of the input
|
||||
* coefficients are zero, especially the AC terms. We can exploit this
|
||||
* by short-circuiting the IDCT calculation for any column in which all
|
||||
* the AC terms are zero. In that case each output is equal to the
|
||||
* DC coefficient (with scale factor as needed).
|
||||
* With typical images and quantization tables, half or more of the
|
||||
* column DCT calculations can be simplified this way.
|
||||
*/
|
||||
|
||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
|
||||
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
|
||||
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
|
||||
inptr[DCTSIZE*7] == 0) {
|
||||
/* AC terms all zero */
|
||||
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
|
||||
|
||||
wsptr[DCTSIZE*0] = dcval;
|
||||
wsptr[DCTSIZE*1] = dcval;
|
||||
wsptr[DCTSIZE*2] = dcval;
|
||||
wsptr[DCTSIZE*3] = dcval;
|
||||
wsptr[DCTSIZE*4] = dcval;
|
||||
wsptr[DCTSIZE*5] = dcval;
|
||||
wsptr[DCTSIZE*6] = dcval;
|
||||
wsptr[DCTSIZE*7] = dcval;
|
||||
|
||||
inptr++; /* advance pointers to next column */
|
||||
quantptr++;
|
||||
wsptr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Even part: reverse the even part of the forward DCT. */
|
||||
/* The rotator is sqrt(2)*c(-6). */
|
||||
|
||||
z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
|
||||
z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
|
||||
|
||||
z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
|
||||
tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
|
||||
tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
|
||||
|
||||
z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
|
||||
|
||||
tmp0 = (z2 + z3) << CONST_BITS;
|
||||
tmp1 = (z2 - z3) << CONST_BITS;
|
||||
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
/* Odd part per figure 8; the matrix is unitary and hence its
|
||||
* transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
|
||||
*/
|
||||
|
||||
tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
||||
tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
||||
tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
||||
tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
||||
|
||||
z1 = tmp0 + tmp3;
|
||||
z2 = tmp1 + tmp2;
|
||||
z3 = tmp0 + tmp2;
|
||||
z4 = tmp1 + tmp3;
|
||||
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
|
||||
|
||||
tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
|
||||
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
|
||||
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
|
||||
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
|
||||
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
|
||||
/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
|
||||
|
||||
wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
|
||||
|
||||
inptr++; /* advance pointers to next column */
|
||||
quantptr++;
|
||||
wsptr++;
|
||||
}
|
||||
|
||||
/* Pass 2: process rows from work array, store into output array. */
|
||||
/* Note that we must descale the results by a factor of 8 == 2**3, */
|
||||
/* and also undo the PASS1_BITS scaling. */
|
||||
|
||||
wsptr = workspace;
|
||||
for (ctr = 0; ctr < DCTSIZE; ctr++) {
|
||||
outptr = output_buf[ctr] + output_col;
|
||||
/* Rows of zeroes can be exploited in the same way as we did with columns.
|
||||
* However, the column calculation has created many nonzero AC terms, so
|
||||
* the simplification applies less often (typically 5% to 10% of the time).
|
||||
* On machines with very fast multiplication, it's possible that the
|
||||
* test takes more time than it's worth. In that case this section
|
||||
* may be commented out.
|
||||
*/
|
||||
|
||||
#ifndef NO_ZERO_ROW_TEST
|
||||
if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
|
||||
wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
|
||||
/* AC terms all zero */
|
||||
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
outptr[1] = dcval;
|
||||
outptr[2] = dcval;
|
||||
outptr[3] = dcval;
|
||||
outptr[4] = dcval;
|
||||
outptr[5] = dcval;
|
||||
outptr[6] = dcval;
|
||||
outptr[7] = dcval;
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Even part: reverse the even part of the forward DCT. */
|
||||
/* The rotator is sqrt(2)*c(-6). */
|
||||
|
||||
z2 = (INT32) wsptr[2];
|
||||
z3 = (INT32) wsptr[6];
|
||||
|
||||
z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
|
||||
tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
|
||||
tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
|
||||
|
||||
tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS;
|
||||
tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS;
|
||||
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
/* Odd part per figure 8; the matrix is unitary and hence its
|
||||
* transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
|
||||
*/
|
||||
|
||||
tmp0 = (INT32) wsptr[7];
|
||||
tmp1 = (INT32) wsptr[5];
|
||||
tmp2 = (INT32) wsptr[3];
|
||||
tmp3 = (INT32) wsptr[1];
|
||||
|
||||
z1 = tmp0 + tmp3;
|
||||
z2 = tmp1 + tmp2;
|
||||
z3 = tmp0 + tmp2;
|
||||
z4 = tmp1 + tmp3;
|
||||
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
|
||||
|
||||
tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
|
||||
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
|
||||
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
|
||||
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
|
||||
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
|
||||
/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
|
||||
|
||||
outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_ISLOW_SUPPORTED */
|
||||
/*
|
||||
* jidctint.c
|
||||
*
|
||||
* Copyright (C) 1991-1998, 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 a slow-but-accurate integer implementation of the
|
||||
* inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
|
||||
* must also perform dequantization of the input coefficients.
|
||||
*
|
||||
* A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
|
||||
* on each row (or vice versa, but it's more convenient to emit a row at
|
||||
* a time). Direct algorithms are also available, but they are much more
|
||||
* complex and seem not to be any faster when reduced to code.
|
||||
*
|
||||
* This implementation is based on an algorithm described in
|
||||
* C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
|
||||
* Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
|
||||
* Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
|
||||
* The primary algorithm described there uses 11 multiplies and 29 adds.
|
||||
* We use their alternate method with 12 multiplies and 32 adds.
|
||||
* The advantage of this method is that no data path contains more than one
|
||||
* multiplication; this allows a very simple and accurate implementation in
|
||||
* scaled fixed-point arithmetic, with a minimal number of shifts.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* The poop on this scaling stuff is as follows:
|
||||
*
|
||||
* Each 1-D IDCT step produces outputs which are a factor of sqrt(N)
|
||||
* larger than the true IDCT outputs. The final outputs are therefore
|
||||
* a factor of N larger than desired; since N=8 this can be cured by
|
||||
* a simple right shift at the end of the algorithm. The advantage of
|
||||
* this arrangement is that we save two multiplications per 1-D IDCT,
|
||||
* because the y0 and y4 inputs need not be divided by sqrt(N).
|
||||
*
|
||||
* We have to do addition and subtraction of the integer inputs, which
|
||||
* is no problem, and multiplication by fractional constants, which is
|
||||
* a problem to do in integer arithmetic. We multiply all the constants
|
||||
* by CONST_SCALE and convert them to integer constants (thus retaining
|
||||
* CONST_BITS bits of precision in the constants). After doing a
|
||||
* multiplication we have to divide the product by CONST_SCALE, with proper
|
||||
* rounding, to produce the correct output. This division can be done
|
||||
* cheaply as a right shift of CONST_BITS bits. We postpone shifting
|
||||
* as long as possible so that partial sums can be added together with
|
||||
* full fractional precision.
|
||||
*
|
||||
* The outputs of the first pass are scaled up by PASS1_BITS bits so that
|
||||
* they are represented to better-than-integral precision. These outputs
|
||||
* require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
|
||||
* with the recommended scaling. (To scale up 12-bit sample data further, an
|
||||
* intermediate INT32 array would be needed.)
|
||||
*
|
||||
* To avoid overflow of the 32-bit intermediate results in pass 2, we must
|
||||
* have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
|
||||
* shows that the values given below are the most effective.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 2
|
||||
#else
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
|
||||
#endif
|
||||
|
||||
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
|
||||
* causing a lot of useless floating-point operations at run time.
|
||||
* To get around this we use the following pre-calculated constants.
|
||||
* If you change CONST_BITS you may want to add appropriate values.
|
||||
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
|
||||
*/
|
||||
|
||||
#if CONST_BITS == 13
|
||||
#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */
|
||||
#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
|
||||
#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */
|
||||
#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
|
||||
#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
|
||||
#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */
|
||||
#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */
|
||||
#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
|
||||
#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */
|
||||
#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */
|
||||
#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
|
||||
#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */
|
||||
#else
|
||||
#define FIX_0_298631336 FIX(0.298631336)
|
||||
#define FIX_0_390180644 FIX(0.390180644)
|
||||
#define FIX_0_541196100 FIX(0.541196100)
|
||||
#define FIX_0_765366865 FIX(0.765366865)
|
||||
#define FIX_0_899976223 FIX(0.899976223)
|
||||
#define FIX_1_175875602 FIX(1.175875602)
|
||||
#define FIX_1_501321110 FIX(1.501321110)
|
||||
#define FIX_1_847759065 FIX(1.847759065)
|
||||
#define FIX_1_961570560 FIX(1.961570560)
|
||||
#define FIX_2_053119869 FIX(2.053119869)
|
||||
#define FIX_2_562915447 FIX(2.562915447)
|
||||
#define FIX_3_072711026 FIX(3.072711026)
|
||||
#endif
|
||||
|
||||
|
||||
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
|
||||
* For 8-bit samples with the recommended scaling, all the variable
|
||||
* and constant values involved are no more than 16 bits wide, so a
|
||||
* 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
|
||||
* For 12-bit samples, a full 32-bit multiplication will be needed.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
|
||||
#else
|
||||
#define MULTIPLY(var,const) ((var) * (const))
|
||||
#endif
|
||||
|
||||
|
||||
/* Dequantize a coefficient by multiplying it by the multiplier-table
|
||||
* entry; produce an int result. In this module, both inputs and result
|
||||
* are 16 bits or less, so either int or short multiply will work.
|
||||
*/
|
||||
|
||||
#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval))
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
INT32 tmp0, tmp1, tmp2, tmp3;
|
||||
INT32 tmp10, tmp11, tmp12, tmp13;
|
||||
INT32 z1, z2, z3, z4, z5;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE * quantptr;
|
||||
int * wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE2]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process columns from input, store into work array. */
|
||||
/* Note results are scaled up by sqrt(8) compared to a true IDCT; */
|
||||
/* furthermore, we scale the results by 2**PASS1_BITS. */
|
||||
|
||||
inptr = coef_block;
|
||||
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
||||
wsptr = workspace;
|
||||
for (ctr = DCTSIZE; ctr > 0; ctr--) {
|
||||
/* Due to quantization, we will usually find that many of the input
|
||||
* coefficients are zero, especially the AC terms. We can exploit this
|
||||
* by short-circuiting the IDCT calculation for any column in which all
|
||||
* the AC terms are zero. In that case each output is equal to the
|
||||
* DC coefficient (with scale factor as needed).
|
||||
* With typical images and quantization tables, half or more of the
|
||||
* column DCT calculations can be simplified this way.
|
||||
*/
|
||||
|
||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
|
||||
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
|
||||
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
|
||||
inptr[DCTSIZE*7] == 0) {
|
||||
/* AC terms all zero */
|
||||
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
|
||||
|
||||
wsptr[DCTSIZE*0] = dcval;
|
||||
wsptr[DCTSIZE*1] = dcval;
|
||||
wsptr[DCTSIZE*2] = dcval;
|
||||
wsptr[DCTSIZE*3] = dcval;
|
||||
wsptr[DCTSIZE*4] = dcval;
|
||||
wsptr[DCTSIZE*5] = dcval;
|
||||
wsptr[DCTSIZE*6] = dcval;
|
||||
wsptr[DCTSIZE*7] = dcval;
|
||||
|
||||
inptr++; /* advance pointers to next column */
|
||||
quantptr++;
|
||||
wsptr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Even part: reverse the even part of the forward DCT. */
|
||||
/* The rotator is sqrt(2)*c(-6). */
|
||||
|
||||
z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
|
||||
z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
|
||||
|
||||
z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
|
||||
tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
|
||||
tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
|
||||
|
||||
z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
|
||||
|
||||
tmp0 = (z2 + z3) << CONST_BITS;
|
||||
tmp1 = (z2 - z3) << CONST_BITS;
|
||||
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
/* Odd part per figure 8; the matrix is unitary and hence its
|
||||
* transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
|
||||
*/
|
||||
|
||||
tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
||||
tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
||||
tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
||||
tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
||||
|
||||
z1 = tmp0 + tmp3;
|
||||
z2 = tmp1 + tmp2;
|
||||
z3 = tmp0 + tmp2;
|
||||
z4 = tmp1 + tmp3;
|
||||
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
|
||||
|
||||
tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
|
||||
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
|
||||
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
|
||||
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
|
||||
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
|
||||
/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
|
||||
|
||||
wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
|
||||
wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
|
||||
|
||||
inptr++; /* advance pointers to next column */
|
||||
quantptr++;
|
||||
wsptr++;
|
||||
}
|
||||
|
||||
/* Pass 2: process rows from work array, store into output array. */
|
||||
/* Note that we must descale the results by a factor of 8 == 2**3, */
|
||||
/* and also undo the PASS1_BITS scaling. */
|
||||
|
||||
wsptr = workspace;
|
||||
for (ctr = 0; ctr < DCTSIZE; ctr++) {
|
||||
outptr = output_buf[ctr] + output_col;
|
||||
/* Rows of zeroes can be exploited in the same way as we did with columns.
|
||||
* However, the column calculation has created many nonzero AC terms, so
|
||||
* the simplification applies less often (typically 5% to 10% of the time).
|
||||
* On machines with very fast multiplication, it's possible that the
|
||||
* test takes more time than it's worth. In that case this section
|
||||
* may be commented out.
|
||||
*/
|
||||
|
||||
#ifndef NO_ZERO_ROW_TEST
|
||||
if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
|
||||
wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
|
||||
/* AC terms all zero */
|
||||
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
outptr[1] = dcval;
|
||||
outptr[2] = dcval;
|
||||
outptr[3] = dcval;
|
||||
outptr[4] = dcval;
|
||||
outptr[5] = dcval;
|
||||
outptr[6] = dcval;
|
||||
outptr[7] = dcval;
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Even part: reverse the even part of the forward DCT. */
|
||||
/* The rotator is sqrt(2)*c(-6). */
|
||||
|
||||
z2 = (INT32) wsptr[2];
|
||||
z3 = (INT32) wsptr[6];
|
||||
|
||||
z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
|
||||
tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
|
||||
tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
|
||||
|
||||
tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS;
|
||||
tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS;
|
||||
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
/* Odd part per figure 8; the matrix is unitary and hence its
|
||||
* transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
|
||||
*/
|
||||
|
||||
tmp0 = (INT32) wsptr[7];
|
||||
tmp1 = (INT32) wsptr[5];
|
||||
tmp2 = (INT32) wsptr[3];
|
||||
tmp3 = (INT32) wsptr[1];
|
||||
|
||||
z1 = tmp0 + tmp3;
|
||||
z2 = tmp1 + tmp2;
|
||||
z3 = tmp0 + tmp2;
|
||||
z4 = tmp1 + tmp3;
|
||||
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
|
||||
|
||||
tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
|
||||
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
|
||||
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
|
||||
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
|
||||
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
|
||||
/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
|
||||
|
||||
outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0,
|
||||
CONST_BITS+PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_ISLOW_SUPPORTED */
|
||||
|
@ -1,398 +1,398 @@
|
||||
/*
|
||||
* jidctred.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, 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 inverse-DCT routines that produce reduced-size output:
|
||||
* either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block.
|
||||
*
|
||||
* The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M)
|
||||
* algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step
|
||||
* with an 8-to-4 step that produces the four averages of two adjacent outputs
|
||||
* (or an 8-to-2 step producing two averages of four outputs, for 2x2 output).
|
||||
* These steps were derived by computing the corresponding values at the end
|
||||
* of the normal LL&M code, then simplifying as much as possible.
|
||||
*
|
||||
* 1x1 is trivial: just take the DC coefficient divided by 8.
|
||||
*
|
||||
* See jidctint.c for additional comments.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/* Scaling is the same as in jidctint.c. */
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 2
|
||||
#else
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
|
||||
#endif
|
||||
|
||||
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
|
||||
* causing a lot of useless floating-point operations at run time.
|
||||
* To get around this we use the following pre-calculated constants.
|
||||
* If you change CONST_BITS you may want to add appropriate values.
|
||||
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
|
||||
*/
|
||||
|
||||
#if CONST_BITS == 13
|
||||
#define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */
|
||||
#define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */
|
||||
#define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */
|
||||
#define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */
|
||||
#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
|
||||
#define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */
|
||||
#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
|
||||
#define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */
|
||||
#define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */
|
||||
#define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */
|
||||
#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
|
||||
#define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */
|
||||
#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
|
||||
#define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */
|
||||
#else
|
||||
#define FIX_0_211164243 FIX(0.211164243)
|
||||
#define FIX_0_509795579 FIX(0.509795579)
|
||||
#define FIX_0_601344887 FIX(0.601344887)
|
||||
#define FIX_0_720959822 FIX(0.720959822)
|
||||
#define FIX_0_765366865 FIX(0.765366865)
|
||||
#define FIX_0_850430095 FIX(0.850430095)
|
||||
#define FIX_0_899976223 FIX(0.899976223)
|
||||
#define FIX_1_061594337 FIX(1.061594337)
|
||||
#define FIX_1_272758580 FIX(1.272758580)
|
||||
#define FIX_1_451774981 FIX(1.451774981)
|
||||
#define FIX_1_847759065 FIX(1.847759065)
|
||||
#define FIX_2_172734803 FIX(2.172734803)
|
||||
#define FIX_2_562915447 FIX(2.562915447)
|
||||
#define FIX_3_624509785 FIX(3.624509785)
|
||||
#endif
|
||||
|
||||
|
||||
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
|
||||
* For 8-bit samples with the recommended scaling, all the variable
|
||||
* and constant values involved are no more than 16 bits wide, so a
|
||||
* 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
|
||||
* For 12-bit samples, a full 32-bit multiplication will be needed.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
|
||||
#else
|
||||
#define MULTIPLY(var,const) ((var) * (const))
|
||||
#endif
|
||||
|
||||
|
||||
/* Dequantize a coefficient by multiplying it by the multiplier-table
|
||||
* entry; produce an int result. In this module, both inputs and result
|
||||
* are 16 bits or less, so either int or short multiply will work.
|
||||
*/
|
||||
|
||||
#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval))
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a reduced-size 4x4 output block.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
INT32 tmp0, tmp2, tmp10, tmp12;
|
||||
INT32 z1, z2, z3, z4;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE * quantptr;
|
||||
int * wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE*4]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process columns from input, store into work array. */
|
||||
|
||||
inptr = coef_block;
|
||||
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
||||
wsptr = workspace;
|
||||
for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
|
||||
/* Don't bother to process column 4, because second pass won't use it */
|
||||
if (ctr == DCTSIZE-4)
|
||||
continue;
|
||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
|
||||
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 &&
|
||||
inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) {
|
||||
/* AC terms all zero; we need not examine term 4 for 4x4 output */
|
||||
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
|
||||
|
||||
wsptr[DCTSIZE*0] = dcval;
|
||||
wsptr[DCTSIZE*1] = dcval;
|
||||
wsptr[DCTSIZE*2] = dcval;
|
||||
wsptr[DCTSIZE*3] = dcval;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
tmp0 <<= (CONST_BITS+1);
|
||||
|
||||
z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
|
||||
z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
|
||||
|
||||
tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865);
|
||||
|
||||
tmp10 = tmp0 + tmp2;
|
||||
tmp12 = tmp0 - tmp2;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
||||
z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
||||
z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
||||
z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
||||
|
||||
tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
|
||||
+ MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
|
||||
+ MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
|
||||
+ MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
|
||||
|
||||
tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
|
||||
+ MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
|
||||
+ MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
|
||||
+ MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
|
||||
|
||||
/* Final output stage */
|
||||
|
||||
wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1);
|
||||
wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1);
|
||||
wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1);
|
||||
wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1);
|
||||
}
|
||||
|
||||
/* Pass 2: process 4 rows from work array, store into output array. */
|
||||
|
||||
wsptr = workspace;
|
||||
for (ctr = 0; ctr < 4; ctr++) {
|
||||
outptr = output_buf[ctr] + output_col;
|
||||
/* It's not clear whether a zero row test is worthwhile here ... */
|
||||
|
||||
#ifndef NO_ZERO_ROW_TEST
|
||||
if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 &&
|
||||
wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
|
||||
/* AC terms all zero */
|
||||
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
outptr[1] = dcval;
|
||||
outptr[2] = dcval;
|
||||
outptr[3] = dcval;
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1);
|
||||
|
||||
tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065)
|
||||
+ MULTIPLY((INT32) wsptr[6], - FIX_0_765366865);
|
||||
|
||||
tmp10 = tmp0 + tmp2;
|
||||
tmp12 = tmp0 - tmp2;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z1 = (INT32) wsptr[7];
|
||||
z2 = (INT32) wsptr[5];
|
||||
z3 = (INT32) wsptr[3];
|
||||
z4 = (INT32) wsptr[1];
|
||||
|
||||
tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
|
||||
+ MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
|
||||
+ MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
|
||||
+ MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
|
||||
|
||||
tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
|
||||
+ MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
|
||||
+ MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
|
||||
+ MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
|
||||
|
||||
/* Final output stage */
|
||||
|
||||
outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2,
|
||||
CONST_BITS+PASS1_BITS+3+1)
|
||||
& RANGE_MASK];
|
||||
outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2,
|
||||
CONST_BITS+PASS1_BITS+3+1)
|
||||
& RANGE_MASK];
|
||||
outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0,
|
||||
CONST_BITS+PASS1_BITS+3+1)
|
||||
& RANGE_MASK];
|
||||
outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0,
|
||||
CONST_BITS+PASS1_BITS+3+1)
|
||||
& RANGE_MASK];
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a reduced-size 2x2 output block.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
INT32 tmp0, tmp10, z1;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE * quantptr;
|
||||
int * wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE*2]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process columns from input, store into work array. */
|
||||
|
||||
inptr = coef_block;
|
||||
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
||||
wsptr = workspace;
|
||||
for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
|
||||
/* Don't bother to process columns 2,4,6 */
|
||||
if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6)
|
||||
continue;
|
||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 &&
|
||||
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) {
|
||||
/* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */
|
||||
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
|
||||
|
||||
wsptr[DCTSIZE*0] = dcval;
|
||||
wsptr[DCTSIZE*1] = dcval;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Even part */
|
||||
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
tmp10 = z1 << (CONST_BITS+2);
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
||||
tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
||||
tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
||||
tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
||||
tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
|
||||
|
||||
/* Final output stage */
|
||||
|
||||
wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2);
|
||||
wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2);
|
||||
}
|
||||
|
||||
/* Pass 2: process 2 rows from work array, store into output array. */
|
||||
|
||||
wsptr = workspace;
|
||||
for (ctr = 0; ctr < 2; ctr++) {
|
||||
outptr = output_buf[ctr] + output_col;
|
||||
/* It's not clear whether a zero row test is worthwhile here ... */
|
||||
|
||||
#ifndef NO_ZERO_ROW_TEST
|
||||
if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) {
|
||||
/* AC terms all zero */
|
||||
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
outptr[1] = dcval;
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2);
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */
|
||||
+ MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */
|
||||
+ MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */
|
||||
+ MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
|
||||
|
||||
/* Final output stage */
|
||||
|
||||
outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0,
|
||||
CONST_BITS+PASS1_BITS+3+2)
|
||||
& RANGE_MASK];
|
||||
outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0,
|
||||
CONST_BITS+PASS1_BITS+3+2)
|
||||
& RANGE_MASK];
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a reduced-size 1x1 output block.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
int dcval;
|
||||
ISLOW_MULT_TYPE * quantptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* We hardly need an inverse DCT routine for this: just take the
|
||||
* average pixel value, which is one-eighth of the DC coefficient.
|
||||
*/
|
||||
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
||||
dcval = DEQUANTIZE(coef_block[0], quantptr[0]);
|
||||
dcval = (int) DESCALE((INT32) dcval, 3);
|
||||
|
||||
output_buf[0][output_col] = range_limit[dcval & RANGE_MASK];
|
||||
}
|
||||
|
||||
#endif /* IDCT_SCALING_SUPPORTED */
|
||||
/*
|
||||
* jidctred.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, 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 inverse-DCT routines that produce reduced-size output:
|
||||
* either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block.
|
||||
*
|
||||
* The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M)
|
||||
* algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step
|
||||
* with an 8-to-4 step that produces the four averages of two adjacent outputs
|
||||
* (or an 8-to-2 step producing two averages of four outputs, for 2x2 output).
|
||||
* These steps were derived by computing the corresponding values at the end
|
||||
* of the normal LL&M code, then simplifying as much as possible.
|
||||
*
|
||||
* 1x1 is trivial: just take the DC coefficient divided by 8.
|
||||
*
|
||||
* See jidctint.c for additional comments.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/* Scaling is the same as in jidctint.c. */
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 2
|
||||
#else
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
|
||||
#endif
|
||||
|
||||
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
|
||||
* causing a lot of useless floating-point operations at run time.
|
||||
* To get around this we use the following pre-calculated constants.
|
||||
* If you change CONST_BITS you may want to add appropriate values.
|
||||
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
|
||||
*/
|
||||
|
||||
#if CONST_BITS == 13
|
||||
#define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */
|
||||
#define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */
|
||||
#define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */
|
||||
#define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */
|
||||
#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
|
||||
#define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */
|
||||
#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
|
||||
#define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */
|
||||
#define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */
|
||||
#define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */
|
||||
#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
|
||||
#define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */
|
||||
#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
|
||||
#define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */
|
||||
#else
|
||||
#define FIX_0_211164243 FIX(0.211164243)
|
||||
#define FIX_0_509795579 FIX(0.509795579)
|
||||
#define FIX_0_601344887 FIX(0.601344887)
|
||||
#define FIX_0_720959822 FIX(0.720959822)
|
||||
#define FIX_0_765366865 FIX(0.765366865)
|
||||
#define FIX_0_850430095 FIX(0.850430095)
|
||||
#define FIX_0_899976223 FIX(0.899976223)
|
||||
#define FIX_1_061594337 FIX(1.061594337)
|
||||
#define FIX_1_272758580 FIX(1.272758580)
|
||||
#define FIX_1_451774981 FIX(1.451774981)
|
||||
#define FIX_1_847759065 FIX(1.847759065)
|
||||
#define FIX_2_172734803 FIX(2.172734803)
|
||||
#define FIX_2_562915447 FIX(2.562915447)
|
||||
#define FIX_3_624509785 FIX(3.624509785)
|
||||
#endif
|
||||
|
||||
|
||||
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
|
||||
* For 8-bit samples with the recommended scaling, all the variable
|
||||
* and constant values involved are no more than 16 bits wide, so a
|
||||
* 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
|
||||
* For 12-bit samples, a full 32-bit multiplication will be needed.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
|
||||
#else
|
||||
#define MULTIPLY(var,const) ((var) * (const))
|
||||
#endif
|
||||
|
||||
|
||||
/* Dequantize a coefficient by multiplying it by the multiplier-table
|
||||
* entry; produce an int result. In this module, both inputs and result
|
||||
* are 16 bits or less, so either int or short multiply will work.
|
||||
*/
|
||||
|
||||
#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval))
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a reduced-size 4x4 output block.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
INT32 tmp0, tmp2, tmp10, tmp12;
|
||||
INT32 z1, z2, z3, z4;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE * quantptr;
|
||||
int * wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE*4]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process columns from input, store into work array. */
|
||||
|
||||
inptr = coef_block;
|
||||
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
||||
wsptr = workspace;
|
||||
for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
|
||||
/* Don't bother to process column 4, because second pass won't use it */
|
||||
if (ctr == DCTSIZE-4)
|
||||
continue;
|
||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
|
||||
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 &&
|
||||
inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) {
|
||||
/* AC terms all zero; we need not examine term 4 for 4x4 output */
|
||||
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
|
||||
|
||||
wsptr[DCTSIZE*0] = dcval;
|
||||
wsptr[DCTSIZE*1] = dcval;
|
||||
wsptr[DCTSIZE*2] = dcval;
|
||||
wsptr[DCTSIZE*3] = dcval;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
tmp0 <<= (CONST_BITS+1);
|
||||
|
||||
z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
|
||||
z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
|
||||
|
||||
tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865);
|
||||
|
||||
tmp10 = tmp0 + tmp2;
|
||||
tmp12 = tmp0 - tmp2;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
||||
z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
||||
z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
||||
z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
||||
|
||||
tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
|
||||
+ MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
|
||||
+ MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
|
||||
+ MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
|
||||
|
||||
tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
|
||||
+ MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
|
||||
+ MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
|
||||
+ MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
|
||||
|
||||
/* Final output stage */
|
||||
|
||||
wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1);
|
||||
wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1);
|
||||
wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1);
|
||||
wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1);
|
||||
}
|
||||
|
||||
/* Pass 2: process 4 rows from work array, store into output array. */
|
||||
|
||||
wsptr = workspace;
|
||||
for (ctr = 0; ctr < 4; ctr++) {
|
||||
outptr = output_buf[ctr] + output_col;
|
||||
/* It's not clear whether a zero row test is worthwhile here ... */
|
||||
|
||||
#ifndef NO_ZERO_ROW_TEST
|
||||
if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 &&
|
||||
wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
|
||||
/* AC terms all zero */
|
||||
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
outptr[1] = dcval;
|
||||
outptr[2] = dcval;
|
||||
outptr[3] = dcval;
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1);
|
||||
|
||||
tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065)
|
||||
+ MULTIPLY((INT32) wsptr[6], - FIX_0_765366865);
|
||||
|
||||
tmp10 = tmp0 + tmp2;
|
||||
tmp12 = tmp0 - tmp2;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z1 = (INT32) wsptr[7];
|
||||
z2 = (INT32) wsptr[5];
|
||||
z3 = (INT32) wsptr[3];
|
||||
z4 = (INT32) wsptr[1];
|
||||
|
||||
tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
|
||||
+ MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
|
||||
+ MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
|
||||
+ MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
|
||||
|
||||
tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
|
||||
+ MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
|
||||
+ MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
|
||||
+ MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
|
||||
|
||||
/* Final output stage */
|
||||
|
||||
outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2,
|
||||
CONST_BITS+PASS1_BITS+3+1)
|
||||
& RANGE_MASK];
|
||||
outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2,
|
||||
CONST_BITS+PASS1_BITS+3+1)
|
||||
& RANGE_MASK];
|
||||
outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0,
|
||||
CONST_BITS+PASS1_BITS+3+1)
|
||||
& RANGE_MASK];
|
||||
outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0,
|
||||
CONST_BITS+PASS1_BITS+3+1)
|
||||
& RANGE_MASK];
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a reduced-size 2x2 output block.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
INT32 tmp0, tmp10, z1;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE * quantptr;
|
||||
int * wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE*2]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process columns from input, store into work array. */
|
||||
|
||||
inptr = coef_block;
|
||||
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
||||
wsptr = workspace;
|
||||
for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
|
||||
/* Don't bother to process columns 2,4,6 */
|
||||
if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6)
|
||||
continue;
|
||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 &&
|
||||
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) {
|
||||
/* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */
|
||||
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
|
||||
|
||||
wsptr[DCTSIZE*0] = dcval;
|
||||
wsptr[DCTSIZE*1] = dcval;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Even part */
|
||||
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
tmp10 = z1 << (CONST_BITS+2);
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
||||
tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
||||
tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
||||
tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
||||
tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
|
||||
|
||||
/* Final output stage */
|
||||
|
||||
wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2);
|
||||
wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2);
|
||||
}
|
||||
|
||||
/* Pass 2: process 2 rows from work array, store into output array. */
|
||||
|
||||
wsptr = workspace;
|
||||
for (ctr = 0; ctr < 2; ctr++) {
|
||||
outptr = output_buf[ctr] + output_col;
|
||||
/* It's not clear whether a zero row test is worthwhile here ... */
|
||||
|
||||
#ifndef NO_ZERO_ROW_TEST
|
||||
if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) {
|
||||
/* AC terms all zero */
|
||||
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
outptr[1] = dcval;
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2);
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */
|
||||
+ MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */
|
||||
+ MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */
|
||||
+ MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
|
||||
|
||||
/* Final output stage */
|
||||
|
||||
outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0,
|
||||
CONST_BITS+PASS1_BITS+3+2)
|
||||
& RANGE_MASK];
|
||||
outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0,
|
||||
CONST_BITS+PASS1_BITS+3+2)
|
||||
& RANGE_MASK];
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a reduced-size 1x1 output block.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
int dcval;
|
||||
ISLOW_MULT_TYPE * quantptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* We hardly need an inverse DCT routine for this: just take the
|
||||
* average pixel value, which is one-eighth of the DC coefficient.
|
||||
*/
|
||||
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
||||
dcval = DEQUANTIZE(coef_block[0], quantptr[0]);
|
||||
dcval = (int) DESCALE((INT32) dcval, 3);
|
||||
|
||||
output_buf[0][output_col] = range_limit[dcval & RANGE_MASK];
|
||||
}
|
||||
|
||||
#endif /* IDCT_SCALING_SUPPORTED */
|
||||
|
@ -1,197 +1,197 @@
|
||||
/*
|
||||
* jinclude.h
|
||||
*
|
||||
* Copyright (C) 1991-1994, 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 exists to provide a single place to fix any problems with
|
||||
* including the wrong system include files. (Common problems are taken
|
||||
* care of by the standard jconfig symbols, but on really weird systems
|
||||
* you may have to edit this file.)
|
||||
*
|
||||
* NOTE: this file is NOT intended to be included by applications using the
|
||||
* JPEG library. Most applications need only include jpeglib.h.
|
||||
*/
|
||||
|
||||
|
||||
/* Include auto-config file to find out which system include files we need. */
|
||||
|
||||
#ifndef __jinclude_h__
|
||||
#define __jinclude_h__
|
||||
|
||||
#include "jconfig.h" /* auto configuration options */
|
||||
#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */
|
||||
|
||||
/*
|
||||
* We need the NULL macro and size_t typedef.
|
||||
* On an ANSI-conforming system it is sufficient to include <stddef.h>.
|
||||
* Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to
|
||||
* pull in <sys/types.h> as well.
|
||||
* Note that the core JPEG library does not require <stdio.h>;
|
||||
* only the default error handler and data source/destination modules do.
|
||||
* But we must pull it in because of the references to FILE in jpeglib.h.
|
||||
* You can remove those references if you want to compile without <stdio.h>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_STDDEF_H
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef NEED_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* We need memory copying and zeroing functions, plus strncpy().
|
||||
* ANSI and System V implementations declare these in <string.h>.
|
||||
* BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
|
||||
* Some systems may declare memset and memcpy in <memory.h>.
|
||||
*
|
||||
* NOTE: we assume the size parameters to these functions are of type size_t.
|
||||
* Change the casts in these macros if not!
|
||||
*/
|
||||
|
||||
#ifdef NEED_BSD_STRINGS
|
||||
|
||||
#include <strings.h>
|
||||
#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size))
|
||||
#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size))
|
||||
|
||||
#else /* not BSD, assume ANSI/SysV string lib */
|
||||
|
||||
#include <string.h>
|
||||
#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size))
|
||||
#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size))
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* In ANSI C, and indeed any rational implementation, size_t is also the
|
||||
* type returned by sizeof(). However, it seems there are some irrational
|
||||
* implementations out there, in which sizeof() returns an int even though
|
||||
* size_t is defined as long or unsigned long. To ensure consistent results
|
||||
* we always use this SIZEOF() macro in place of using sizeof() directly.
|
||||
*/
|
||||
|
||||
#define SIZEOF(object) ((size_t) sizeof(object))
|
||||
|
||||
/*
|
||||
* The modules that use fread() and fwrite() always invoke them through
|
||||
* these macros. On some systems you may need to twiddle the argument casts.
|
||||
* CAUTION: argument order is different from underlying functions!
|
||||
*/
|
||||
|
||||
#define JFREAD(file,buf,sizeofbuf) \
|
||||
((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
|
||||
#define JFWRITE(file,buf,sizeofbuf) \
|
||||
((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
|
||||
|
||||
|
||||
|
||||
typedef enum { /* JPEG marker codes */
|
||||
M_SOF0 = 0xc0,
|
||||
M_SOF1 = 0xc1,
|
||||
M_SOF2 = 0xc2,
|
||||
M_SOF3 = 0xc3,
|
||||
|
||||
M_SOF5 = 0xc5,
|
||||
M_SOF6 = 0xc6,
|
||||
M_SOF7 = 0xc7,
|
||||
|
||||
M_JPG = 0xc8,
|
||||
M_SOF9 = 0xc9,
|
||||
M_SOF10 = 0xca,
|
||||
M_SOF11 = 0xcb,
|
||||
|
||||
M_SOF13 = 0xcd,
|
||||
M_SOF14 = 0xce,
|
||||
M_SOF15 = 0xcf,
|
||||
|
||||
M_DHT = 0xc4,
|
||||
|
||||
M_DAC = 0xcc,
|
||||
|
||||
M_RST0 = 0xd0,
|
||||
M_RST1 = 0xd1,
|
||||
M_RST2 = 0xd2,
|
||||
M_RST3 = 0xd3,
|
||||
M_RST4 = 0xd4,
|
||||
M_RST5 = 0xd5,
|
||||
M_RST6 = 0xd6,
|
||||
M_RST7 = 0xd7,
|
||||
|
||||
M_SOI = 0xd8,
|
||||
M_EOI = 0xd9,
|
||||
M_SOS = 0xda,
|
||||
M_DQT = 0xdb,
|
||||
M_DNL = 0xdc,
|
||||
M_DRI = 0xdd,
|
||||
M_DHP = 0xde,
|
||||
M_EXP = 0xdf,
|
||||
|
||||
M_APP0 = 0xe0,
|
||||
M_APP1 = 0xe1,
|
||||
M_APP2 = 0xe2,
|
||||
M_APP3 = 0xe3,
|
||||
M_APP4 = 0xe4,
|
||||
M_APP5 = 0xe5,
|
||||
M_APP6 = 0xe6,
|
||||
M_APP7 = 0xe7,
|
||||
M_APP8 = 0xe8,
|
||||
M_APP9 = 0xe9,
|
||||
M_APP10 = 0xea,
|
||||
M_APP11 = 0xeb,
|
||||
M_APP12 = 0xec,
|
||||
M_APP13 = 0xed,
|
||||
M_APP14 = 0xee,
|
||||
M_APP15 = 0xef,
|
||||
|
||||
M_JPG0 = 0xf0,
|
||||
M_JPG13 = 0xfd,
|
||||
M_COM = 0xfe,
|
||||
|
||||
M_TEM = 0x01,
|
||||
|
||||
M_ERROR = 0x100
|
||||
} JPEG_MARKER;
|
||||
|
||||
|
||||
/*
|
||||
* Figure F.12: extend sign bit.
|
||||
* On some machines, a shift and add will be faster than a table lookup.
|
||||
*/
|
||||
|
||||
#ifdef AVOID_TABLES
|
||||
|
||||
#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
|
||||
|
||||
#else
|
||||
|
||||
#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
|
||||
|
||||
static const int extend_test[16] = /* entry n is 2**(n-1) */
|
||||
{ 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
|
||||
0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
|
||||
|
||||
#define SHIFTED_BITS_PLUS_ONE(n) (int) (((unsigned int) -1) << n) + 1
|
||||
|
||||
static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
|
||||
{ 0,
|
||||
SHIFTED_BITS_PLUS_ONE (1), SHIFTED_BITS_PLUS_ONE (2), SHIFTED_BITS_PLUS_ONE (3), SHIFTED_BITS_PLUS_ONE (4),
|
||||
SHIFTED_BITS_PLUS_ONE (5), SHIFTED_BITS_PLUS_ONE (6), SHIFTED_BITS_PLUS_ONE (7), SHIFTED_BITS_PLUS_ONE (8),
|
||||
SHIFTED_BITS_PLUS_ONE (9), SHIFTED_BITS_PLUS_ONE (10), SHIFTED_BITS_PLUS_ONE (11), SHIFTED_BITS_PLUS_ONE (12),
|
||||
SHIFTED_BITS_PLUS_ONE (13), SHIFTED_BITS_PLUS_ONE (14), SHIFTED_BITS_PLUS_ONE (15) };
|
||||
|
||||
#undef SHIFTED_BITS_PLUS_ONE
|
||||
|
||||
#endif /* AVOID_TABLES */
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
* jinclude.h
|
||||
*
|
||||
* Copyright (C) 1991-1994, 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 exists to provide a single place to fix any problems with
|
||||
* including the wrong system include files. (Common problems are taken
|
||||
* care of by the standard jconfig symbols, but on really weird systems
|
||||
* you may have to edit this file.)
|
||||
*
|
||||
* NOTE: this file is NOT intended to be included by applications using the
|
||||
* JPEG library. Most applications need only include jpeglib.h.
|
||||
*/
|
||||
|
||||
|
||||
/* Include auto-config file to find out which system include files we need. */
|
||||
|
||||
#ifndef __jinclude_h__
|
||||
#define __jinclude_h__
|
||||
|
||||
#include "jconfig.h" /* auto configuration options */
|
||||
#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */
|
||||
|
||||
/*
|
||||
* We need the NULL macro and size_t typedef.
|
||||
* On an ANSI-conforming system it is sufficient to include <stddef.h>.
|
||||
* Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to
|
||||
* pull in <sys/types.h> as well.
|
||||
* Note that the core JPEG library does not require <stdio.h>;
|
||||
* only the default error handler and data source/destination modules do.
|
||||
* But we must pull it in because of the references to FILE in jpeglib.h.
|
||||
* You can remove those references if you want to compile without <stdio.h>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_STDDEF_H
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef NEED_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* We need memory copying and zeroing functions, plus strncpy().
|
||||
* ANSI and System V implementations declare these in <string.h>.
|
||||
* BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
|
||||
* Some systems may declare memset and memcpy in <memory.h>.
|
||||
*
|
||||
* NOTE: we assume the size parameters to these functions are of type size_t.
|
||||
* Change the casts in these macros if not!
|
||||
*/
|
||||
|
||||
#ifdef NEED_BSD_STRINGS
|
||||
|
||||
#include <strings.h>
|
||||
#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size))
|
||||
#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size))
|
||||
|
||||
#else /* not BSD, assume ANSI/SysV string lib */
|
||||
|
||||
#include <string.h>
|
||||
#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size))
|
||||
#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size))
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* In ANSI C, and indeed any rational implementation, size_t is also the
|
||||
* type returned by sizeof(). However, it seems there are some irrational
|
||||
* implementations out there, in which sizeof() returns an int even though
|
||||
* size_t is defined as long or unsigned long. To ensure consistent results
|
||||
* we always use this SIZEOF() macro in place of using sizeof() directly.
|
||||
*/
|
||||
|
||||
#define SIZEOF(object) ((size_t) sizeof(object))
|
||||
|
||||
/*
|
||||
* The modules that use fread() and fwrite() always invoke them through
|
||||
* these macros. On some systems you may need to twiddle the argument casts.
|
||||
* CAUTION: argument order is different from underlying functions!
|
||||
*/
|
||||
|
||||
#define JFREAD(file,buf,sizeofbuf) \
|
||||
((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
|
||||
#define JFWRITE(file,buf,sizeofbuf) \
|
||||
((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
|
||||
|
||||
|
||||
|
||||
typedef enum { /* JPEG marker codes */
|
||||
M_SOF0 = 0xc0,
|
||||
M_SOF1 = 0xc1,
|
||||
M_SOF2 = 0xc2,
|
||||
M_SOF3 = 0xc3,
|
||||
|
||||
M_SOF5 = 0xc5,
|
||||
M_SOF6 = 0xc6,
|
||||
M_SOF7 = 0xc7,
|
||||
|
||||
M_JPG = 0xc8,
|
||||
M_SOF9 = 0xc9,
|
||||
M_SOF10 = 0xca,
|
||||
M_SOF11 = 0xcb,
|
||||
|
||||
M_SOF13 = 0xcd,
|
||||
M_SOF14 = 0xce,
|
||||
M_SOF15 = 0xcf,
|
||||
|
||||
M_DHT = 0xc4,
|
||||
|
||||
M_DAC = 0xcc,
|
||||
|
||||
M_RST0 = 0xd0,
|
||||
M_RST1 = 0xd1,
|
||||
M_RST2 = 0xd2,
|
||||
M_RST3 = 0xd3,
|
||||
M_RST4 = 0xd4,
|
||||
M_RST5 = 0xd5,
|
||||
M_RST6 = 0xd6,
|
||||
M_RST7 = 0xd7,
|
||||
|
||||
M_SOI = 0xd8,
|
||||
M_EOI = 0xd9,
|
||||
M_SOS = 0xda,
|
||||
M_DQT = 0xdb,
|
||||
M_DNL = 0xdc,
|
||||
M_DRI = 0xdd,
|
||||
M_DHP = 0xde,
|
||||
M_EXP = 0xdf,
|
||||
|
||||
M_APP0 = 0xe0,
|
||||
M_APP1 = 0xe1,
|
||||
M_APP2 = 0xe2,
|
||||
M_APP3 = 0xe3,
|
||||
M_APP4 = 0xe4,
|
||||
M_APP5 = 0xe5,
|
||||
M_APP6 = 0xe6,
|
||||
M_APP7 = 0xe7,
|
||||
M_APP8 = 0xe8,
|
||||
M_APP9 = 0xe9,
|
||||
M_APP10 = 0xea,
|
||||
M_APP11 = 0xeb,
|
||||
M_APP12 = 0xec,
|
||||
M_APP13 = 0xed,
|
||||
M_APP14 = 0xee,
|
||||
M_APP15 = 0xef,
|
||||
|
||||
M_JPG0 = 0xf0,
|
||||
M_JPG13 = 0xfd,
|
||||
M_COM = 0xfe,
|
||||
|
||||
M_TEM = 0x01,
|
||||
|
||||
M_ERROR = 0x100
|
||||
} JPEG_MARKER;
|
||||
|
||||
|
||||
/*
|
||||
* Figure F.12: extend sign bit.
|
||||
* On some machines, a shift and add will be faster than a table lookup.
|
||||
*/
|
||||
|
||||
#ifdef AVOID_TABLES
|
||||
|
||||
#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
|
||||
|
||||
#else
|
||||
|
||||
#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
|
||||
|
||||
static const int extend_test[16] = /* entry n is 2**(n-1) */
|
||||
{ 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
|
||||
0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
|
||||
|
||||
#define SHIFTED_BITS_PLUS_ONE(n) (int) (((unsigned int) -1) << n) + 1
|
||||
|
||||
static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
|
||||
{ 0,
|
||||
SHIFTED_BITS_PLUS_ONE (1), SHIFTED_BITS_PLUS_ONE (2), SHIFTED_BITS_PLUS_ONE (3), SHIFTED_BITS_PLUS_ONE (4),
|
||||
SHIFTED_BITS_PLUS_ONE (5), SHIFTED_BITS_PLUS_ONE (6), SHIFTED_BITS_PLUS_ONE (7), SHIFTED_BITS_PLUS_ONE (8),
|
||||
SHIFTED_BITS_PLUS_ONE (9), SHIFTED_BITS_PLUS_ONE (10), SHIFTED_BITS_PLUS_ONE (11), SHIFTED_BITS_PLUS_ONE (12),
|
||||
SHIFTED_BITS_PLUS_ONE (13), SHIFTED_BITS_PLUS_ONE (14), SHIFTED_BITS_PLUS_ONE (15) };
|
||||
|
||||
#undef SHIFTED_BITS_PLUS_ONE
|
||||
|
||||
#endif /* AVOID_TABLES */
|
||||
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,109 +1,109 @@
|
||||
/*
|
||||
* jmemnobs.c
|
||||
*
|
||||
* Copyright (C) 1992-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 provides a really simple implementation of the system-
|
||||
* dependent portion of the JPEG memory manager. This implementation
|
||||
* assumes that no backing-store files are needed: all required space
|
||||
* can be obtained from malloc().
|
||||
* This is very portable in the sense that it'll compile on almost anything,
|
||||
* but you'd better have lots of main memory (or virtual memory) if you want
|
||||
* to process big images.
|
||||
* Note that the max_memory_to_use option is ignored by this implementation.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jmemsys.h" /* import the system-dependent declarations */
|
||||
|
||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
|
||||
extern void * malloc JPP((size_t size));
|
||||
extern void free JPP((void *ptr));
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Memory allocation and freeing are controlled by the regular library
|
||||
* routines malloc() and free().
|
||||
*/
|
||||
|
||||
GLOBAL(void *)
|
||||
jpeg_get_small (j_common_ptr , size_t sizeofobject)
|
||||
{
|
||||
return (void *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_small (j_common_ptr , void * object, size_t)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Large" objects are treated the same as "small" ones.
|
||||
* NB: although we include FAR keywords in the routine declarations,
|
||||
* this file won't actually work in 80x86 small/medium model; at least,
|
||||
* you probably won't be able to process useful-size images in only 64KB.
|
||||
*/
|
||||
|
||||
GLOBAL(void FAR *)
|
||||
jpeg_get_large (j_common_ptr, size_t sizeofobject)
|
||||
{
|
||||
return (void FAR *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_large (j_common_ptr, void FAR * object, size_t)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine computes the total memory space available for allocation.
|
||||
* Here we always say, "we got all you want bud!"
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_available (j_common_ptr, long,
|
||||
long max_bytes_needed, long)
|
||||
{
|
||||
return max_bytes_needed;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Backing store (temporary file) management.
|
||||
* Since jpeg_mem_available always promised the moon,
|
||||
* this should never be called and we can just error out.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_open_backing_store (j_common_ptr cinfo, struct backing_store_struct *,
|
||||
long )
|
||||
{
|
||||
ERREXIT(cinfo, JERR_NO_BACKING_STORE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These routines take care of any system-dependent initialization and
|
||||
* cleanup required. Here, there isn't any.
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_init (j_common_ptr)
|
||||
{
|
||||
return 0; /* just set max_memory_to_use to 0 */
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_term (j_common_ptr)
|
||||
{
|
||||
/* no work */
|
||||
}
|
||||
/*
|
||||
* jmemnobs.c
|
||||
*
|
||||
* Copyright (C) 1992-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 provides a really simple implementation of the system-
|
||||
* dependent portion of the JPEG memory manager. This implementation
|
||||
* assumes that no backing-store files are needed: all required space
|
||||
* can be obtained from malloc().
|
||||
* This is very portable in the sense that it'll compile on almost anything,
|
||||
* but you'd better have lots of main memory (or virtual memory) if you want
|
||||
* to process big images.
|
||||
* Note that the max_memory_to_use option is ignored by this implementation.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jmemsys.h" /* import the system-dependent declarations */
|
||||
|
||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
|
||||
extern void * malloc JPP((size_t size));
|
||||
extern void free JPP((void *ptr));
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Memory allocation and freeing are controlled by the regular library
|
||||
* routines malloc() and free().
|
||||
*/
|
||||
|
||||
GLOBAL(void *)
|
||||
jpeg_get_small (j_common_ptr , size_t sizeofobject)
|
||||
{
|
||||
return (void *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_small (j_common_ptr , void * object, size_t)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Large" objects are treated the same as "small" ones.
|
||||
* NB: although we include FAR keywords in the routine declarations,
|
||||
* this file won't actually work in 80x86 small/medium model; at least,
|
||||
* you probably won't be able to process useful-size images in only 64KB.
|
||||
*/
|
||||
|
||||
GLOBAL(void FAR *)
|
||||
jpeg_get_large (j_common_ptr, size_t sizeofobject)
|
||||
{
|
||||
return (void FAR *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_large (j_common_ptr, void FAR * object, size_t)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine computes the total memory space available for allocation.
|
||||
* Here we always say, "we got all you want bud!"
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_available (j_common_ptr, long,
|
||||
long max_bytes_needed, long)
|
||||
{
|
||||
return max_bytes_needed;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Backing store (temporary file) management.
|
||||
* Since jpeg_mem_available always promised the moon,
|
||||
* this should never be called and we can just error out.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_open_backing_store (j_common_ptr cinfo, struct backing_store_struct *,
|
||||
long )
|
||||
{
|
||||
ERREXIT(cinfo, JERR_NO_BACKING_STORE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These routines take care of any system-dependent initialization and
|
||||
* cleanup required. Here, there isn't any.
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_init (j_common_ptr)
|
||||
{
|
||||
return 0; /* just set max_memory_to_use to 0 */
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_term (j_common_ptr)
|
||||
{
|
||||
/* no work */
|
||||
}
|
||||
|
@ -1,203 +1,203 @@
|
||||
/*
|
||||
* jmemsys.h
|
||||
*
|
||||
* Copyright (C) 1992-1997, 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 include file defines the interface between the system-independent
|
||||
* and system-dependent portions of the JPEG memory manager. No other
|
||||
* modules need include it. (The system-independent portion is jmemmgr.c;
|
||||
* there are several different versions of the system-dependent portion.)
|
||||
*
|
||||
* This file works as-is for the system-dependent memory managers supplied
|
||||
* in the IJG distribution. You may need to modify it if you write a
|
||||
* custom memory manager. If system-dependent changes are needed in
|
||||
* this file, the best method is to #ifdef them based on a configuration
|
||||
* symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR
|
||||
* and USE_MAC_MEMMGR.
|
||||
*/
|
||||
|
||||
#ifndef __jmemsys_h__
|
||||
#define __jmemsys_h__
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jpeg_get_small jGetSmall
|
||||
#define jpeg_free_small jFreeSmall
|
||||
#define jpeg_get_large jGetLarge
|
||||
#define jpeg_free_large jFreeLarge
|
||||
#define jpeg_mem_available jMemAvail
|
||||
#define jpeg_open_backing_store jOpenBackStore
|
||||
#define jpeg_mem_init jMemInit
|
||||
#define jpeg_mem_term jMemTerm
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
|
||||
/*
|
||||
* These two functions are used to allocate and release small chunks of
|
||||
* memory. (Typically the total amount requested through jpeg_get_small is
|
||||
* no more than 20K or so; this will be requested in chunks of a few K each.)
|
||||
* Behavior should be the same as for the standard library functions malloc
|
||||
* and free; in particular, jpeg_get_small must return NULL on failure.
|
||||
* On most systems, these ARE malloc and free. jpeg_free_small is passed the
|
||||
* size of the object being freed, just in case it's needed.
|
||||
* On an 80x86 machine using small-data memory model, these manage near heap.
|
||||
*/
|
||||
|
||||
EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject));
|
||||
EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object,
|
||||
size_t sizeofobject));
|
||||
|
||||
/*
|
||||
* These two functions are used to allocate and release large chunks of
|
||||
* memory (up to the total free space designated by jpeg_mem_available).
|
||||
* The interface is the same as above, except that on an 80x86 machine,
|
||||
* far pointers are used. On most other machines these are identical to
|
||||
* the jpeg_get/free_small routines; but we keep them separate anyway,
|
||||
* in case a different allocation strategy is desirable for large chunks.
|
||||
*/
|
||||
|
||||
EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo,
|
||||
size_t sizeofobject));
|
||||
EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
|
||||
size_t sizeofobject));
|
||||
|
||||
/*
|
||||
* The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
|
||||
* be requested in a single call to jpeg_get_large (and jpeg_get_small for that
|
||||
* matter, but that case should never come into play). This macro is needed
|
||||
* to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
|
||||
* On those machines, we expect that jconfig.h will provide a proper value.
|
||||
* On machines with 32-bit flat address spaces, any large constant may be used.
|
||||
*
|
||||
* NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type
|
||||
* size_t and will be a multiple of sizeof(align_type).
|
||||
*/
|
||||
|
||||
#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */
|
||||
#define MAX_ALLOC_CHUNK 1000000000L
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This routine computes the total space still available for allocation by
|
||||
* jpeg_get_large. If more space than this is needed, backing store will be
|
||||
* used. NOTE: any memory already allocated must not be counted.
|
||||
*
|
||||
* There is a minimum space requirement, corresponding to the minimum
|
||||
* feasible buffer sizes; jmemmgr.c will request that much space even if
|
||||
* jpeg_mem_available returns zero. The maximum space needed, enough to hold
|
||||
* all working storage in memory, is also passed in case it is useful.
|
||||
* Finally, the total space already allocated is passed. If no better
|
||||
* method is available, cinfo->mem->max_memory_to_use - already_allocated
|
||||
* is often a suitable calculation.
|
||||
*
|
||||
* It is OK for jpeg_mem_available to underestimate the space available
|
||||
* (that'll just lead to more backing-store access than is really necessary).
|
||||
* However, an overestimate will lead to failure. Hence it's wise to subtract
|
||||
* a slop factor from the true available space. 5% should be enough.
|
||||
*
|
||||
* On machines with lots of virtual memory, any large constant may be returned.
|
||||
* Conversely, zero may be returned to always use the minimum amount of memory.
|
||||
*/
|
||||
|
||||
EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo,
|
||||
long min_bytes_needed,
|
||||
long max_bytes_needed,
|
||||
long already_allocated));
|
||||
|
||||
|
||||
/*
|
||||
* This structure holds whatever state is needed to access a single
|
||||
* backing-store object. The read/write/close method pointers are called
|
||||
* by jmemmgr.c to manipulate the backing-store object; all other fields
|
||||
* are private to the system-dependent backing store routines.
|
||||
*/
|
||||
|
||||
#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
|
||||
|
||||
|
||||
#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */
|
||||
|
||||
typedef unsigned short XMSH; /* type of extended-memory handles */
|
||||
typedef unsigned short EMSH; /* type of expanded-memory handles */
|
||||
|
||||
typedef union {
|
||||
short file_handle; /* DOS file handle if it's a temp file */
|
||||
XMSH xms_handle; /* handle if it's a chunk of XMS */
|
||||
EMSH ems_handle; /* handle if it's a chunk of EMS */
|
||||
} handle_union;
|
||||
|
||||
#endif /* USE_MSDOS_MEMMGR */
|
||||
|
||||
#ifdef USE_MAC_MEMMGR /* Mac-specific junk */
|
||||
#include <Files.h>
|
||||
#endif /* USE_MAC_MEMMGR */
|
||||
|
||||
|
||||
//typedef struct backing_store_struct * backing_store_ptr;
|
||||
|
||||
typedef struct backing_store_struct {
|
||||
/* Methods for reading/writing/closing this backing-store object */
|
||||
JMETHOD(void, read_backing_store, (j_common_ptr cinfo,
|
||||
struct backing_store_struct *info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count));
|
||||
JMETHOD(void, write_backing_store, (j_common_ptr cinfo,
|
||||
struct backing_store_struct *info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count));
|
||||
JMETHOD(void, close_backing_store, (j_common_ptr cinfo,
|
||||
struct backing_store_struct *info));
|
||||
|
||||
/* Private fields for system-dependent backing-store management */
|
||||
#ifdef USE_MSDOS_MEMMGR
|
||||
/* For the MS-DOS manager (jmemdos.c), we need: */
|
||||
handle_union handle; /* reference to backing-store storage object */
|
||||
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
|
||||
#else
|
||||
#ifdef USE_MAC_MEMMGR
|
||||
/* For the Mac manager (jmemmac.c), we need: */
|
||||
short temp_file; /* file reference number to temp file */
|
||||
FSSpec tempSpec; /* the FSSpec for the temp file */
|
||||
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
|
||||
#else
|
||||
/* For a typical implementation with temp files, we need: */
|
||||
FILE * temp_file; /* stdio reference to temp file */
|
||||
char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
|
||||
#endif
|
||||
#endif
|
||||
} backing_store_info;
|
||||
|
||||
|
||||
/*
|
||||
* Initial opening of a backing-store object. This must fill in the
|
||||
* read/write/close pointers in the object. The read/write routines
|
||||
* may take an error exit if the specified maximum file size is exceeded.
|
||||
* (If jpeg_mem_available always returns a large value, this routine can
|
||||
* just take an error exit.)
|
||||
*/
|
||||
|
||||
EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo,
|
||||
struct backing_store_struct *info,
|
||||
long total_bytes_needed));
|
||||
|
||||
|
||||
/*
|
||||
* These routines take care of any system-dependent initialization and
|
||||
* cleanup required. jpeg_mem_init will be called before anything is
|
||||
* allocated (and, therefore, nothing in cinfo is of use except the error
|
||||
* manager pointer). It should return a suitable default value for
|
||||
* max_memory_to_use; this may subsequently be overridden by the surrounding
|
||||
* application. (Note that max_memory_to_use is only important if
|
||||
* jpeg_mem_available chooses to consult it ... no one else will.)
|
||||
* jpeg_mem_term may assume that all requested memory has been freed and that
|
||||
* all opened backing-store objects have been closed.
|
||||
*/
|
||||
|
||||
EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo));
|
||||
EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo));
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
* jmemsys.h
|
||||
*
|
||||
* Copyright (C) 1992-1997, 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 include file defines the interface between the system-independent
|
||||
* and system-dependent portions of the JPEG memory manager. No other
|
||||
* modules need include it. (The system-independent portion is jmemmgr.c;
|
||||
* there are several different versions of the system-dependent portion.)
|
||||
*
|
||||
* This file works as-is for the system-dependent memory managers supplied
|
||||
* in the IJG distribution. You may need to modify it if you write a
|
||||
* custom memory manager. If system-dependent changes are needed in
|
||||
* this file, the best method is to #ifdef them based on a configuration
|
||||
* symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR
|
||||
* and USE_MAC_MEMMGR.
|
||||
*/
|
||||
|
||||
#ifndef __jmemsys_h__
|
||||
#define __jmemsys_h__
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jpeg_get_small jGetSmall
|
||||
#define jpeg_free_small jFreeSmall
|
||||
#define jpeg_get_large jGetLarge
|
||||
#define jpeg_free_large jFreeLarge
|
||||
#define jpeg_mem_available jMemAvail
|
||||
#define jpeg_open_backing_store jOpenBackStore
|
||||
#define jpeg_mem_init jMemInit
|
||||
#define jpeg_mem_term jMemTerm
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
|
||||
/*
|
||||
* These two functions are used to allocate and release small chunks of
|
||||
* memory. (Typically the total amount requested through jpeg_get_small is
|
||||
* no more than 20K or so; this will be requested in chunks of a few K each.)
|
||||
* Behavior should be the same as for the standard library functions malloc
|
||||
* and free; in particular, jpeg_get_small must return NULL on failure.
|
||||
* On most systems, these ARE malloc and free. jpeg_free_small is passed the
|
||||
* size of the object being freed, just in case it's needed.
|
||||
* On an 80x86 machine using small-data memory model, these manage near heap.
|
||||
*/
|
||||
|
||||
EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject));
|
||||
EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object,
|
||||
size_t sizeofobject));
|
||||
|
||||
/*
|
||||
* These two functions are used to allocate and release large chunks of
|
||||
* memory (up to the total free space designated by jpeg_mem_available).
|
||||
* The interface is the same as above, except that on an 80x86 machine,
|
||||
* far pointers are used. On most other machines these are identical to
|
||||
* the jpeg_get/free_small routines; but we keep them separate anyway,
|
||||
* in case a different allocation strategy is desirable for large chunks.
|
||||
*/
|
||||
|
||||
EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo,
|
||||
size_t sizeofobject));
|
||||
EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
|
||||
size_t sizeofobject));
|
||||
|
||||
/*
|
||||
* The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
|
||||
* be requested in a single call to jpeg_get_large (and jpeg_get_small for that
|
||||
* matter, but that case should never come into play). This macro is needed
|
||||
* to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
|
||||
* On those machines, we expect that jconfig.h will provide a proper value.
|
||||
* On machines with 32-bit flat address spaces, any large constant may be used.
|
||||
*
|
||||
* NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type
|
||||
* size_t and will be a multiple of sizeof(align_type).
|
||||
*/
|
||||
|
||||
#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */
|
||||
#define MAX_ALLOC_CHUNK 1000000000L
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This routine computes the total space still available for allocation by
|
||||
* jpeg_get_large. If more space than this is needed, backing store will be
|
||||
* used. NOTE: any memory already allocated must not be counted.
|
||||
*
|
||||
* There is a minimum space requirement, corresponding to the minimum
|
||||
* feasible buffer sizes; jmemmgr.c will request that much space even if
|
||||
* jpeg_mem_available returns zero. The maximum space needed, enough to hold
|
||||
* all working storage in memory, is also passed in case it is useful.
|
||||
* Finally, the total space already allocated is passed. If no better
|
||||
* method is available, cinfo->mem->max_memory_to_use - already_allocated
|
||||
* is often a suitable calculation.
|
||||
*
|
||||
* It is OK for jpeg_mem_available to underestimate the space available
|
||||
* (that'll just lead to more backing-store access than is really necessary).
|
||||
* However, an overestimate will lead to failure. Hence it's wise to subtract
|
||||
* a slop factor from the true available space. 5% should be enough.
|
||||
*
|
||||
* On machines with lots of virtual memory, any large constant may be returned.
|
||||
* Conversely, zero may be returned to always use the minimum amount of memory.
|
||||
*/
|
||||
|
||||
EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo,
|
||||
long min_bytes_needed,
|
||||
long max_bytes_needed,
|
||||
long already_allocated));
|
||||
|
||||
|
||||
/*
|
||||
* This structure holds whatever state is needed to access a single
|
||||
* backing-store object. The read/write/close method pointers are called
|
||||
* by jmemmgr.c to manipulate the backing-store object; all other fields
|
||||
* are private to the system-dependent backing store routines.
|
||||
*/
|
||||
|
||||
#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
|
||||
|
||||
|
||||
#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */
|
||||
|
||||
typedef unsigned short XMSH; /* type of extended-memory handles */
|
||||
typedef unsigned short EMSH; /* type of expanded-memory handles */
|
||||
|
||||
typedef union {
|
||||
short file_handle; /* DOS file handle if it's a temp file */
|
||||
XMSH xms_handle; /* handle if it's a chunk of XMS */
|
||||
EMSH ems_handle; /* handle if it's a chunk of EMS */
|
||||
} handle_union;
|
||||
|
||||
#endif /* USE_MSDOS_MEMMGR */
|
||||
|
||||
#ifdef USE_MAC_MEMMGR /* Mac-specific junk */
|
||||
#include <Files.h>
|
||||
#endif /* USE_MAC_MEMMGR */
|
||||
|
||||
|
||||
//typedef struct backing_store_struct * backing_store_ptr;
|
||||
|
||||
typedef struct backing_store_struct {
|
||||
/* Methods for reading/writing/closing this backing-store object */
|
||||
JMETHOD(void, read_backing_store, (j_common_ptr cinfo,
|
||||
struct backing_store_struct *info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count));
|
||||
JMETHOD(void, write_backing_store, (j_common_ptr cinfo,
|
||||
struct backing_store_struct *info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count));
|
||||
JMETHOD(void, close_backing_store, (j_common_ptr cinfo,
|
||||
struct backing_store_struct *info));
|
||||
|
||||
/* Private fields for system-dependent backing-store management */
|
||||
#ifdef USE_MSDOS_MEMMGR
|
||||
/* For the MS-DOS manager (jmemdos.c), we need: */
|
||||
handle_union handle; /* reference to backing-store storage object */
|
||||
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
|
||||
#else
|
||||
#ifdef USE_MAC_MEMMGR
|
||||
/* For the Mac manager (jmemmac.c), we need: */
|
||||
short temp_file; /* file reference number to temp file */
|
||||
FSSpec tempSpec; /* the FSSpec for the temp file */
|
||||
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
|
||||
#else
|
||||
/* For a typical implementation with temp files, we need: */
|
||||
FILE * temp_file; /* stdio reference to temp file */
|
||||
char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
|
||||
#endif
|
||||
#endif
|
||||
} backing_store_info;
|
||||
|
||||
|
||||
/*
|
||||
* Initial opening of a backing-store object. This must fill in the
|
||||
* read/write/close pointers in the object. The read/write routines
|
||||
* may take an error exit if the specified maximum file size is exceeded.
|
||||
* (If jpeg_mem_available always returns a large value, this routine can
|
||||
* just take an error exit.)
|
||||
*/
|
||||
|
||||
EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo,
|
||||
struct backing_store_struct *info,
|
||||
long total_bytes_needed));
|
||||
|
||||
|
||||
/*
|
||||
* These routines take care of any system-dependent initialization and
|
||||
* cleanup required. jpeg_mem_init will be called before anything is
|
||||
* allocated (and, therefore, nothing in cinfo is of use except the error
|
||||
* manager pointer). It should return a suitable default value for
|
||||
* max_memory_to_use; this may subsequently be overridden by the surrounding
|
||||
* application. (Note that max_memory_to_use is only important if
|
||||
* jpeg_mem_available chooses to consult it ... no one else will.)
|
||||
* jpeg_mem_term may assume that all requested memory has been freed and that
|
||||
* all opened backing-store objects have been closed.
|
||||
*/
|
||||
|
||||
EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo));
|
||||
EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo));
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,363 +1,363 @@
|
||||
/*
|
||||
* jmorecfg.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 additional configuration options that customize the
|
||||
* JPEG software for special applications or support machine-dependent
|
||||
* optimizations. Most users will not need to touch this file.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Define BITS_IN_JSAMPLE as either
|
||||
* 8 for 8-bit sample values (the usual setting)
|
||||
* 12 for 12-bit sample values
|
||||
* Only 8 and 12 are legal data precisions for lossy JPEG according to the
|
||||
* JPEG standard, and the IJG code does not support anything else!
|
||||
* We do not support run-time selection of data precision, sorry.
|
||||
*/
|
||||
|
||||
#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */
|
||||
|
||||
|
||||
/*
|
||||
* Maximum number of components (color channels) allowed in JPEG image.
|
||||
* To meet the letter of the JPEG spec, set this to 255. However, darn
|
||||
* few applications need more than 4 channels (maybe 5 for CMYK + alpha
|
||||
* mask). We recommend 10 as a reasonable compromise; use 4 if you are
|
||||
* really short on memory. (Each allowed component costs a hundred or so
|
||||
* bytes of storage, whether actually used in an image or not.)
|
||||
*/
|
||||
|
||||
#define MAX_COMPONENTS 10 /* maximum number of image components */
|
||||
|
||||
|
||||
/*
|
||||
* Basic data types.
|
||||
* You may need to change these if you have a machine with unusual data
|
||||
* type sizes; for example, "char" not 8 bits, "short" not 16 bits,
|
||||
* or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits,
|
||||
* but it had better be at least 16.
|
||||
*/
|
||||
|
||||
/* Representation of a single sample (pixel element value).
|
||||
* We frequently allocate large arrays of these, so it's important to keep
|
||||
* them small. But if you have memory to burn and access to char or short
|
||||
* arrays is very slow on your hardware, you might want to change these.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
/* JSAMPLE should be the smallest type that will hold the values 0..255.
|
||||
* You can use a signed char by having GETJSAMPLE mask it with 0xFF.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
|
||||
typedef unsigned char JSAMPLE;
|
||||
#define GETJSAMPLE(value) ((int) (value))
|
||||
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
|
||||
typedef char JSAMPLE;
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
#define GETJSAMPLE(value) ((int) (value))
|
||||
#else
|
||||
#define GETJSAMPLE(value) ((int) (value) & 0xFF)
|
||||
#endif /* CHAR_IS_UNSIGNED */
|
||||
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
#define MAXJSAMPLE 255
|
||||
#define CENTERJSAMPLE 128
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 8 */
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE == 12
|
||||
/* JSAMPLE should be the smallest type that will hold the values 0..4095.
|
||||
* On nearly all machines "short" will do nicely.
|
||||
*/
|
||||
|
||||
typedef short JSAMPLE;
|
||||
#define GETJSAMPLE(value) ((int) (value))
|
||||
|
||||
#define MAXJSAMPLE 4095
|
||||
#define CENTERJSAMPLE 2048
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 12 */
|
||||
|
||||
|
||||
/* Representation of a DCT frequency coefficient.
|
||||
* This should be a signed value of at least 16 bits; "short" is usually OK.
|
||||
* Again, we allocate large arrays of these, but you can change to int
|
||||
* if you have memory to burn and "short" is really slow.
|
||||
*/
|
||||
|
||||
typedef short JCOEF;
|
||||
|
||||
|
||||
/* Compressed datastreams are represented as arrays of JOCTET.
|
||||
* These must be EXACTLY 8 bits wide, at least once they are written to
|
||||
* external storage. Note that when using the stdio data source/destination
|
||||
* managers, this is also the data type passed to fread/fwrite.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
|
||||
typedef unsigned char JOCTET;
|
||||
#define GETJOCTET(value) (value)
|
||||
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
|
||||
typedef char JOCTET;
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
#define GETJOCTET(value) (value)
|
||||
#else
|
||||
#define GETJOCTET(value) ((value) & 0xFF)
|
||||
#endif /* CHAR_IS_UNSIGNED */
|
||||
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
|
||||
/* These typedefs are used for various table entries and so forth.
|
||||
* They must be at least as wide as specified; but making them too big
|
||||
* won't cost a huge amount of memory, so we don't provide special
|
||||
* extraction code like we did for JSAMPLE. (In other words, these
|
||||
* typedefs live at a different point on the speed/space tradeoff curve.)
|
||||
*/
|
||||
|
||||
/* UINT8 must hold at least the values 0..255. */
|
||||
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
typedef unsigned char UINT8;
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
typedef char UINT8;
|
||||
#else /* not CHAR_IS_UNSIGNED */
|
||||
typedef short UINT8;
|
||||
#endif /* CHAR_IS_UNSIGNED */
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
/* UINT16 must hold at least the values 0..65535. */
|
||||
|
||||
#ifdef HAVE_UNSIGNED_SHORT
|
||||
typedef unsigned short UINT16;
|
||||
#else /* not HAVE_UNSIGNED_SHORT */
|
||||
typedef unsigned int UINT16;
|
||||
#endif /* HAVE_UNSIGNED_SHORT */
|
||||
|
||||
/* INT16 must hold at least the values -32768..32767. */
|
||||
|
||||
#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
|
||||
typedef short INT16;
|
||||
#endif
|
||||
|
||||
/* INT32 must hold at least signed 32-bit values. */
|
||||
|
||||
#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
|
||||
typedef long INT32;
|
||||
#endif
|
||||
|
||||
/* Datatype used for image dimensions. The JPEG standard only supports
|
||||
* images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
|
||||
* "unsigned int" is sufficient on all machines. However, if you need to
|
||||
* handle larger images and you don't mind deviating from the spec, you
|
||||
* can change this datatype.
|
||||
*/
|
||||
|
||||
typedef unsigned int JDIMENSION;
|
||||
|
||||
#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
|
||||
|
||||
|
||||
/* These macros are used in all function definitions and extern declarations.
|
||||
* You could modify them if you need to change function linkage conventions;
|
||||
* in particular, you'll need to do that to make the library a Windows DLL.
|
||||
* Another application is to make all functions global for use with debuggers
|
||||
* or code profilers that require it.
|
||||
*/
|
||||
|
||||
/* a function called through method pointers: */
|
||||
#define METHODDEF(type) static type
|
||||
/* a function used only in its module: */
|
||||
#define LOCAL(type) static type
|
||||
/* a function referenced thru EXTERNs: */
|
||||
#define GLOBAL(type) type
|
||||
/* a reference to a GLOBAL function: */
|
||||
#define EXTERN(type) extern type
|
||||
|
||||
|
||||
/* This macro is used to declare a "method", that is, a function pointer.
|
||||
* We want to supply prototype parameters if the compiler can cope.
|
||||
* Note that the arglist parameter must be parenthesized!
|
||||
* Again, you can customize this if you need special linkage keywords.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
#define JMETHOD(type,methodname,arglist) type (*methodname) arglist
|
||||
#else
|
||||
#define JMETHOD(type,methodname,arglist) type (*methodname) ()
|
||||
#endif
|
||||
|
||||
|
||||
/* Here is the pseudo-keyword for declaring pointers that must be "far"
|
||||
* on 80x86 machines. Most of the specialized coding for 80x86 is handled
|
||||
* by just saying "FAR *" where such a pointer is needed. In a few places
|
||||
* explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
|
||||
*/
|
||||
|
||||
#ifdef NEED_FAR_POINTERS
|
||||
#define FAR far
|
||||
#else
|
||||
#define FAR
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* On a few systems, type boolean and/or its values FALSE, TRUE may appear
|
||||
* in standard header files. Or you may have conflicts with application-
|
||||
* specific header files that you want to include together with these files.
|
||||
* Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_BOOLEAN
|
||||
typedef int boolean;
|
||||
#endif
|
||||
#ifndef FALSE /* in case these macros already exist */
|
||||
#define FALSE 0 /* values of boolean */
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* The remaining options affect code selection within the JPEG library,
|
||||
* but they don't need to be visible to most applications using the library.
|
||||
* To minimize application namespace pollution, the symbols won't be
|
||||
* defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
|
||||
*/
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
#define JPEG_INTERNAL_OPTIONS
|
||||
#endif
|
||||
|
||||
#ifdef JPEG_INTERNAL_OPTIONS
|
||||
|
||||
|
||||
/*
|
||||
* These defines indicate whether to include various optional functions.
|
||||
* Undefining some of these symbols will produce a smaller but less capable
|
||||
* library. Note that you can leave certain source files out of the
|
||||
* compilation/linking process if you've #undef'd the corresponding symbols.
|
||||
* (You may HAVE to do that if your compiler doesn't like null source files.)
|
||||
*/
|
||||
|
||||
/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */
|
||||
|
||||
/* Capability options common to encoder and decoder: */
|
||||
|
||||
#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */
|
||||
#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */
|
||||
#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */
|
||||
|
||||
/* Encoder capability options: */
|
||||
|
||||
#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
||||
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
||||
#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
||||
#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
|
||||
/* Note: if you selected 12-bit data precision, it is dangerous to turn off
|
||||
* ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit
|
||||
* precision, so jchuff.c normally uses entropy optimization to compute
|
||||
* usable tables for higher precision. If you don't want to do optimization,
|
||||
* you'll have to supply different default Huffman tables.
|
||||
* The exact same statements apply for progressive JPEG: the default tables
|
||||
* don't work for progressive mode. (This may get fixed, however.)
|
||||
*/
|
||||
#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */
|
||||
|
||||
/* Decoder capability options: */
|
||||
|
||||
#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
||||
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
||||
#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
||||
#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
|
||||
#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
|
||||
#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
|
||||
#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
|
||||
#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */
|
||||
#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
|
||||
#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */
|
||||
|
||||
/* more capability options later, no doubt */
|
||||
|
||||
|
||||
/*
|
||||
* Ordering of RGB data in scanlines passed to or from the application.
|
||||
* If your application wants to deal with data in the order B,G,R, just
|
||||
* change these macros. You can also deal with formats such as R,G,B,X
|
||||
* (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing
|
||||
* the offsets will also change the order in which colormap data is organized.
|
||||
* RESTRICTIONS:
|
||||
* 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
|
||||
* 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
|
||||
* useful if you are using JPEG color spaces other than YCbCr or grayscale.
|
||||
* 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
|
||||
* is not 3 (they don't understand about dummy color components!). So you
|
||||
* can't use color quantization if you change that value.
|
||||
*/
|
||||
|
||||
#define RGB_RED 0 /* Offset of Red in an RGB scanline element */
|
||||
#define RGB_GREEN 1 /* Offset of Green */
|
||||
#define RGB_BLUE 2 /* Offset of Blue */
|
||||
#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */
|
||||
|
||||
|
||||
/* Definitions for speed-related optimizations. */
|
||||
|
||||
|
||||
/* If your compiler supports inline functions, define INLINE
|
||||
* as the inline keyword; otherwise define it as empty.
|
||||
*/
|
||||
|
||||
#ifndef INLINE
|
||||
#ifdef __GNUC__ /* for instance, GNU C knows about inline */
|
||||
#define INLINE __inline__
|
||||
#endif
|
||||
#ifndef INLINE
|
||||
#define INLINE /* default is to define it as empty */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
|
||||
* two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER
|
||||
* as short on such a machine. MULTIPLIER must be at least 16 bits wide.
|
||||
*/
|
||||
|
||||
#ifndef MULTIPLIER
|
||||
#define MULTIPLIER int /* type for fastest integer multiply */
|
||||
#endif
|
||||
|
||||
|
||||
/* FAST_FLOAT should be either float or double, whichever is done faster
|
||||
* by your compiler. (Note that this type is only used in the floating point
|
||||
* DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
|
||||
* Typically, float is faster in ANSI C compilers, while double is faster in
|
||||
* pre-ANSI compilers (because they insist on converting to double anyway).
|
||||
* The code below therefore chooses float if we have ANSI-style prototypes.
|
||||
*/
|
||||
|
||||
#ifndef FAST_FLOAT
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
#define FAST_FLOAT float
|
||||
#else
|
||||
#define FAST_FLOAT double
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* JPEG_INTERNAL_OPTIONS */
|
||||
/*
|
||||
* jmorecfg.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 additional configuration options that customize the
|
||||
* JPEG software for special applications or support machine-dependent
|
||||
* optimizations. Most users will not need to touch this file.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Define BITS_IN_JSAMPLE as either
|
||||
* 8 for 8-bit sample values (the usual setting)
|
||||
* 12 for 12-bit sample values
|
||||
* Only 8 and 12 are legal data precisions for lossy JPEG according to the
|
||||
* JPEG standard, and the IJG code does not support anything else!
|
||||
* We do not support run-time selection of data precision, sorry.
|
||||
*/
|
||||
|
||||
#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */
|
||||
|
||||
|
||||
/*
|
||||
* Maximum number of components (color channels) allowed in JPEG image.
|
||||
* To meet the letter of the JPEG spec, set this to 255. However, darn
|
||||
* few applications need more than 4 channels (maybe 5 for CMYK + alpha
|
||||
* mask). We recommend 10 as a reasonable compromise; use 4 if you are
|
||||
* really short on memory. (Each allowed component costs a hundred or so
|
||||
* bytes of storage, whether actually used in an image or not.)
|
||||
*/
|
||||
|
||||
#define MAX_COMPONENTS 10 /* maximum number of image components */
|
||||
|
||||
|
||||
/*
|
||||
* Basic data types.
|
||||
* You may need to change these if you have a machine with unusual data
|
||||
* type sizes; for example, "char" not 8 bits, "short" not 16 bits,
|
||||
* or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits,
|
||||
* but it had better be at least 16.
|
||||
*/
|
||||
|
||||
/* Representation of a single sample (pixel element value).
|
||||
* We frequently allocate large arrays of these, so it's important to keep
|
||||
* them small. But if you have memory to burn and access to char or short
|
||||
* arrays is very slow on your hardware, you might want to change these.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
/* JSAMPLE should be the smallest type that will hold the values 0..255.
|
||||
* You can use a signed char by having GETJSAMPLE mask it with 0xFF.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
|
||||
typedef unsigned char JSAMPLE;
|
||||
#define GETJSAMPLE(value) ((int) (value))
|
||||
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
|
||||
typedef char JSAMPLE;
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
#define GETJSAMPLE(value) ((int) (value))
|
||||
#else
|
||||
#define GETJSAMPLE(value) ((int) (value) & 0xFF)
|
||||
#endif /* CHAR_IS_UNSIGNED */
|
||||
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
#define MAXJSAMPLE 255
|
||||
#define CENTERJSAMPLE 128
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 8 */
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE == 12
|
||||
/* JSAMPLE should be the smallest type that will hold the values 0..4095.
|
||||
* On nearly all machines "short" will do nicely.
|
||||
*/
|
||||
|
||||
typedef short JSAMPLE;
|
||||
#define GETJSAMPLE(value) ((int) (value))
|
||||
|
||||
#define MAXJSAMPLE 4095
|
||||
#define CENTERJSAMPLE 2048
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 12 */
|
||||
|
||||
|
||||
/* Representation of a DCT frequency coefficient.
|
||||
* This should be a signed value of at least 16 bits; "short" is usually OK.
|
||||
* Again, we allocate large arrays of these, but you can change to int
|
||||
* if you have memory to burn and "short" is really slow.
|
||||
*/
|
||||
|
||||
typedef short JCOEF;
|
||||
|
||||
|
||||
/* Compressed datastreams are represented as arrays of JOCTET.
|
||||
* These must be EXACTLY 8 bits wide, at least once they are written to
|
||||
* external storage. Note that when using the stdio data source/destination
|
||||
* managers, this is also the data type passed to fread/fwrite.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
|
||||
typedef unsigned char JOCTET;
|
||||
#define GETJOCTET(value) (value)
|
||||
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
|
||||
typedef char JOCTET;
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
#define GETJOCTET(value) (value)
|
||||
#else
|
||||
#define GETJOCTET(value) ((value) & 0xFF)
|
||||
#endif /* CHAR_IS_UNSIGNED */
|
||||
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
|
||||
/* These typedefs are used for various table entries and so forth.
|
||||
* They must be at least as wide as specified; but making them too big
|
||||
* won't cost a huge amount of memory, so we don't provide special
|
||||
* extraction code like we did for JSAMPLE. (In other words, these
|
||||
* typedefs live at a different point on the speed/space tradeoff curve.)
|
||||
*/
|
||||
|
||||
/* UINT8 must hold at least the values 0..255. */
|
||||
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
typedef unsigned char UINT8;
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
typedef char UINT8;
|
||||
#else /* not CHAR_IS_UNSIGNED */
|
||||
typedef short UINT8;
|
||||
#endif /* CHAR_IS_UNSIGNED */
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
/* UINT16 must hold at least the values 0..65535. */
|
||||
|
||||
#ifdef HAVE_UNSIGNED_SHORT
|
||||
typedef unsigned short UINT16;
|
||||
#else /* not HAVE_UNSIGNED_SHORT */
|
||||
typedef unsigned int UINT16;
|
||||
#endif /* HAVE_UNSIGNED_SHORT */
|
||||
|
||||
/* INT16 must hold at least the values -32768..32767. */
|
||||
|
||||
#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
|
||||
typedef short INT16;
|
||||
#endif
|
||||
|
||||
/* INT32 must hold at least signed 32-bit values. */
|
||||
|
||||
#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
|
||||
typedef long INT32;
|
||||
#endif
|
||||
|
||||
/* Datatype used for image dimensions. The JPEG standard only supports
|
||||
* images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
|
||||
* "unsigned int" is sufficient on all machines. However, if you need to
|
||||
* handle larger images and you don't mind deviating from the spec, you
|
||||
* can change this datatype.
|
||||
*/
|
||||
|
||||
typedef unsigned int JDIMENSION;
|
||||
|
||||
#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
|
||||
|
||||
|
||||
/* These macros are used in all function definitions and extern declarations.
|
||||
* You could modify them if you need to change function linkage conventions;
|
||||
* in particular, you'll need to do that to make the library a Windows DLL.
|
||||
* Another application is to make all functions global for use with debuggers
|
||||
* or code profilers that require it.
|
||||
*/
|
||||
|
||||
/* a function called through method pointers: */
|
||||
#define METHODDEF(type) static type
|
||||
/* a function used only in its module: */
|
||||
#define LOCAL(type) static type
|
||||
/* a function referenced thru EXTERNs: */
|
||||
#define GLOBAL(type) type
|
||||
/* a reference to a GLOBAL function: */
|
||||
#define EXTERN(type) extern type
|
||||
|
||||
|
||||
/* This macro is used to declare a "method", that is, a function pointer.
|
||||
* We want to supply prototype parameters if the compiler can cope.
|
||||
* Note that the arglist parameter must be parenthesized!
|
||||
* Again, you can customize this if you need special linkage keywords.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
#define JMETHOD(type,methodname,arglist) type (*methodname) arglist
|
||||
#else
|
||||
#define JMETHOD(type,methodname,arglist) type (*methodname) ()
|
||||
#endif
|
||||
|
||||
|
||||
/* Here is the pseudo-keyword for declaring pointers that must be "far"
|
||||
* on 80x86 machines. Most of the specialized coding for 80x86 is handled
|
||||
* by just saying "FAR *" where such a pointer is needed. In a few places
|
||||
* explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
|
||||
*/
|
||||
|
||||
#ifdef NEED_FAR_POINTERS
|
||||
#define FAR far
|
||||
#else
|
||||
#define FAR
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* On a few systems, type boolean and/or its values FALSE, TRUE may appear
|
||||
* in standard header files. Or you may have conflicts with application-
|
||||
* specific header files that you want to include together with these files.
|
||||
* Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_BOOLEAN
|
||||
typedef int boolean;
|
||||
#endif
|
||||
#ifndef FALSE /* in case these macros already exist */
|
||||
#define FALSE 0 /* values of boolean */
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* The remaining options affect code selection within the JPEG library,
|
||||
* but they don't need to be visible to most applications using the library.
|
||||
* To minimize application namespace pollution, the symbols won't be
|
||||
* defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
|
||||
*/
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
#define JPEG_INTERNAL_OPTIONS
|
||||
#endif
|
||||
|
||||
#ifdef JPEG_INTERNAL_OPTIONS
|
||||
|
||||
|
||||
/*
|
||||
* These defines indicate whether to include various optional functions.
|
||||
* Undefining some of these symbols will produce a smaller but less capable
|
||||
* library. Note that you can leave certain source files out of the
|
||||
* compilation/linking process if you've #undef'd the corresponding symbols.
|
||||
* (You may HAVE to do that if your compiler doesn't like null source files.)
|
||||
*/
|
||||
|
||||
/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */
|
||||
|
||||
/* Capability options common to encoder and decoder: */
|
||||
|
||||
#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */
|
||||
#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */
|
||||
#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */
|
||||
|
||||
/* Encoder capability options: */
|
||||
|
||||
#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
||||
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
||||
#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
||||
#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
|
||||
/* Note: if you selected 12-bit data precision, it is dangerous to turn off
|
||||
* ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit
|
||||
* precision, so jchuff.c normally uses entropy optimization to compute
|
||||
* usable tables for higher precision. If you don't want to do optimization,
|
||||
* you'll have to supply different default Huffman tables.
|
||||
* The exact same statements apply for progressive JPEG: the default tables
|
||||
* don't work for progressive mode. (This may get fixed, however.)
|
||||
*/
|
||||
#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */
|
||||
|
||||
/* Decoder capability options: */
|
||||
|
||||
#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
||||
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
||||
#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
||||
#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
|
||||
#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
|
||||
#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
|
||||
#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
|
||||
#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */
|
||||
#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
|
||||
#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */
|
||||
|
||||
/* more capability options later, no doubt */
|
||||
|
||||
|
||||
/*
|
||||
* Ordering of RGB data in scanlines passed to or from the application.
|
||||
* If your application wants to deal with data in the order B,G,R, just
|
||||
* change these macros. You can also deal with formats such as R,G,B,X
|
||||
* (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing
|
||||
* the offsets will also change the order in which colormap data is organized.
|
||||
* RESTRICTIONS:
|
||||
* 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
|
||||
* 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
|
||||
* useful if you are using JPEG color spaces other than YCbCr or grayscale.
|
||||
* 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
|
||||
* is not 3 (they don't understand about dummy color components!). So you
|
||||
* can't use color quantization if you change that value.
|
||||
*/
|
||||
|
||||
#define RGB_RED 0 /* Offset of Red in an RGB scanline element */
|
||||
#define RGB_GREEN 1 /* Offset of Green */
|
||||
#define RGB_BLUE 2 /* Offset of Blue */
|
||||
#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */
|
||||
|
||||
|
||||
/* Definitions for speed-related optimizations. */
|
||||
|
||||
|
||||
/* If your compiler supports inline functions, define INLINE
|
||||
* as the inline keyword; otherwise define it as empty.
|
||||
*/
|
||||
|
||||
#ifndef INLINE
|
||||
#ifdef __GNUC__ /* for instance, GNU C knows about inline */
|
||||
#define INLINE __inline__
|
||||
#endif
|
||||
#ifndef INLINE
|
||||
#define INLINE /* default is to define it as empty */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
|
||||
* two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER
|
||||
* as short on such a machine. MULTIPLIER must be at least 16 bits wide.
|
||||
*/
|
||||
|
||||
#ifndef MULTIPLIER
|
||||
#define MULTIPLIER int /* type for fastest integer multiply */
|
||||
#endif
|
||||
|
||||
|
||||
/* FAST_FLOAT should be either float or double, whichever is done faster
|
||||
* by your compiler. (Note that this type is only used in the floating point
|
||||
* DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
|
||||
* Typically, float is faster in ANSI C compilers, while double is faster in
|
||||
* pre-ANSI compilers (because they insist on converting to double anyway).
|
||||
* The code below therefore chooses float if we have ANSI-style prototypes.
|
||||
*/
|
||||
|
||||
#ifndef FAST_FLOAT
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
#define FAST_FLOAT float
|
||||
#else
|
||||
#define FAST_FLOAT double
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* JPEG_INTERNAL_OPTIONS */
|
||||
|
@ -1,392 +1,392 @@
|
||||
/*
|
||||
* jpegint.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 provides common declarations for the various JPEG modules.
|
||||
* These declarations are considered internal to the JPEG library; most
|
||||
* applications using the library shouldn't need to include this file.
|
||||
*/
|
||||
|
||||
|
||||
/* Declarations for both compression & decompression */
|
||||
|
||||
typedef enum { /* Operating modes for buffer controllers */
|
||||
JBUF_PASS_THRU, /* Plain stripwise operation */
|
||||
/* Remaining modes require a full-image buffer to have been created */
|
||||
JBUF_SAVE_SOURCE, /* Run source subobject only, save output */
|
||||
JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */
|
||||
JBUF_SAVE_AND_PASS /* Run both subobjects, save output */
|
||||
} J_BUF_MODE;
|
||||
|
||||
/* Values of global_state field (jdapi.c has some dependencies on ordering!) */
|
||||
#define CSTATE_START 100 /* after create_compress */
|
||||
#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */
|
||||
#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */
|
||||
#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */
|
||||
#define DSTATE_START 200 /* after create_decompress */
|
||||
#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */
|
||||
#define DSTATE_READY 202 /* found SOS, ready for start_decompress */
|
||||
#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/
|
||||
#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */
|
||||
#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */
|
||||
#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */
|
||||
#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */
|
||||
#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */
|
||||
#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */
|
||||
#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */
|
||||
|
||||
|
||||
/* Declarations for compression modules */
|
||||
|
||||
/* Master control module */
|
||||
struct jpeg_comp_master {
|
||||
JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, pass_startup, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
|
||||
|
||||
/* State variables made visible to other modules */
|
||||
boolean call_pass_startup; /* True if pass_startup must be called */
|
||||
boolean is_last_pass; /* True during last pass */
|
||||
};
|
||||
|
||||
/* Main buffer control (downsampled-data buffer) */
|
||||
struct jpeg_c_main_controller {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
|
||||
JMETHOD(void, process_data, (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail));
|
||||
};
|
||||
|
||||
/* Compression preprocessing (downsampling input buffer control) */
|
||||
struct jpeg_c_prep_controller {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
|
||||
JMETHOD(void, pre_process_data, (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf,
|
||||
JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail,
|
||||
JSAMPIMAGE output_buf,
|
||||
JDIMENSION *out_row_group_ctr,
|
||||
JDIMENSION out_row_groups_avail));
|
||||
};
|
||||
|
||||
/* Coefficient buffer control */
|
||||
struct jpeg_c_coef_controller {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
|
||||
JMETHOD(boolean, compress_data, (j_compress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf));
|
||||
};
|
||||
|
||||
/* Colorspace conversion */
|
||||
struct jpeg_color_converter {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, color_convert, (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows));
|
||||
};
|
||||
|
||||
/* Downsampling */
|
||||
struct jpeg_downsampler {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, downsample, (j_compress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION in_row_index,
|
||||
JSAMPIMAGE output_buf,
|
||||
JDIMENSION out_row_group_index));
|
||||
|
||||
boolean need_context_rows; /* TRUE if need rows above & below */
|
||||
};
|
||||
|
||||
/* Forward DCT (also controls coefficient quantization) */
|
||||
struct jpeg_forward_dct {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo));
|
||||
/* perhaps this should be an array??? */
|
||||
JMETHOD(void, forward_DCT, (j_compress_ptr cinfo,
|
||||
jpeg_component_info * compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks));
|
||||
};
|
||||
|
||||
/* Entropy encoding */
|
||||
struct jpeg_entropy_encoder {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics));
|
||||
JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data));
|
||||
JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
|
||||
};
|
||||
|
||||
/* Marker writing */
|
||||
struct jpeg_marker_writer {
|
||||
JMETHOD(void, write_file_header, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, write_frame_header, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, write_scan_header, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, write_tables_only, (j_compress_ptr cinfo));
|
||||
/* These routines are exported to allow insertion of extra markers */
|
||||
/* Probably only COM and APPn markers should be written this way */
|
||||
JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker,
|
||||
unsigned int datalen));
|
||||
JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val));
|
||||
};
|
||||
|
||||
|
||||
/* Declarations for decompression modules */
|
||||
|
||||
/* Master control module */
|
||||
struct jpeg_decomp_master {
|
||||
JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo));
|
||||
|
||||
/* State variables made visible to other modules */
|
||||
boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */
|
||||
};
|
||||
|
||||
/* Input control module */
|
||||
struct jpeg_input_controller {
|
||||
JMETHOD(int, consume_input, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo));
|
||||
|
||||
/* State variables made visible to other modules */
|
||||
boolean has_multiple_scans; /* True if file has multiple scans */
|
||||
boolean eoi_reached; /* True when EOI has been consumed */
|
||||
};
|
||||
|
||||
/* Main buffer control (downsampled-data buffer) */
|
||||
struct jpeg_d_main_controller {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
|
||||
JMETHOD(void, process_data, (j_decompress_ptr cinfo,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail));
|
||||
};
|
||||
|
||||
/* Coefficient buffer control */
|
||||
struct jpeg_d_coef_controller {
|
||||
JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(int, consume_data, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(int, decompress_data, (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE output_buf));
|
||||
/* Pointer to array of coefficient virtual arrays, or NULL if none */
|
||||
jvirt_barray_ptr *coef_arrays;
|
||||
};
|
||||
|
||||
/* Decompression postprocessing (color quantization buffer control) */
|
||||
struct jpeg_d_post_controller {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
|
||||
JMETHOD(void, post_process_data, (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail));
|
||||
};
|
||||
|
||||
/* Marker reading & parsing */
|
||||
struct jpeg_marker_reader {
|
||||
JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo));
|
||||
/* Read markers until SOS or EOI.
|
||||
* Returns same codes as are defined for jpeg_consume_input:
|
||||
* JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
|
||||
*/
|
||||
JMETHOD(int, read_markers, (j_decompress_ptr cinfo));
|
||||
/* Read a restart marker --- exported for use by entropy decoder only */
|
||||
jpeg_marker_parser_method read_restart_marker;
|
||||
|
||||
/* State of marker reader --- nominally internal, but applications
|
||||
* supplying COM or APPn handlers might like to know the state.
|
||||
*/
|
||||
boolean saw_SOI; /* found SOI? */
|
||||
boolean saw_SOF; /* found SOF? */
|
||||
int next_restart_num; /* next restart number expected (0-7) */
|
||||
unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */
|
||||
};
|
||||
|
||||
/* Entropy decoding */
|
||||
struct jpeg_entropy_decoder {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
|
||||
JBLOCKROW *MCU_data));
|
||||
|
||||
/* This is here to share code between baseline and progressive decoders; */
|
||||
/* other modules probably should not use it */
|
||||
boolean insufficient_data; /* set TRUE after emitting warning */
|
||||
};
|
||||
|
||||
/* Inverse DCT (also performs dequantization) */
|
||||
typedef JMETHOD(void, inverse_DCT_method_ptr,
|
||||
(j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
|
||||
struct jpeg_inverse_dct {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
|
||||
/* It is useful to allow each component to have a separate IDCT method. */
|
||||
inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS];
|
||||
};
|
||||
|
||||
/* Upsampling (note that upsampler must also call color converter) */
|
||||
struct jpeg_upsampler {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, upsample, (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail));
|
||||
|
||||
boolean need_context_rows; /* TRUE if need rows above & below */
|
||||
};
|
||||
|
||||
/* Colorspace conversion */
|
||||
struct jpeg_color_deconverter {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
||||
JSAMPARRAY output_buf, int num_rows));
|
||||
};
|
||||
|
||||
/* Color quantization or color precision reduction */
|
||||
struct jpeg_color_quantizer {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan));
|
||||
JMETHOD(void, color_quantize, (j_decompress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPARRAY output_buf,
|
||||
int num_rows));
|
||||
JMETHOD(void, finish_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, new_color_map, (j_decompress_ptr cinfo));
|
||||
};
|
||||
|
||||
|
||||
/* Miscellaneous useful macros */
|
||||
|
||||
#undef MAX
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#undef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
|
||||
/* We assume that right shift corresponds to signed division by 2 with
|
||||
* rounding towards minus infinity. This is correct for typical "arithmetic
|
||||
* shift" instructions that shift in copies of the sign bit. But some
|
||||
* C compilers implement >> with an unsigned shift. For these machines you
|
||||
* must define RIGHT_SHIFT_IS_UNSIGNED.
|
||||
* RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
|
||||
* It is only applied with constant shift counts. SHIFT_TEMPS must be
|
||||
* included in the variables of any routine using RIGHT_SHIFT.
|
||||
*/
|
||||
|
||||
#ifdef RIGHT_SHIFT_IS_UNSIGNED
|
||||
#define SHIFT_TEMPS INT32 shift_temp;
|
||||
#define RIGHT_SHIFT(x,shft) \
|
||||
((shift_temp = (x)) < 0 ? \
|
||||
(shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
|
||||
(shift_temp >> (shft)))
|
||||
#else
|
||||
#define SHIFT_TEMPS
|
||||
#define RIGHT_SHIFT(x,shft) ((x) >> (shft))
|
||||
#endif
|
||||
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jinit_compress_master jICompress
|
||||
#define jinit_c_master_control jICMaster
|
||||
#define jinit_c_main_controller jICMainC
|
||||
#define jinit_c_prep_controller jICPrepC
|
||||
#define jinit_c_coef_controller jICCoefC
|
||||
#define jinit_color_converter jICColor
|
||||
#define jinit_downsampler jIDownsampler
|
||||
#define jinit_forward_dct jIFDCT
|
||||
#define jinit_huff_encoder jIHEncoder
|
||||
#define jinit_phuff_encoder jIPHEncoder
|
||||
#define jinit_marker_writer jIMWriter
|
||||
#define jinit_master_decompress jIDMaster
|
||||
#define jinit_d_main_controller jIDMainC
|
||||
#define jinit_d_coef_controller jIDCoefC
|
||||
#define jinit_d_post_controller jIDPostC
|
||||
#define jinit_input_controller jIInCtlr
|
||||
#define jinit_marker_reader jIMReader
|
||||
#define jinit_huff_decoder jIHDecoder
|
||||
#define jinit_phuff_decoder jIPHDecoder
|
||||
#define jinit_inverse_dct jIIDCT
|
||||
#define jinit_upsampler jIUpsampler
|
||||
#define jinit_color_deconverter jIDColor
|
||||
#define jinit_1pass_quantizer jI1Quant
|
||||
#define jinit_2pass_quantizer jI2Quant
|
||||
#define jinit_merged_upsampler jIMUpsampler
|
||||
#define jinit_memory_mgr jIMemMgr
|
||||
#define jdiv_round_up jDivRound
|
||||
#define jround_up jRound
|
||||
#define jcopy_sample_rows jCopySamples
|
||||
#define jcopy_block_row jCopyBlocks
|
||||
#define jzero_far jZeroFar
|
||||
#define jpeg_zigzag_order jZIGTable
|
||||
#define jpeg_natural_order jZAGTable
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
|
||||
/* Compression module initialization routines */
|
||||
EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo,
|
||||
boolean transcode_only));
|
||||
EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo,
|
||||
boolean need_full_buffer));
|
||||
EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo,
|
||||
boolean need_full_buffer));
|
||||
EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo,
|
||||
boolean need_full_buffer));
|
||||
EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo));
|
||||
/* Decompression module initialization routines */
|
||||
EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer));
|
||||
EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer));
|
||||
EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer));
|
||||
EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
|
||||
/* Memory manager initialization */
|
||||
EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
|
||||
|
||||
/* Utility routines in jutils.c */
|
||||
EXTERN(long) jdiv_round_up JPP((long a, long b));
|
||||
EXTERN(long) jround_up JPP((long a, long b));
|
||||
EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
|
||||
JSAMPARRAY output_array, int dest_row,
|
||||
int num_rows, JDIMENSION num_cols));
|
||||
EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
|
||||
JDIMENSION num_blocks));
|
||||
EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
|
||||
/* Constant tables in jutils.c */
|
||||
#if 0 /* This table is not actually needed in v6a */
|
||||
extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */
|
||||
#endif
|
||||
extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
|
||||
|
||||
/* Suppress undefined-structure complaints if necessary. */
|
||||
|
||||
#ifdef INCOMPLETE_TYPES_BROKEN
|
||||
#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */
|
||||
struct jvirt_sarray_control { long dummy; };
|
||||
struct jvirt_barray_control { long dummy; };
|
||||
#endif
|
||||
#endif /* INCOMPLETE_TYPES_BROKEN */
|
||||
/*
|
||||
* jpegint.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, 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 provides common declarations for the various JPEG modules.
|
||||
* These declarations are considered internal to the JPEG library; most
|
||||
* applications using the library shouldn't need to include this file.
|
||||
*/
|
||||
|
||||
|
||||
/* Declarations for both compression & decompression */
|
||||
|
||||
typedef enum { /* Operating modes for buffer controllers */
|
||||
JBUF_PASS_THRU, /* Plain stripwise operation */
|
||||
/* Remaining modes require a full-image buffer to have been created */
|
||||
JBUF_SAVE_SOURCE, /* Run source subobject only, save output */
|
||||
JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */
|
||||
JBUF_SAVE_AND_PASS /* Run both subobjects, save output */
|
||||
} J_BUF_MODE;
|
||||
|
||||
/* Values of global_state field (jdapi.c has some dependencies on ordering!) */
|
||||
#define CSTATE_START 100 /* after create_compress */
|
||||
#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */
|
||||
#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */
|
||||
#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */
|
||||
#define DSTATE_START 200 /* after create_decompress */
|
||||
#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */
|
||||
#define DSTATE_READY 202 /* found SOS, ready for start_decompress */
|
||||
#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/
|
||||
#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */
|
||||
#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */
|
||||
#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */
|
||||
#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */
|
||||
#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */
|
||||
#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */
|
||||
#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */
|
||||
|
||||
|
||||
/* Declarations for compression modules */
|
||||
|
||||
/* Master control module */
|
||||
struct jpeg_comp_master {
|
||||
JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, pass_startup, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
|
||||
|
||||
/* State variables made visible to other modules */
|
||||
boolean call_pass_startup; /* True if pass_startup must be called */
|
||||
boolean is_last_pass; /* True during last pass */
|
||||
};
|
||||
|
||||
/* Main buffer control (downsampled-data buffer) */
|
||||
struct jpeg_c_main_controller {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
|
||||
JMETHOD(void, process_data, (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail));
|
||||
};
|
||||
|
||||
/* Compression preprocessing (downsampling input buffer control) */
|
||||
struct jpeg_c_prep_controller {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
|
||||
JMETHOD(void, pre_process_data, (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf,
|
||||
JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail,
|
||||
JSAMPIMAGE output_buf,
|
||||
JDIMENSION *out_row_group_ctr,
|
||||
JDIMENSION out_row_groups_avail));
|
||||
};
|
||||
|
||||
/* Coefficient buffer control */
|
||||
struct jpeg_c_coef_controller {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
|
||||
JMETHOD(boolean, compress_data, (j_compress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf));
|
||||
};
|
||||
|
||||
/* Colorspace conversion */
|
||||
struct jpeg_color_converter {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, color_convert, (j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows));
|
||||
};
|
||||
|
||||
/* Downsampling */
|
||||
struct jpeg_downsampler {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, downsample, (j_compress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION in_row_index,
|
||||
JSAMPIMAGE output_buf,
|
||||
JDIMENSION out_row_group_index));
|
||||
|
||||
boolean need_context_rows; /* TRUE if need rows above & below */
|
||||
};
|
||||
|
||||
/* Forward DCT (also controls coefficient quantization) */
|
||||
struct jpeg_forward_dct {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo));
|
||||
/* perhaps this should be an array??? */
|
||||
JMETHOD(void, forward_DCT, (j_compress_ptr cinfo,
|
||||
jpeg_component_info * compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks));
|
||||
};
|
||||
|
||||
/* Entropy encoding */
|
||||
struct jpeg_entropy_encoder {
|
||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics));
|
||||
JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data));
|
||||
JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
|
||||
};
|
||||
|
||||
/* Marker writing */
|
||||
struct jpeg_marker_writer {
|
||||
JMETHOD(void, write_file_header, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, write_frame_header, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, write_scan_header, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo));
|
||||
JMETHOD(void, write_tables_only, (j_compress_ptr cinfo));
|
||||
/* These routines are exported to allow insertion of extra markers */
|
||||
/* Probably only COM and APPn markers should be written this way */
|
||||
JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker,
|
||||
unsigned int datalen));
|
||||
JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val));
|
||||
};
|
||||
|
||||
|
||||
/* Declarations for decompression modules */
|
||||
|
||||
/* Master control module */
|
||||
struct jpeg_decomp_master {
|
||||
JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo));
|
||||
|
||||
/* State variables made visible to other modules */
|
||||
boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */
|
||||
};
|
||||
|
||||
/* Input control module */
|
||||
struct jpeg_input_controller {
|
||||
JMETHOD(int, consume_input, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo));
|
||||
|
||||
/* State variables made visible to other modules */
|
||||
boolean has_multiple_scans; /* True if file has multiple scans */
|
||||
boolean eoi_reached; /* True when EOI has been consumed */
|
||||
};
|
||||
|
||||
/* Main buffer control (downsampled-data buffer) */
|
||||
struct jpeg_d_main_controller {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
|
||||
JMETHOD(void, process_data, (j_decompress_ptr cinfo,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail));
|
||||
};
|
||||
|
||||
/* Coefficient buffer control */
|
||||
struct jpeg_d_coef_controller {
|
||||
JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(int, consume_data, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(int, decompress_data, (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE output_buf));
|
||||
/* Pointer to array of coefficient virtual arrays, or NULL if none */
|
||||
jvirt_barray_ptr *coef_arrays;
|
||||
};
|
||||
|
||||
/* Decompression postprocessing (color quantization buffer control) */
|
||||
struct jpeg_d_post_controller {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
|
||||
JMETHOD(void, post_process_data, (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail));
|
||||
};
|
||||
|
||||
/* Marker reading & parsing */
|
||||
struct jpeg_marker_reader {
|
||||
JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo));
|
||||
/* Read markers until SOS or EOI.
|
||||
* Returns same codes as are defined for jpeg_consume_input:
|
||||
* JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
|
||||
*/
|
||||
JMETHOD(int, read_markers, (j_decompress_ptr cinfo));
|
||||
/* Read a restart marker --- exported for use by entropy decoder only */
|
||||
jpeg_marker_parser_method read_restart_marker;
|
||||
|
||||
/* State of marker reader --- nominally internal, but applications
|
||||
* supplying COM or APPn handlers might like to know the state.
|
||||
*/
|
||||
boolean saw_SOI; /* found SOI? */
|
||||
boolean saw_SOF; /* found SOF? */
|
||||
int next_restart_num; /* next restart number expected (0-7) */
|
||||
unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */
|
||||
};
|
||||
|
||||
/* Entropy decoding */
|
||||
struct jpeg_entropy_decoder {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
|
||||
JBLOCKROW *MCU_data));
|
||||
|
||||
/* This is here to share code between baseline and progressive decoders; */
|
||||
/* other modules probably should not use it */
|
||||
boolean insufficient_data; /* set TRUE after emitting warning */
|
||||
};
|
||||
|
||||
/* Inverse DCT (also performs dequantization) */
|
||||
typedef JMETHOD(void, inverse_DCT_method_ptr,
|
||||
(j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col));
|
||||
|
||||
struct jpeg_inverse_dct {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
|
||||
/* It is useful to allow each component to have a separate IDCT method. */
|
||||
inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS];
|
||||
};
|
||||
|
||||
/* Upsampling (note that upsampler must also call color converter) */
|
||||
struct jpeg_upsampler {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, upsample, (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail));
|
||||
|
||||
boolean need_context_rows; /* TRUE if need rows above & below */
|
||||
};
|
||||
|
||||
/* Colorspace conversion */
|
||||
struct jpeg_color_deconverter {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
||||
JSAMPARRAY output_buf, int num_rows));
|
||||
};
|
||||
|
||||
/* Color quantization or color precision reduction */
|
||||
struct jpeg_color_quantizer {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan));
|
||||
JMETHOD(void, color_quantize, (j_decompress_ptr cinfo,
|
||||
JSAMPARRAY input_buf, JSAMPARRAY output_buf,
|
||||
int num_rows));
|
||||
JMETHOD(void, finish_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(void, new_color_map, (j_decompress_ptr cinfo));
|
||||
};
|
||||
|
||||
|
||||
/* Miscellaneous useful macros */
|
||||
|
||||
#undef MAX
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#undef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
|
||||
/* We assume that right shift corresponds to signed division by 2 with
|
||||
* rounding towards minus infinity. This is correct for typical "arithmetic
|
||||
* shift" instructions that shift in copies of the sign bit. But some
|
||||
* C compilers implement >> with an unsigned shift. For these machines you
|
||||
* must define RIGHT_SHIFT_IS_UNSIGNED.
|
||||
* RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
|
||||
* It is only applied with constant shift counts. SHIFT_TEMPS must be
|
||||
* included in the variables of any routine using RIGHT_SHIFT.
|
||||
*/
|
||||
|
||||
#ifdef RIGHT_SHIFT_IS_UNSIGNED
|
||||
#define SHIFT_TEMPS INT32 shift_temp;
|
||||
#define RIGHT_SHIFT(x,shft) \
|
||||
((shift_temp = (x)) < 0 ? \
|
||||
(shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
|
||||
(shift_temp >> (shft)))
|
||||
#else
|
||||
#define SHIFT_TEMPS
|
||||
#define RIGHT_SHIFT(x,shft) ((x) >> (shft))
|
||||
#endif
|
||||
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jinit_compress_master jICompress
|
||||
#define jinit_c_master_control jICMaster
|
||||
#define jinit_c_main_controller jICMainC
|
||||
#define jinit_c_prep_controller jICPrepC
|
||||
#define jinit_c_coef_controller jICCoefC
|
||||
#define jinit_color_converter jICColor
|
||||
#define jinit_downsampler jIDownsampler
|
||||
#define jinit_forward_dct jIFDCT
|
||||
#define jinit_huff_encoder jIHEncoder
|
||||
#define jinit_phuff_encoder jIPHEncoder
|
||||
#define jinit_marker_writer jIMWriter
|
||||
#define jinit_master_decompress jIDMaster
|
||||
#define jinit_d_main_controller jIDMainC
|
||||
#define jinit_d_coef_controller jIDCoefC
|
||||
#define jinit_d_post_controller jIDPostC
|
||||
#define jinit_input_controller jIInCtlr
|
||||
#define jinit_marker_reader jIMReader
|
||||
#define jinit_huff_decoder jIHDecoder
|
||||
#define jinit_phuff_decoder jIPHDecoder
|
||||
#define jinit_inverse_dct jIIDCT
|
||||
#define jinit_upsampler jIUpsampler
|
||||
#define jinit_color_deconverter jIDColor
|
||||
#define jinit_1pass_quantizer jI1Quant
|
||||
#define jinit_2pass_quantizer jI2Quant
|
||||
#define jinit_merged_upsampler jIMUpsampler
|
||||
#define jinit_memory_mgr jIMemMgr
|
||||
#define jdiv_round_up jDivRound
|
||||
#define jround_up jRound
|
||||
#define jcopy_sample_rows jCopySamples
|
||||
#define jcopy_block_row jCopyBlocks
|
||||
#define jzero_far jZeroFar
|
||||
#define jpeg_zigzag_order jZIGTable
|
||||
#define jpeg_natural_order jZAGTable
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
|
||||
/* Compression module initialization routines */
|
||||
EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo,
|
||||
boolean transcode_only));
|
||||
EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo,
|
||||
boolean need_full_buffer));
|
||||
EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo,
|
||||
boolean need_full_buffer));
|
||||
EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo,
|
||||
boolean need_full_buffer));
|
||||
EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo));
|
||||
/* Decompression module initialization routines */
|
||||
EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer));
|
||||
EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer));
|
||||
EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer));
|
||||
EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
|
||||
/* Memory manager initialization */
|
||||
EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
|
||||
|
||||
/* Utility routines in jutils.c */
|
||||
EXTERN(long) jdiv_round_up JPP((long a, long b));
|
||||
EXTERN(long) jround_up JPP((long a, long b));
|
||||
EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
|
||||
JSAMPARRAY output_array, int dest_row,
|
||||
int num_rows, JDIMENSION num_cols));
|
||||
EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
|
||||
JDIMENSION num_blocks));
|
||||
EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
|
||||
/* Constant tables in jutils.c */
|
||||
#if 0 /* This table is not actually needed in v6a */
|
||||
extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */
|
||||
#endif
|
||||
extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
|
||||
|
||||
/* Suppress undefined-structure complaints if necessary. */
|
||||
|
||||
#ifdef INCOMPLETE_TYPES_BROKEN
|
||||
#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */
|
||||
struct jvirt_sarray_control { long dummy; };
|
||||
struct jvirt_barray_control { long dummy; };
|
||||
#endif
|
||||
#endif /* INCOMPLETE_TYPES_BROKEN */
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,179 +1,179 @@
|
||||
/*
|
||||
* jutils.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 tables and miscellaneous utility routines needed
|
||||
* for both compression and decompression.
|
||||
* Note we prefix all global names with "j" to minimize conflicts with
|
||||
* a surrounding application.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/*
|
||||
* jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
|
||||
* of a DCT block read in natural order (left to right, top to bottom).
|
||||
*/
|
||||
|
||||
#if 0 /* This table is not actually needed in v6a */
|
||||
|
||||
const int jpeg_zigzag_order[DCTSIZE2] = {
|
||||
0, 1, 5, 6, 14, 15, 27, 28,
|
||||
2, 4, 7, 13, 16, 26, 29, 42,
|
||||
3, 8, 12, 17, 25, 30, 41, 43,
|
||||
9, 11, 18, 24, 31, 40, 44, 53,
|
||||
10, 19, 23, 32, 39, 45, 52, 54,
|
||||
20, 22, 33, 38, 46, 51, 55, 60,
|
||||
21, 34, 37, 47, 50, 56, 59, 61,
|
||||
35, 36, 48, 49, 57, 58, 62, 63
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* jpeg_natural_order[i] is the natural-order position of the i'th element
|
||||
* of zigzag order.
|
||||
*
|
||||
* When reading corrupted data, the Huffman decoders could attempt
|
||||
* to reference an entry beyond the end of this array (if the decoded
|
||||
* zero run length reaches past the end of the block). To prevent
|
||||
* wild stores without adding an inner-loop test, we put some extra
|
||||
* "63"s after the real entries. This will cause the extra coefficient
|
||||
* to be stored in location 63 of the block, not somewhere random.
|
||||
* The worst case would be a run-length of 15, which means we need 16
|
||||
* fake entries.
|
||||
*/
|
||||
|
||||
const int jpeg_natural_order[DCTSIZE2+16] = {
|
||||
0, 1, 8, 16, 9, 2, 3, 10,
|
||||
17, 24, 32, 25, 18, 11, 4, 5,
|
||||
12, 19, 26, 33, 40, 48, 41, 34,
|
||||
27, 20, 13, 6, 7, 14, 21, 28,
|
||||
35, 42, 49, 56, 57, 50, 43, 36,
|
||||
29, 22, 15, 23, 30, 37, 44, 51,
|
||||
58, 59, 52, 45, 38, 31, 39, 46,
|
||||
53, 60, 61, 54, 47, 55, 62, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
|
||||
63, 63, 63, 63, 63, 63, 63, 63
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Arithmetic utilities
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jdiv_round_up (long a, long b)
|
||||
/* Compute a/b rounded up to next integer, ie, ceil(a/b) */
|
||||
/* Assumes a >= 0, b > 0 */
|
||||
{
|
||||
return (a + b - 1L) / b;
|
||||
}
|
||||
|
||||
|
||||
GLOBAL(long)
|
||||
jround_up (long a, long b)
|
||||
/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
|
||||
/* Assumes a >= 0, b > 0 */
|
||||
{
|
||||
a += b - 1L;
|
||||
return a - (a % b);
|
||||
}
|
||||
|
||||
|
||||
/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
|
||||
* and coefficient-block arrays. This won't work on 80x86 because the arrays
|
||||
* are FAR and we're assuming a small-pointer memory model. However, some
|
||||
* DOS compilers provide far-pointer versions of memcpy() and memset() even
|
||||
* in the small-model libraries. These will be used if USE_FMEM is defined.
|
||||
* Otherwise, the routines below do it the hard way. (The performance cost
|
||||
* is not all that great, because these routines aren't very heavily used.)
|
||||
*/
|
||||
|
||||
#ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */
|
||||
#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size)
|
||||
#define FMEMZERO(target,size) MEMZERO(target,size)
|
||||
#else /* 80x86 case, define if we can */
|
||||
#ifdef USE_FMEM
|
||||
#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
|
||||
#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
GLOBAL(void)
|
||||
jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
|
||||
JSAMPARRAY output_array, int dest_row,
|
||||
int num_rows, JDIMENSION num_cols)
|
||||
/* Copy some rows of samples from one place to another.
|
||||
* num_rows rows are copied from input_array[source_row++]
|
||||
* to output_array[dest_row++]; these areas may overlap for duplication.
|
||||
* The source and destination arrays must be at least as wide as num_cols.
|
||||
*/
|
||||
{
|
||||
JSAMPROW inptr, outptr;
|
||||
#ifdef FMEMCOPY
|
||||
size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
|
||||
#else
|
||||
JDIMENSION count;
|
||||
#endif
|
||||
int row;
|
||||
|
||||
input_array += source_row;
|
||||
output_array += dest_row;
|
||||
|
||||
for (row = num_rows; row > 0; row--) {
|
||||
inptr = *input_array++;
|
||||
outptr = *output_array++;
|
||||
#ifdef FMEMCOPY
|
||||
FMEMCOPY(outptr, inptr, count);
|
||||
#else
|
||||
for (count = num_cols; count > 0; count--)
|
||||
*outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GLOBAL(void)
|
||||
jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
|
||||
JDIMENSION num_blocks)
|
||||
/* Copy a row of coefficient blocks from one place to another. */
|
||||
{
|
||||
#ifdef FMEMCOPY
|
||||
FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
|
||||
#else
|
||||
JCOEFPTR inptr, outptr;
|
||||
long count;
|
||||
|
||||
inptr = (JCOEFPTR) input_row;
|
||||
outptr = (JCOEFPTR) output_row;
|
||||
for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
|
||||
*outptr++ = *inptr++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
GLOBAL(void)
|
||||
jzero_far (void FAR * target, size_t bytestozero)
|
||||
/* Zero out a chunk of FAR memory. */
|
||||
/* This might be sample-array data, block-array data, or alloc_large data. */
|
||||
{
|
||||
#ifdef FMEMZERO
|
||||
FMEMZERO(target, bytestozero);
|
||||
#else
|
||||
char FAR * ptr = (char FAR *) target;
|
||||
size_t count;
|
||||
|
||||
for (count = bytestozero; count > 0; count--) {
|
||||
*ptr++ = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* jutils.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 tables and miscellaneous utility routines needed
|
||||
* for both compression and decompression.
|
||||
* Note we prefix all global names with "j" to minimize conflicts with
|
||||
* a surrounding application.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/*
|
||||
* jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
|
||||
* of a DCT block read in natural order (left to right, top to bottom).
|
||||
*/
|
||||
|
||||
#if 0 /* This table is not actually needed in v6a */
|
||||
|
||||
const int jpeg_zigzag_order[DCTSIZE2] = {
|
||||
0, 1, 5, 6, 14, 15, 27, 28,
|
||||
2, 4, 7, 13, 16, 26, 29, 42,
|
||||
3, 8, 12, 17, 25, 30, 41, 43,
|
||||
9, 11, 18, 24, 31, 40, 44, 53,
|
||||
10, 19, 23, 32, 39, 45, 52, 54,
|
||||
20, 22, 33, 38, 46, 51, 55, 60,
|
||||
21, 34, 37, 47, 50, 56, 59, 61,
|
||||
35, 36, 48, 49, 57, 58, 62, 63
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* jpeg_natural_order[i] is the natural-order position of the i'th element
|
||||
* of zigzag order.
|
||||
*
|
||||
* When reading corrupted data, the Huffman decoders could attempt
|
||||
* to reference an entry beyond the end of this array (if the decoded
|
||||
* zero run length reaches past the end of the block). To prevent
|
||||
* wild stores without adding an inner-loop test, we put some extra
|
||||
* "63"s after the real entries. This will cause the extra coefficient
|
||||
* to be stored in location 63 of the block, not somewhere random.
|
||||
* The worst case would be a run-length of 15, which means we need 16
|
||||
* fake entries.
|
||||
*/
|
||||
|
||||
const int jpeg_natural_order[DCTSIZE2+16] = {
|
||||
0, 1, 8, 16, 9, 2, 3, 10,
|
||||
17, 24, 32, 25, 18, 11, 4, 5,
|
||||
12, 19, 26, 33, 40, 48, 41, 34,
|
||||
27, 20, 13, 6, 7, 14, 21, 28,
|
||||
35, 42, 49, 56, 57, 50, 43, 36,
|
||||
29, 22, 15, 23, 30, 37, 44, 51,
|
||||
58, 59, 52, 45, 38, 31, 39, 46,
|
||||
53, 60, 61, 54, 47, 55, 62, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
|
||||
63, 63, 63, 63, 63, 63, 63, 63
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Arithmetic utilities
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jdiv_round_up (long a, long b)
|
||||
/* Compute a/b rounded up to next integer, ie, ceil(a/b) */
|
||||
/* Assumes a >= 0, b > 0 */
|
||||
{
|
||||
return (a + b - 1L) / b;
|
||||
}
|
||||
|
||||
|
||||
GLOBAL(long)
|
||||
jround_up (long a, long b)
|
||||
/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
|
||||
/* Assumes a >= 0, b > 0 */
|
||||
{
|
||||
a += b - 1L;
|
||||
return a - (a % b);
|
||||
}
|
||||
|
||||
|
||||
/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
|
||||
* and coefficient-block arrays. This won't work on 80x86 because the arrays
|
||||
* are FAR and we're assuming a small-pointer memory model. However, some
|
||||
* DOS compilers provide far-pointer versions of memcpy() and memset() even
|
||||
* in the small-model libraries. These will be used if USE_FMEM is defined.
|
||||
* Otherwise, the routines below do it the hard way. (The performance cost
|
||||
* is not all that great, because these routines aren't very heavily used.)
|
||||
*/
|
||||
|
||||
#ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */
|
||||
#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size)
|
||||
#define FMEMZERO(target,size) MEMZERO(target,size)
|
||||
#else /* 80x86 case, define if we can */
|
||||
#ifdef USE_FMEM
|
||||
#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
|
||||
#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
GLOBAL(void)
|
||||
jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
|
||||
JSAMPARRAY output_array, int dest_row,
|
||||
int num_rows, JDIMENSION num_cols)
|
||||
/* Copy some rows of samples from one place to another.
|
||||
* num_rows rows are copied from input_array[source_row++]
|
||||
* to output_array[dest_row++]; these areas may overlap for duplication.
|
||||
* The source and destination arrays must be at least as wide as num_cols.
|
||||
*/
|
||||
{
|
||||
JSAMPROW inptr, outptr;
|
||||
#ifdef FMEMCOPY
|
||||
size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
|
||||
#else
|
||||
JDIMENSION count;
|
||||
#endif
|
||||
int row;
|
||||
|
||||
input_array += source_row;
|
||||
output_array += dest_row;
|
||||
|
||||
for (row = num_rows; row > 0; row--) {
|
||||
inptr = *input_array++;
|
||||
outptr = *output_array++;
|
||||
#ifdef FMEMCOPY
|
||||
FMEMCOPY(outptr, inptr, count);
|
||||
#else
|
||||
for (count = num_cols; count > 0; count--)
|
||||
*outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GLOBAL(void)
|
||||
jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
|
||||
JDIMENSION num_blocks)
|
||||
/* Copy a row of coefficient blocks from one place to another. */
|
||||
{
|
||||
#ifdef FMEMCOPY
|
||||
FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
|
||||
#else
|
||||
JCOEFPTR inptr, outptr;
|
||||
long count;
|
||||
|
||||
inptr = (JCOEFPTR) input_row;
|
||||
outptr = (JCOEFPTR) output_row;
|
||||
for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
|
||||
*outptr++ = *inptr++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
GLOBAL(void)
|
||||
jzero_far (void FAR * target, size_t bytestozero)
|
||||
/* Zero out a chunk of FAR memory. */
|
||||
/* This might be sample-array data, block-array data, or alloc_large data. */
|
||||
{
|
||||
#ifdef FMEMZERO
|
||||
FMEMZERO(target, bytestozero);
|
||||
#else
|
||||
char FAR * ptr = (char FAR *) target;
|
||||
size_t count;
|
||||
|
||||
for (count = bytestozero; count > 0; count--) {
|
||||
*ptr++ = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
/*
|
||||
* jversion.h
|
||||
*
|
||||
* Copyright (C) 1991-1998, 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 software version identification.
|
||||
*/
|
||||
|
||||
|
||||
#define JVERSION "6b 27-Mar-1998"
|
||||
|
||||
#define JCOPYRIGHT "Copyright (C) 1998, Thomas G. Lane"
|
||||
/*
|
||||
* jversion.h
|
||||
*
|
||||
* Copyright (C) 1991-1998, 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 software version identification.
|
||||
*/
|
||||
|
||||
|
||||
#define JVERSION "6b 27-Mar-1998"
|
||||
|
||||
#define JCOPYRIGHT "Copyright (C) 1998, Thomas G. Lane"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,135 +1,135 @@
|
||||
/*
|
||||
* transupp.h
|
||||
*
|
||||
* Copyright (C) 1997, 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 declarations for image transformation routines and
|
||||
* other utility code used by the jpegtran sample application. These are
|
||||
* NOT part of the core JPEG library. But we keep these routines separate
|
||||
* from jpegtran.c to ease the task of maintaining jpegtran-like programs
|
||||
* that have other user interfaces.
|
||||
*
|
||||
* NOTE: all the routines declared here have very specific requirements
|
||||
* about when they are to be executed during the reading and writing of the
|
||||
* source and destination files. See the comments in transupp.c, or see
|
||||
* jpegtran.c for an example of correct usage.
|
||||
*/
|
||||
|
||||
/* If you happen not to want the image transform support, disable it here */
|
||||
#ifndef TRANSFORMS_SUPPORTED
|
||||
#define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */
|
||||
#endif
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jtransform_request_workspace jTrRequest
|
||||
#define jtransform_adjust_parameters jTrAdjust
|
||||
#define jtransform_execute_transformation jTrExec
|
||||
#define jcopy_markers_setup jCMrkSetup
|
||||
#define jcopy_markers_execute jCMrkExec
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
|
||||
/*
|
||||
* Codes for supported types of image transformations.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
JXFORM_NONE, /* no transformation */
|
||||
JXFORM_FLIP_H, /* horizontal flip */
|
||||
JXFORM_FLIP_V, /* vertical flip */
|
||||
JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */
|
||||
JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */
|
||||
JXFORM_ROT_90, /* 90-degree clockwise rotation */
|
||||
JXFORM_ROT_180, /* 180-degree rotation */
|
||||
JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */
|
||||
} JXFORM_CODE;
|
||||
|
||||
/*
|
||||
* Although rotating and flipping data expressed as DCT coefficients is not
|
||||
* hard, there is an asymmetry in the JPEG format specification for images
|
||||
* whose dimensions aren't multiples of the iMCU size. The right and bottom
|
||||
* image edges are padded out to the next iMCU boundary with junk data; but
|
||||
* no padding is possible at the top and left edges. If we were to flip
|
||||
* the whole image including the pad data, then pad garbage would become
|
||||
* visible at the top and/or left, and real pixels would disappear into the
|
||||
* pad margins --- perhaps permanently, since encoders & decoders may not
|
||||
* bother to preserve DCT blocks that appear to be completely outside the
|
||||
* nominal image area. So, we have to exclude any partial iMCUs from the
|
||||
* basic transformation.
|
||||
*
|
||||
* Transpose is the only transformation that can handle partial iMCUs at the
|
||||
* right and bottom edges completely cleanly. flip_h can flip partial iMCUs
|
||||
* at the bottom, but leaves any partial iMCUs at the right edge untouched.
|
||||
* Similarly flip_v leaves any partial iMCUs at the bottom edge untouched.
|
||||
* The other transforms are defined as combinations of these basic transforms
|
||||
* and process edge blocks in a way that preserves the equivalence.
|
||||
*
|
||||
* The "trim" option causes untransformable partial iMCUs to be dropped;
|
||||
* this is not strictly lossless, but it usually gives the best-looking
|
||||
* result for odd-size images. Note that when this option is active,
|
||||
* the expected mathematical equivalences between the transforms may not hold.
|
||||
* (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim
|
||||
* followed by -rot 180 -trim trims both edges.)
|
||||
*
|
||||
* We also offer a "force to grayscale" option, which simply discards the
|
||||
* chrominance channels of a YCbCr image. This is lossless in the sense that
|
||||
* the luminance channel is preserved exactly. It's not the same kind of
|
||||
* thing as the rotate/flip transformations, but it's convenient to handle it
|
||||
* as part of this package, mainly because the transformation routines have to
|
||||
* be aware of the option to know how many components to work on.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* Options: set by caller */
|
||||
JXFORM_CODE transform; /* image transform operator */
|
||||
boolean trim; /* if TRUE, trim partial MCUs as needed */
|
||||
boolean force_grayscale; /* if TRUE, convert color image to grayscale */
|
||||
|
||||
/* Internal workspace: caller should not touch these */
|
||||
int num_components; /* # of components in workspace */
|
||||
jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */
|
||||
} jpeg_transform_info;
|
||||
|
||||
|
||||
#if TRANSFORMS_SUPPORTED
|
||||
|
||||
/* Request any required workspace */
|
||||
EXTERN(void) jtransform_request_workspace
|
||||
JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info));
|
||||
/* Adjust output image parameters */
|
||||
EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters
|
||||
JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
|
||||
jvirt_barray_ptr *src_coef_arrays,
|
||||
jpeg_transform_info *info));
|
||||
/* Execute the actual transformation, if any */
|
||||
EXTERN(void) jtransform_execute_transformation
|
||||
JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
|
||||
jvirt_barray_ptr *src_coef_arrays,
|
||||
jpeg_transform_info *info));
|
||||
|
||||
#endif /* TRANSFORMS_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Support for copying optional markers from source to destination file.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
JCOPYOPT_NONE, /* copy no optional markers */
|
||||
JCOPYOPT_COMMENTS, /* copy only comment (COM) markers */
|
||||
JCOPYOPT_ALL /* copy all optional markers */
|
||||
} JCOPY_OPTION;
|
||||
|
||||
#define JCOPYOPT_DEFAULT JCOPYOPT_COMMENTS /* recommended default */
|
||||
|
||||
/* Setup decompression object to save desired markers in memory */
|
||||
EXTERN(void) jcopy_markers_setup
|
||||
JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option));
|
||||
/* Copy markers saved in the given source object to the destination object */
|
||||
EXTERN(void) jcopy_markers_execute
|
||||
JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
|
||||
JCOPY_OPTION option));
|
||||
/*
|
||||
* transupp.h
|
||||
*
|
||||
* Copyright (C) 1997, 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 declarations for image transformation routines and
|
||||
* other utility code used by the jpegtran sample application. These are
|
||||
* NOT part of the core JPEG library. But we keep these routines separate
|
||||
* from jpegtran.c to ease the task of maintaining jpegtran-like programs
|
||||
* that have other user interfaces.
|
||||
*
|
||||
* NOTE: all the routines declared here have very specific requirements
|
||||
* about when they are to be executed during the reading and writing of the
|
||||
* source and destination files. See the comments in transupp.c, or see
|
||||
* jpegtran.c for an example of correct usage.
|
||||
*/
|
||||
|
||||
/* If you happen not to want the image transform support, disable it here */
|
||||
#ifndef TRANSFORMS_SUPPORTED
|
||||
#define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */
|
||||
#endif
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jtransform_request_workspace jTrRequest
|
||||
#define jtransform_adjust_parameters jTrAdjust
|
||||
#define jtransform_execute_transformation jTrExec
|
||||
#define jcopy_markers_setup jCMrkSetup
|
||||
#define jcopy_markers_execute jCMrkExec
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
|
||||
/*
|
||||
* Codes for supported types of image transformations.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
JXFORM_NONE, /* no transformation */
|
||||
JXFORM_FLIP_H, /* horizontal flip */
|
||||
JXFORM_FLIP_V, /* vertical flip */
|
||||
JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */
|
||||
JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */
|
||||
JXFORM_ROT_90, /* 90-degree clockwise rotation */
|
||||
JXFORM_ROT_180, /* 180-degree rotation */
|
||||
JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */
|
||||
} JXFORM_CODE;
|
||||
|
||||
/*
|
||||
* Although rotating and flipping data expressed as DCT coefficients is not
|
||||
* hard, there is an asymmetry in the JPEG format specification for images
|
||||
* whose dimensions aren't multiples of the iMCU size. The right and bottom
|
||||
* image edges are padded out to the next iMCU boundary with junk data; but
|
||||
* no padding is possible at the top and left edges. If we were to flip
|
||||
* the whole image including the pad data, then pad garbage would become
|
||||
* visible at the top and/or left, and real pixels would disappear into the
|
||||
* pad margins --- perhaps permanently, since encoders & decoders may not
|
||||
* bother to preserve DCT blocks that appear to be completely outside the
|
||||
* nominal image area. So, we have to exclude any partial iMCUs from the
|
||||
* basic transformation.
|
||||
*
|
||||
* Transpose is the only transformation that can handle partial iMCUs at the
|
||||
* right and bottom edges completely cleanly. flip_h can flip partial iMCUs
|
||||
* at the bottom, but leaves any partial iMCUs at the right edge untouched.
|
||||
* Similarly flip_v leaves any partial iMCUs at the bottom edge untouched.
|
||||
* The other transforms are defined as combinations of these basic transforms
|
||||
* and process edge blocks in a way that preserves the equivalence.
|
||||
*
|
||||
* The "trim" option causes untransformable partial iMCUs to be dropped;
|
||||
* this is not strictly lossless, but it usually gives the best-looking
|
||||
* result for odd-size images. Note that when this option is active,
|
||||
* the expected mathematical equivalences between the transforms may not hold.
|
||||
* (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim
|
||||
* followed by -rot 180 -trim trims both edges.)
|
||||
*
|
||||
* We also offer a "force to grayscale" option, which simply discards the
|
||||
* chrominance channels of a YCbCr image. This is lossless in the sense that
|
||||
* the luminance channel is preserved exactly. It's not the same kind of
|
||||
* thing as the rotate/flip transformations, but it's convenient to handle it
|
||||
* as part of this package, mainly because the transformation routines have to
|
||||
* be aware of the option to know how many components to work on.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* Options: set by caller */
|
||||
JXFORM_CODE transform; /* image transform operator */
|
||||
boolean trim; /* if TRUE, trim partial MCUs as needed */
|
||||
boolean force_grayscale; /* if TRUE, convert color image to grayscale */
|
||||
|
||||
/* Internal workspace: caller should not touch these */
|
||||
int num_components; /* # of components in workspace */
|
||||
jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */
|
||||
} jpeg_transform_info;
|
||||
|
||||
|
||||
#if TRANSFORMS_SUPPORTED
|
||||
|
||||
/* Request any required workspace */
|
||||
EXTERN(void) jtransform_request_workspace
|
||||
JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info));
|
||||
/* Adjust output image parameters */
|
||||
EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters
|
||||
JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
|
||||
jvirt_barray_ptr *src_coef_arrays,
|
||||
jpeg_transform_info *info));
|
||||
/* Execute the actual transformation, if any */
|
||||
EXTERN(void) jtransform_execute_transformation
|
||||
JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
|
||||
jvirt_barray_ptr *src_coef_arrays,
|
||||
jpeg_transform_info *info));
|
||||
|
||||
#endif /* TRANSFORMS_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Support for copying optional markers from source to destination file.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
JCOPYOPT_NONE, /* copy no optional markers */
|
||||
JCOPYOPT_COMMENTS, /* copy only comment (COM) markers */
|
||||
JCOPYOPT_ALL /* copy all optional markers */
|
||||
} JCOPY_OPTION;
|
||||
|
||||
#define JCOPYOPT_DEFAULT JCOPYOPT_COMMENTS /* recommended default */
|
||||
|
||||
/* Setup decompression object to save desired markers in memory */
|
||||
EXTERN(void) jcopy_markers_setup
|
||||
JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option));
|
||||
/* Copy markers saved in the given source object to the destination object */
|
||||
EXTERN(void) jcopy_markers_execute
|
||||
JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
|
||||
JCOPY_OPTION option));
|
||||
|
@ -1,455 +1,455 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
#if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && JUCE_USE_COREIMAGE_LOADER
|
||||
Image juce_loadWithCoreImage (InputStream& input);
|
||||
#else
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (6385)
|
||||
|
||||
//==============================================================================
|
||||
class GIFLoader
|
||||
{
|
||||
public:
|
||||
GIFLoader (InputStream& in)
|
||||
: input (in),
|
||||
dataBlockIsZero (false), fresh (false), finished (false),
|
||||
currentBit (0), lastBit (0), lastByteIndex (0),
|
||||
codeSize (0), setCodeSize (0), maxCode (0), maxCodeSize (0),
|
||||
firstcode (0), oldcode (0), clearCode (0), endCode (0)
|
||||
{
|
||||
int imageWidth, imageHeight;
|
||||
if (! getSizeFromHeader (imageWidth, imageHeight))
|
||||
return;
|
||||
|
||||
uint8 buf [16];
|
||||
if (in.read (buf, 3) != 3)
|
||||
return;
|
||||
|
||||
int numColours = 2 << (buf[0] & 7);
|
||||
int transparent = -1;
|
||||
|
||||
if ((buf[0] & 0x80) != 0)
|
||||
readPalette (numColours);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (input.read (buf, 1) != 1 || buf[0] == ';')
|
||||
break;
|
||||
|
||||
if (buf[0] == '!')
|
||||
{
|
||||
if (readExtension (transparent))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (buf[0] != ',')
|
||||
continue;
|
||||
|
||||
if (input.read (buf, 9) == 9)
|
||||
{
|
||||
imageWidth = (int) ByteOrder::littleEndianShort (buf + 4);
|
||||
imageHeight = (int) ByteOrder::littleEndianShort (buf + 6);
|
||||
|
||||
numColours = 2 << (buf[8] & 7);
|
||||
|
||||
if ((buf[8] & 0x80) != 0)
|
||||
if (! readPalette (numColours))
|
||||
break;
|
||||
|
||||
image = Image (transparent >= 0 ? Image::ARGB : Image::RGB,
|
||||
imageWidth, imageHeight, transparent >= 0);
|
||||
|
||||
image.getProperties()->set ("originalImageHadAlpha", transparent >= 0);
|
||||
|
||||
readImage ((buf[8] & 0x40) != 0, transparent);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Image image;
|
||||
|
||||
private:
|
||||
InputStream& input;
|
||||
uint8 buffer [260];
|
||||
PixelARGB palette [256];
|
||||
bool dataBlockIsZero, fresh, finished;
|
||||
int currentBit, lastBit, lastByteIndex;
|
||||
int codeSize, setCodeSize;
|
||||
int maxCode, maxCodeSize;
|
||||
int firstcode, oldcode;
|
||||
int clearCode, endCode;
|
||||
enum { maxGifCode = 1 << 12 };
|
||||
int table [2] [maxGifCode];
|
||||
int stack [2 * maxGifCode];
|
||||
int* sp;
|
||||
|
||||
bool getSizeFromHeader (int& w, int& h)
|
||||
{
|
||||
// Add an extra byte for the zero terminator
|
||||
char b[7]{};
|
||||
|
||||
if (input.read (b, 6) == 6
|
||||
&& (strncmp ("GIF87a", b, 6) == 0
|
||||
|| strncmp ("GIF89a", b, 6) == 0))
|
||||
{
|
||||
if (input.read (b, 4) == 4)
|
||||
{
|
||||
w = (int) ByteOrder::littleEndianShort (b);
|
||||
h = (int) ByteOrder::littleEndianShort (b + 2);
|
||||
return w > 0 && h > 0;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool readPalette (const int numCols)
|
||||
{
|
||||
for (int i = 0; i < numCols; ++i)
|
||||
{
|
||||
uint8 rgb[4];
|
||||
input.read (rgb, 3);
|
||||
|
||||
palette[i].setARGB (0xff, rgb[0], rgb[1], rgb[2]);
|
||||
palette[i].premultiply();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int readDataBlock (uint8* const dest)
|
||||
{
|
||||
uint8 n;
|
||||
if (input.read (&n, 1) == 1)
|
||||
{
|
||||
dataBlockIsZero = (n == 0);
|
||||
|
||||
if (dataBlockIsZero || (input.read (dest, n) == n))
|
||||
return n;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int readExtension (int& transparent)
|
||||
{
|
||||
uint8 type;
|
||||
if (input.read (&type, 1) != 1)
|
||||
return false;
|
||||
|
||||
uint8 b [260];
|
||||
int n = 0;
|
||||
|
||||
if (type == 0xf9)
|
||||
{
|
||||
n = readDataBlock (b);
|
||||
if (n < 0)
|
||||
return 1;
|
||||
|
||||
if ((b[0] & 1) != 0)
|
||||
transparent = b[3];
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
n = readDataBlock (b);
|
||||
}
|
||||
while (n > 0);
|
||||
|
||||
return n >= 0;
|
||||
}
|
||||
|
||||
void clearTable()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < clearCode; ++i)
|
||||
{
|
||||
table[0][i] = 0;
|
||||
table[1][i] = i;
|
||||
}
|
||||
|
||||
for (; i < maxGifCode; ++i)
|
||||
{
|
||||
table[0][i] = 0;
|
||||
table[1][i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void initialise (const int inputCodeSize)
|
||||
{
|
||||
setCodeSize = inputCodeSize;
|
||||
codeSize = setCodeSize + 1;
|
||||
clearCode = 1 << setCodeSize;
|
||||
endCode = clearCode + 1;
|
||||
maxCodeSize = 2 * clearCode;
|
||||
maxCode = clearCode + 2;
|
||||
|
||||
getCode (0, true);
|
||||
|
||||
fresh = true;
|
||||
clearTable();
|
||||
sp = stack;
|
||||
}
|
||||
|
||||
int readLZWByte()
|
||||
{
|
||||
if (fresh)
|
||||
{
|
||||
fresh = false;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
firstcode = oldcode = getCode (codeSize, false);
|
||||
|
||||
if (firstcode != clearCode)
|
||||
return firstcode;
|
||||
}
|
||||
}
|
||||
|
||||
if (sp > stack)
|
||||
return *--sp;
|
||||
|
||||
int code;
|
||||
|
||||
while ((code = getCode (codeSize, false)) >= 0)
|
||||
{
|
||||
if (code == clearCode)
|
||||
{
|
||||
clearTable();
|
||||
codeSize = setCodeSize + 1;
|
||||
maxCodeSize = 2 * clearCode;
|
||||
maxCode = clearCode + 2;
|
||||
sp = stack;
|
||||
firstcode = oldcode = getCode (codeSize, false);
|
||||
return firstcode;
|
||||
}
|
||||
else if (code == endCode)
|
||||
{
|
||||
if (dataBlockIsZero)
|
||||
return -2;
|
||||
|
||||
uint8 buf [260];
|
||||
int n;
|
||||
|
||||
while ((n = readDataBlock (buf)) > 0)
|
||||
{}
|
||||
|
||||
if (n != 0)
|
||||
return -2;
|
||||
}
|
||||
|
||||
const int incode = code;
|
||||
|
||||
if (code >= maxCode)
|
||||
{
|
||||
*sp++ = firstcode;
|
||||
code = oldcode;
|
||||
}
|
||||
|
||||
while (code >= clearCode)
|
||||
{
|
||||
*sp++ = table[1][code];
|
||||
if (code == table[0][code])
|
||||
return -2;
|
||||
|
||||
code = table[0][code];
|
||||
}
|
||||
|
||||
*sp++ = firstcode = table[1][code];
|
||||
|
||||
if ((code = maxCode) < maxGifCode)
|
||||
{
|
||||
table[0][code] = oldcode;
|
||||
table[1][code] = firstcode;
|
||||
++maxCode;
|
||||
|
||||
if (maxCode >= maxCodeSize && maxCodeSize < maxGifCode)
|
||||
{
|
||||
maxCodeSize <<= 1;
|
||||
++codeSize;
|
||||
}
|
||||
}
|
||||
|
||||
oldcode = incode;
|
||||
|
||||
if (sp > stack)
|
||||
return *--sp;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int getCode (const int codeSize_, const bool shouldInitialise)
|
||||
{
|
||||
if (shouldInitialise)
|
||||
{
|
||||
currentBit = 0;
|
||||
lastBit = 0;
|
||||
finished = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((currentBit + codeSize_) >= lastBit)
|
||||
{
|
||||
if (finished)
|
||||
return -1;
|
||||
|
||||
buffer[0] = buffer [lastByteIndex - 2];
|
||||
buffer[1] = buffer [lastByteIndex - 1];
|
||||
|
||||
const int n = readDataBlock (buffer + 2);
|
||||
|
||||
if (n == 0)
|
||||
finished = true;
|
||||
|
||||
lastByteIndex = 2 + n;
|
||||
currentBit = (currentBit - lastBit) + 16;
|
||||
lastBit = (2 + n) * 8 ;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
int i = currentBit;
|
||||
|
||||
for (int j = 0; j < codeSize_; ++j)
|
||||
{
|
||||
result |= ((buffer[i >> 3] & (1 << (i & 7))) != 0) << j;
|
||||
++i;
|
||||
}
|
||||
|
||||
currentBit += codeSize_;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool readImage (const int interlace, const int transparent)
|
||||
{
|
||||
uint8 c;
|
||||
if (input.read (&c, 1) != 1)
|
||||
return false;
|
||||
|
||||
initialise (c);
|
||||
|
||||
if (transparent >= 0)
|
||||
palette [transparent].setARGB (0, 0, 0, 0);
|
||||
|
||||
int xpos = 0, ypos = 0, yStep = 8, pass = 0;
|
||||
|
||||
const Image::BitmapData destData (image, Image::BitmapData::writeOnly);
|
||||
uint8* p = destData.getPixelPointer (0, 0);
|
||||
const bool hasAlpha = image.hasAlphaChannel();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const int index = readLZWByte();
|
||||
if (index < 0)
|
||||
break;
|
||||
|
||||
if (hasAlpha)
|
||||
((PixelARGB*) p)->set (palette [index]);
|
||||
else
|
||||
((PixelRGB*) p)->set (palette [index]);
|
||||
|
||||
p += destData.pixelStride;
|
||||
|
||||
if (++xpos == destData.width)
|
||||
{
|
||||
xpos = 0;
|
||||
|
||||
if (interlace)
|
||||
{
|
||||
ypos += yStep;
|
||||
|
||||
while (ypos >= destData.height)
|
||||
{
|
||||
switch (++pass)
|
||||
{
|
||||
case 1: ypos = 4; yStep = 8; break;
|
||||
case 2: ypos = 2; yStep = 4; break;
|
||||
case 3: ypos = 1; yStep = 2; break;
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (++ypos >= destData.height)
|
||||
break;
|
||||
}
|
||||
|
||||
p = destData.getPixelPointer (xpos, ypos);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (GIFLoader)
|
||||
};
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
GIFImageFormat::GIFImageFormat() {}
|
||||
GIFImageFormat::~GIFImageFormat() {}
|
||||
|
||||
String GIFImageFormat::getFormatName() { return "GIF"; }
|
||||
bool GIFImageFormat::usesFileExtension (const File& f) { return f.hasFileExtension ("gif"); }
|
||||
|
||||
bool GIFImageFormat::canUnderstand (InputStream& in)
|
||||
{
|
||||
char header [4];
|
||||
|
||||
return (in.read (header, sizeof (header)) == (int) sizeof (header))
|
||||
&& header[0] == 'G'
|
||||
&& header[1] == 'I'
|
||||
&& header[2] == 'F';
|
||||
}
|
||||
|
||||
Image GIFImageFormat::decodeImage (InputStream& in)
|
||||
{
|
||||
#if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && JUCE_USE_COREIMAGE_LOADER
|
||||
return juce_loadWithCoreImage (in);
|
||||
#else
|
||||
const std::unique_ptr<GIFLoader> loader (new GIFLoader (in));
|
||||
return loader->image;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GIFImageFormat::writeImageToStream (const Image& /*sourceImage*/, OutputStream& /*destStream*/)
|
||||
{
|
||||
jassertfalse; // writing isn't implemented for GIFs!
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
#if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && JUCE_USE_COREIMAGE_LOADER
|
||||
Image juce_loadWithCoreImage (InputStream& input);
|
||||
#else
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (6385)
|
||||
|
||||
//==============================================================================
|
||||
class GIFLoader
|
||||
{
|
||||
public:
|
||||
GIFLoader (InputStream& in)
|
||||
: input (in),
|
||||
dataBlockIsZero (false), fresh (false), finished (false),
|
||||
currentBit (0), lastBit (0), lastByteIndex (0),
|
||||
codeSize (0), setCodeSize (0), maxCode (0), maxCodeSize (0),
|
||||
firstcode (0), oldcode (0), clearCode (0), endCode (0)
|
||||
{
|
||||
int imageWidth, imageHeight;
|
||||
if (! getSizeFromHeader (imageWidth, imageHeight))
|
||||
return;
|
||||
|
||||
uint8 buf [16];
|
||||
if (in.read (buf, 3) != 3)
|
||||
return;
|
||||
|
||||
int numColours = 2 << (buf[0] & 7);
|
||||
int transparent = -1;
|
||||
|
||||
if ((buf[0] & 0x80) != 0)
|
||||
readPalette (numColours);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (input.read (buf, 1) != 1 || buf[0] == ';')
|
||||
break;
|
||||
|
||||
if (buf[0] == '!')
|
||||
{
|
||||
if (readExtension (transparent))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (buf[0] != ',')
|
||||
continue;
|
||||
|
||||
if (input.read (buf, 9) == 9)
|
||||
{
|
||||
imageWidth = (int) ByteOrder::littleEndianShort (buf + 4);
|
||||
imageHeight = (int) ByteOrder::littleEndianShort (buf + 6);
|
||||
|
||||
numColours = 2 << (buf[8] & 7);
|
||||
|
||||
if ((buf[8] & 0x80) != 0)
|
||||
if (! readPalette (numColours))
|
||||
break;
|
||||
|
||||
image = Image (transparent >= 0 ? Image::ARGB : Image::RGB,
|
||||
imageWidth, imageHeight, transparent >= 0);
|
||||
|
||||
image.getProperties()->set ("originalImageHadAlpha", transparent >= 0);
|
||||
|
||||
readImage ((buf[8] & 0x40) != 0, transparent);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Image image;
|
||||
|
||||
private:
|
||||
InputStream& input;
|
||||
uint8 buffer [260];
|
||||
PixelARGB palette [256];
|
||||
bool dataBlockIsZero, fresh, finished;
|
||||
int currentBit, lastBit, lastByteIndex;
|
||||
int codeSize, setCodeSize;
|
||||
int maxCode, maxCodeSize;
|
||||
int firstcode, oldcode;
|
||||
int clearCode, endCode;
|
||||
enum { maxGifCode = 1 << 12 };
|
||||
int table [2] [maxGifCode];
|
||||
int stack [2 * maxGifCode];
|
||||
int* sp;
|
||||
|
||||
bool getSizeFromHeader (int& w, int& h)
|
||||
{
|
||||
// Add an extra byte for the zero terminator
|
||||
char b[7]{};
|
||||
|
||||
if (input.read (b, 6) == 6
|
||||
&& (strncmp ("GIF87a", b, 6) == 0
|
||||
|| strncmp ("GIF89a", b, 6) == 0))
|
||||
{
|
||||
if (input.read (b, 4) == 4)
|
||||
{
|
||||
w = (int) ByteOrder::littleEndianShort (b);
|
||||
h = (int) ByteOrder::littleEndianShort (b + 2);
|
||||
return w > 0 && h > 0;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool readPalette (const int numCols)
|
||||
{
|
||||
for (int i = 0; i < numCols; ++i)
|
||||
{
|
||||
uint8 rgb[4];
|
||||
input.read (rgb, 3);
|
||||
|
||||
palette[i].setARGB (0xff, rgb[0], rgb[1], rgb[2]);
|
||||
palette[i].premultiply();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int readDataBlock (uint8* const dest)
|
||||
{
|
||||
uint8 n;
|
||||
if (input.read (&n, 1) == 1)
|
||||
{
|
||||
dataBlockIsZero = (n == 0);
|
||||
|
||||
if (dataBlockIsZero || (input.read (dest, n) == n))
|
||||
return n;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int readExtension (int& transparent)
|
||||
{
|
||||
uint8 type;
|
||||
if (input.read (&type, 1) != 1)
|
||||
return false;
|
||||
|
||||
uint8 b [260];
|
||||
int n = 0;
|
||||
|
||||
if (type == 0xf9)
|
||||
{
|
||||
n = readDataBlock (b);
|
||||
if (n < 0)
|
||||
return 1;
|
||||
|
||||
if ((b[0] & 1) != 0)
|
||||
transparent = b[3];
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
n = readDataBlock (b);
|
||||
}
|
||||
while (n > 0);
|
||||
|
||||
return n >= 0;
|
||||
}
|
||||
|
||||
void clearTable()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < clearCode; ++i)
|
||||
{
|
||||
table[0][i] = 0;
|
||||
table[1][i] = i;
|
||||
}
|
||||
|
||||
for (; i < maxGifCode; ++i)
|
||||
{
|
||||
table[0][i] = 0;
|
||||
table[1][i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void initialise (const int inputCodeSize)
|
||||
{
|
||||
setCodeSize = inputCodeSize;
|
||||
codeSize = setCodeSize + 1;
|
||||
clearCode = 1 << setCodeSize;
|
||||
endCode = clearCode + 1;
|
||||
maxCodeSize = 2 * clearCode;
|
||||
maxCode = clearCode + 2;
|
||||
|
||||
getCode (0, true);
|
||||
|
||||
fresh = true;
|
||||
clearTable();
|
||||
sp = stack;
|
||||
}
|
||||
|
||||
int readLZWByte()
|
||||
{
|
||||
if (fresh)
|
||||
{
|
||||
fresh = false;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
firstcode = oldcode = getCode (codeSize, false);
|
||||
|
||||
if (firstcode != clearCode)
|
||||
return firstcode;
|
||||
}
|
||||
}
|
||||
|
||||
if (sp > stack)
|
||||
return *--sp;
|
||||
|
||||
int code;
|
||||
|
||||
while ((code = getCode (codeSize, false)) >= 0)
|
||||
{
|
||||
if (code == clearCode)
|
||||
{
|
||||
clearTable();
|
||||
codeSize = setCodeSize + 1;
|
||||
maxCodeSize = 2 * clearCode;
|
||||
maxCode = clearCode + 2;
|
||||
sp = stack;
|
||||
firstcode = oldcode = getCode (codeSize, false);
|
||||
return firstcode;
|
||||
}
|
||||
else if (code == endCode)
|
||||
{
|
||||
if (dataBlockIsZero)
|
||||
return -2;
|
||||
|
||||
uint8 buf [260];
|
||||
int n;
|
||||
|
||||
while ((n = readDataBlock (buf)) > 0)
|
||||
{}
|
||||
|
||||
if (n != 0)
|
||||
return -2;
|
||||
}
|
||||
|
||||
const int incode = code;
|
||||
|
||||
if (code >= maxCode)
|
||||
{
|
||||
*sp++ = firstcode;
|
||||
code = oldcode;
|
||||
}
|
||||
|
||||
while (code >= clearCode)
|
||||
{
|
||||
*sp++ = table[1][code];
|
||||
if (code == table[0][code])
|
||||
return -2;
|
||||
|
||||
code = table[0][code];
|
||||
}
|
||||
|
||||
*sp++ = firstcode = table[1][code];
|
||||
|
||||
if ((code = maxCode) < maxGifCode)
|
||||
{
|
||||
table[0][code] = oldcode;
|
||||
table[1][code] = firstcode;
|
||||
++maxCode;
|
||||
|
||||
if (maxCode >= maxCodeSize && maxCodeSize < maxGifCode)
|
||||
{
|
||||
maxCodeSize <<= 1;
|
||||
++codeSize;
|
||||
}
|
||||
}
|
||||
|
||||
oldcode = incode;
|
||||
|
||||
if (sp > stack)
|
||||
return *--sp;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int getCode (const int codeSize_, const bool shouldInitialise)
|
||||
{
|
||||
if (shouldInitialise)
|
||||
{
|
||||
currentBit = 0;
|
||||
lastBit = 0;
|
||||
finished = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((currentBit + codeSize_) >= lastBit)
|
||||
{
|
||||
if (finished)
|
||||
return -1;
|
||||
|
||||
buffer[0] = buffer [lastByteIndex - 2];
|
||||
buffer[1] = buffer [lastByteIndex - 1];
|
||||
|
||||
const int n = readDataBlock (buffer + 2);
|
||||
|
||||
if (n == 0)
|
||||
finished = true;
|
||||
|
||||
lastByteIndex = 2 + n;
|
||||
currentBit = (currentBit - lastBit) + 16;
|
||||
lastBit = (2 + n) * 8 ;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
int i = currentBit;
|
||||
|
||||
for (int j = 0; j < codeSize_; ++j)
|
||||
{
|
||||
result |= ((buffer[i >> 3] & (1 << (i & 7))) != 0) << j;
|
||||
++i;
|
||||
}
|
||||
|
||||
currentBit += codeSize_;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool readImage (const int interlace, const int transparent)
|
||||
{
|
||||
uint8 c;
|
||||
if (input.read (&c, 1) != 1)
|
||||
return false;
|
||||
|
||||
initialise (c);
|
||||
|
||||
if (transparent >= 0)
|
||||
palette [transparent].setARGB (0, 0, 0, 0);
|
||||
|
||||
int xpos = 0, ypos = 0, yStep = 8, pass = 0;
|
||||
|
||||
const Image::BitmapData destData (image, Image::BitmapData::writeOnly);
|
||||
uint8* p = destData.getPixelPointer (0, 0);
|
||||
const bool hasAlpha = image.hasAlphaChannel();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const int index = readLZWByte();
|
||||
if (index < 0)
|
||||
break;
|
||||
|
||||
if (hasAlpha)
|
||||
((PixelARGB*) p)->set (palette [index]);
|
||||
else
|
||||
((PixelRGB*) p)->set (palette [index]);
|
||||
|
||||
p += destData.pixelStride;
|
||||
|
||||
if (++xpos == destData.width)
|
||||
{
|
||||
xpos = 0;
|
||||
|
||||
if (interlace)
|
||||
{
|
||||
ypos += yStep;
|
||||
|
||||
while (ypos >= destData.height)
|
||||
{
|
||||
switch (++pass)
|
||||
{
|
||||
case 1: ypos = 4; yStep = 8; break;
|
||||
case 2: ypos = 2; yStep = 4; break;
|
||||
case 3: ypos = 1; yStep = 2; break;
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (++ypos >= destData.height)
|
||||
break;
|
||||
}
|
||||
|
||||
p = destData.getPixelPointer (xpos, ypos);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (GIFLoader)
|
||||
};
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
GIFImageFormat::GIFImageFormat() {}
|
||||
GIFImageFormat::~GIFImageFormat() {}
|
||||
|
||||
String GIFImageFormat::getFormatName() { return "GIF"; }
|
||||
bool GIFImageFormat::usesFileExtension (const File& f) { return f.hasFileExtension ("gif"); }
|
||||
|
||||
bool GIFImageFormat::canUnderstand (InputStream& in)
|
||||
{
|
||||
char header [4];
|
||||
|
||||
return (in.read (header, sizeof (header)) == (int) sizeof (header))
|
||||
&& header[0] == 'G'
|
||||
&& header[1] == 'I'
|
||||
&& header[2] == 'F';
|
||||
}
|
||||
|
||||
Image GIFImageFormat::decodeImage (InputStream& in)
|
||||
{
|
||||
#if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && JUCE_USE_COREIMAGE_LOADER
|
||||
return juce_loadWithCoreImage (in);
|
||||
#else
|
||||
const std::unique_ptr<GIFLoader> loader (new GIFLoader (in));
|
||||
return loader->image;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GIFImageFormat::writeImageToStream (const Image& /*sourceImage*/, OutputStream& /*destStream*/)
|
||||
{
|
||||
jassertfalse; // writing isn't implemented for GIFs!
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,451 +1,451 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4365 6240 6326 6386 6385 28182 28183 6387 6011 6001)
|
||||
|
||||
namespace jpeglibNamespace
|
||||
{
|
||||
#if JUCE_INCLUDE_JPEGLIB_CODE || ! defined (JUCE_INCLUDE_JPEGLIB_CODE)
|
||||
#if JUCE_MINGW
|
||||
typedef unsigned char boolean;
|
||||
#endif
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wconversion",
|
||||
"-Wdeprecated-register",
|
||||
"-Wdeprecated-declarations",
|
||||
"-Wsign-conversion",
|
||||
"-Wcast-align",
|
||||
"-Wswitch-enum",
|
||||
"-Wswitch-default",
|
||||
"-Wimplicit-fallthrough",
|
||||
"-Wzero-as-null-pointer-constant",
|
||||
"-Wshift-negative-value",
|
||||
"-Wcomma")
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#undef FAR
|
||||
#include "jpglib/jpeglib.h"
|
||||
|
||||
#include "jpglib/jcapimin.c"
|
||||
#include "jpglib/jcapistd.c"
|
||||
#include "jpglib/jccoefct.c"
|
||||
#include "jpglib/jccolor.c"
|
||||
#undef FIX
|
||||
#include "jpglib/jcdctmgr.c"
|
||||
#undef CONST_BITS
|
||||
#include "jpglib/jchuff.c"
|
||||
#undef emit_byte
|
||||
#include "jpglib/jcinit.c"
|
||||
#include "jpglib/jcmainct.c"
|
||||
#include "jpglib/jcmarker.c"
|
||||
#include "jpglib/jcmaster.c"
|
||||
#include "jpglib/jcomapi.c"
|
||||
#include "jpglib/jcparam.c"
|
||||
#include "jpglib/jcphuff.c"
|
||||
#include "jpglib/jcprepct.c"
|
||||
#include "jpglib/jcsample.c"
|
||||
#include "jpglib/jctrans.c"
|
||||
#include "jpglib/jdapistd.c"
|
||||
#include "jpglib/jdapimin.c"
|
||||
#include "jpglib/jdatasrc.c"
|
||||
#include "jpglib/jdcoefct.c"
|
||||
#undef FIX
|
||||
#include "jpglib/jdcolor.c"
|
||||
#undef FIX
|
||||
#include "jpglib/jddctmgr.c"
|
||||
#undef CONST_BITS
|
||||
#undef ASSIGN_STATE
|
||||
#include "jpglib/jdhuff.c"
|
||||
#include "jpglib/jdinput.c"
|
||||
#include "jpglib/jdmainct.c"
|
||||
#include "jpglib/jdmarker.c"
|
||||
#include "jpglib/jdmaster.c"
|
||||
#undef FIX
|
||||
#include "jpglib/jdmerge.c"
|
||||
#undef ASSIGN_STATE
|
||||
#include "jpglib/jdphuff.c"
|
||||
#include "jpglib/jdpostct.c"
|
||||
#undef FIX
|
||||
#include "jpglib/jdsample.c"
|
||||
#include "jpglib/jdtrans.c"
|
||||
#include "jpglib/jfdctflt.c"
|
||||
#include "jpglib/jfdctint.c"
|
||||
#undef CONST_BITS
|
||||
#undef MULTIPLY
|
||||
#undef FIX_0_541196100
|
||||
#include "jpglib/jfdctfst.c"
|
||||
#undef FIX_0_541196100
|
||||
#include "jpglib/jidctflt.c"
|
||||
#undef CONST_BITS
|
||||
#undef FIX_1_847759065
|
||||
#undef MULTIPLY
|
||||
#undef DEQUANTIZE
|
||||
#undef DESCALE
|
||||
#include "jpglib/jidctfst.c"
|
||||
#undef CONST_BITS
|
||||
#undef FIX_1_847759065
|
||||
#undef MULTIPLY
|
||||
#undef DEQUANTIZE
|
||||
#include "jpglib/jidctint.c"
|
||||
#include "jpglib/jidctred.c"
|
||||
#include "jpglib/jmemmgr.c"
|
||||
#include "jpglib/jmemnobs.c"
|
||||
#include "jpglib/jquant1.c"
|
||||
#include "jpglib/jquant2.c"
|
||||
#include "jpglib/jutils.c"
|
||||
#include "jpglib/transupp.c"
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
#else
|
||||
#define JPEG_INTERNALS
|
||||
#undef FAR
|
||||
#include <jpeglib.h>
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef max
|
||||
#undef min
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
|
||||
//==============================================================================
|
||||
namespace JPEGHelpers
|
||||
{
|
||||
using namespace jpeglibNamespace;
|
||||
|
||||
#if ! (JUCE_WINDOWS && (JUCE_MSVC || JUCE_CLANG))
|
||||
using jpeglibNamespace::boolean;
|
||||
#endif
|
||||
|
||||
static void fatalErrorHandler (j_common_ptr p) { *((bool*) (p->client_data)) = true; }
|
||||
static void silentErrorCallback1 (j_common_ptr) {}
|
||||
static void silentErrorCallback2 (j_common_ptr, int) {}
|
||||
static void silentErrorCallback3 (j_common_ptr, char*) {}
|
||||
|
||||
static void setupSilentErrorHandler (struct jpeg_error_mgr& err)
|
||||
{
|
||||
zerostruct (err);
|
||||
|
||||
err.error_exit = fatalErrorHandler;
|
||||
err.emit_message = silentErrorCallback2;
|
||||
err.output_message = silentErrorCallback1;
|
||||
err.format_message = silentErrorCallback3;
|
||||
err.reset_error_mgr = silentErrorCallback1;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if ! JUCE_USING_COREIMAGE_LOADER
|
||||
static void dummyCallback1 (j_decompress_ptr) {}
|
||||
|
||||
static void jpegSkip (j_decompress_ptr decompStruct, long num)
|
||||
{
|
||||
decompStruct->src->next_input_byte += num;
|
||||
|
||||
num = jmin (num, (long) decompStruct->src->bytes_in_buffer);
|
||||
decompStruct->src->bytes_in_buffer -= (size_t) num;
|
||||
}
|
||||
|
||||
static boolean jpegFill (j_decompress_ptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
const int jpegBufferSize = 512;
|
||||
|
||||
struct JuceJpegDest : public jpeg_destination_mgr
|
||||
{
|
||||
OutputStream* output;
|
||||
char* buffer;
|
||||
};
|
||||
|
||||
static void jpegWriteInit (j_compress_ptr) {}
|
||||
|
||||
static void jpegWriteTerminate (j_compress_ptr cinfo)
|
||||
{
|
||||
JuceJpegDest* const dest = static_cast<JuceJpegDest*> (cinfo->dest);
|
||||
|
||||
const size_t numToWrite = jpegBufferSize - dest->free_in_buffer;
|
||||
dest->output->write (dest->buffer, numToWrite);
|
||||
}
|
||||
|
||||
static boolean jpegWriteFlush (j_compress_ptr cinfo)
|
||||
{
|
||||
JuceJpegDest* const dest = static_cast<JuceJpegDest*> (cinfo->dest);
|
||||
|
||||
const int numToWrite = jpegBufferSize;
|
||||
|
||||
dest->next_output_byte = reinterpret_cast<JOCTET*> (dest->buffer);
|
||||
dest->free_in_buffer = jpegBufferSize;
|
||||
|
||||
return (boolean) dest->output->write (dest->buffer, (size_t) numToWrite);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
JPEGImageFormat::JPEGImageFormat()
|
||||
: quality (-1.0f)
|
||||
{
|
||||
}
|
||||
|
||||
JPEGImageFormat::~JPEGImageFormat() {}
|
||||
|
||||
void JPEGImageFormat::setQuality (const float newQuality)
|
||||
{
|
||||
quality = newQuality;
|
||||
}
|
||||
|
||||
String JPEGImageFormat::getFormatName() { return "JPEG"; }
|
||||
bool JPEGImageFormat::usesFileExtension (const File& f) { return f.hasFileExtension ("jpeg;jpg"); }
|
||||
|
||||
bool JPEGImageFormat::canUnderstand (InputStream& in)
|
||||
{
|
||||
const int bytesNeeded = 24;
|
||||
uint8 header [bytesNeeded];
|
||||
|
||||
if (in.read (header, bytesNeeded) == bytesNeeded
|
||||
&& header[0] == 0xff
|
||||
&& header[1] == 0xd8
|
||||
&& header[2] == 0xff)
|
||||
return true;
|
||||
|
||||
#if JUCE_USING_COREIMAGE_LOADER
|
||||
return header[20] == 'j'
|
||||
&& header[21] == 'p'
|
||||
&& header[22] == '2'
|
||||
&& header[23] == ' ';
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if JUCE_USING_COREIMAGE_LOADER
|
||||
Image juce_loadWithCoreImage (InputStream& input);
|
||||
#endif
|
||||
|
||||
Image JPEGImageFormat::decodeImage (InputStream& in)
|
||||
{
|
||||
#if JUCE_USING_COREIMAGE_LOADER
|
||||
return juce_loadWithCoreImage (in);
|
||||
#else
|
||||
using namespace jpeglibNamespace;
|
||||
using namespace JPEGHelpers;
|
||||
|
||||
MemoryOutputStream mb;
|
||||
mb << in;
|
||||
|
||||
Image image;
|
||||
|
||||
if (mb.getDataSize() > 16)
|
||||
{
|
||||
struct jpeg_decompress_struct jpegDecompStruct;
|
||||
|
||||
struct jpeg_error_mgr jerr;
|
||||
setupSilentErrorHandler (jerr);
|
||||
jpegDecompStruct.err = &jerr;
|
||||
|
||||
jpeg_create_decompress (&jpegDecompStruct);
|
||||
|
||||
jpegDecompStruct.src = (jpeg_source_mgr*)(jpegDecompStruct.mem->alloc_small)
|
||||
((j_common_ptr)(&jpegDecompStruct), JPOOL_PERMANENT, sizeof (jpeg_source_mgr));
|
||||
|
||||
bool hasFailed = false;
|
||||
jpegDecompStruct.client_data = &hasFailed;
|
||||
|
||||
jpegDecompStruct.src->init_source = dummyCallback1;
|
||||
jpegDecompStruct.src->fill_input_buffer = jpegFill;
|
||||
jpegDecompStruct.src->skip_input_data = jpegSkip;
|
||||
jpegDecompStruct.src->resync_to_restart = jpeg_resync_to_restart;
|
||||
jpegDecompStruct.src->term_source = dummyCallback1;
|
||||
|
||||
jpegDecompStruct.src->next_input_byte = static_cast<const unsigned char*> (mb.getData());
|
||||
jpegDecompStruct.src->bytes_in_buffer = mb.getDataSize();
|
||||
|
||||
jpeg_read_header (&jpegDecompStruct, TRUE);
|
||||
|
||||
if (! hasFailed)
|
||||
{
|
||||
jpeg_calc_output_dimensions (&jpegDecompStruct);
|
||||
|
||||
if (! hasFailed)
|
||||
{
|
||||
const int width = (int) jpegDecompStruct.output_width;
|
||||
const int height = (int) jpegDecompStruct.output_height;
|
||||
|
||||
jpegDecompStruct.out_color_space = JCS_RGB;
|
||||
|
||||
JSAMPARRAY buffer
|
||||
= (*jpegDecompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegDecompStruct,
|
||||
JPOOL_IMAGE,
|
||||
(JDIMENSION) width * 3, 1);
|
||||
|
||||
if (jpeg_start_decompress (&jpegDecompStruct) && ! hasFailed)
|
||||
{
|
||||
image = Image (Image::RGB, width, height, false);
|
||||
image.getProperties()->set ("originalImageHadAlpha", false);
|
||||
const bool hasAlphaChan = image.hasAlphaChannel(); // (the native image creator may not give back what we expect)
|
||||
|
||||
const Image::BitmapData destData (image, Image::BitmapData::writeOnly);
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
jpeg_read_scanlines (&jpegDecompStruct, buffer, 1);
|
||||
|
||||
if (hasFailed)
|
||||
break;
|
||||
|
||||
const uint8* src = *buffer;
|
||||
uint8* dest = destData.getLinePointer (y);
|
||||
|
||||
if (hasAlphaChan)
|
||||
{
|
||||
for (int i = width; --i >= 0;)
|
||||
{
|
||||
((PixelARGB*) dest)->setARGB (0xff, src[0], src[1], src[2]);
|
||||
((PixelARGB*) dest)->premultiply();
|
||||
dest += destData.pixelStride;
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = width; --i >= 0;)
|
||||
{
|
||||
((PixelRGB*) dest)->setARGB (0xff, src[0], src[1], src[2]);
|
||||
dest += destData.pixelStride;
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! hasFailed)
|
||||
jpeg_finish_decompress (&jpegDecompStruct);
|
||||
|
||||
in.setPosition (((char*) jpegDecompStruct.src->next_input_byte) - (char*) mb.getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jpeg_destroy_decompress (&jpegDecompStruct);
|
||||
}
|
||||
|
||||
return image;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool JPEGImageFormat::writeImageToStream (const Image& image, OutputStream& out)
|
||||
{
|
||||
using namespace jpeglibNamespace;
|
||||
using namespace JPEGHelpers;
|
||||
|
||||
jpeg_compress_struct jpegCompStruct;
|
||||
zerostruct (jpegCompStruct);
|
||||
jpeg_create_compress (&jpegCompStruct);
|
||||
|
||||
struct jpeg_error_mgr jerr;
|
||||
setupSilentErrorHandler (jerr);
|
||||
jpegCompStruct.err = &jerr;
|
||||
|
||||
JuceJpegDest dest;
|
||||
jpegCompStruct.dest = &dest;
|
||||
|
||||
dest.output = &out;
|
||||
HeapBlock<char> tempBuffer (jpegBufferSize);
|
||||
dest.buffer = tempBuffer;
|
||||
dest.next_output_byte = (JOCTET*) dest.buffer;
|
||||
dest.free_in_buffer = jpegBufferSize;
|
||||
dest.init_destination = jpegWriteInit;
|
||||
dest.empty_output_buffer = jpegWriteFlush;
|
||||
dest.term_destination = jpegWriteTerminate;
|
||||
|
||||
jpegCompStruct.image_width = (JDIMENSION) image.getWidth();
|
||||
jpegCompStruct.image_height = (JDIMENSION) image.getHeight();
|
||||
jpegCompStruct.input_components = 3;
|
||||
jpegCompStruct.in_color_space = JCS_RGB;
|
||||
jpegCompStruct.write_JFIF_header = 1;
|
||||
|
||||
jpegCompStruct.X_density = 72;
|
||||
jpegCompStruct.Y_density = 72;
|
||||
|
||||
jpeg_set_defaults (&jpegCompStruct);
|
||||
|
||||
jpegCompStruct.dct_method = JDCT_FLOAT;
|
||||
jpegCompStruct.optimize_coding = 1;
|
||||
|
||||
if (quality < 0.0f)
|
||||
quality = 0.85f;
|
||||
|
||||
jpeg_set_quality (&jpegCompStruct, jlimit (0, 100, roundToInt (quality * 100.0f)), TRUE);
|
||||
|
||||
jpeg_start_compress (&jpegCompStruct, TRUE);
|
||||
|
||||
const int strideBytes = (int) (jpegCompStruct.image_width * (unsigned int) jpegCompStruct.input_components);
|
||||
|
||||
JSAMPARRAY buffer = (*jpegCompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegCompStruct,
|
||||
JPOOL_IMAGE, (JDIMENSION) strideBytes, 1);
|
||||
|
||||
const Image::BitmapData srcData (image, Image::BitmapData::readOnly);
|
||||
|
||||
while (jpegCompStruct.next_scanline < jpegCompStruct.image_height)
|
||||
{
|
||||
uint8* dst = *buffer;
|
||||
|
||||
if (srcData.pixelFormat == Image::RGB)
|
||||
{
|
||||
const uint8* src = srcData.getLinePointer ((int) jpegCompStruct.next_scanline);
|
||||
|
||||
for (int i = srcData.width; --i >= 0;)
|
||||
{
|
||||
*dst++ = ((const PixelRGB*) src)->getRed();
|
||||
*dst++ = ((const PixelRGB*) src)->getGreen();
|
||||
*dst++ = ((const PixelRGB*) src)->getBlue();
|
||||
src += srcData.pixelStride;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int x = 0; x < srcData.width; ++x)
|
||||
{
|
||||
const Colour pixel (srcData.getPixelColour (x, (int) jpegCompStruct.next_scanline));
|
||||
*dst++ = pixel.getRed();
|
||||
*dst++ = pixel.getGreen();
|
||||
*dst++ = pixel.getBlue();
|
||||
}
|
||||
}
|
||||
|
||||
jpeg_write_scanlines (&jpegCompStruct, buffer, 1);
|
||||
}
|
||||
|
||||
jpeg_finish_compress (&jpegCompStruct);
|
||||
jpeg_destroy_compress (&jpegCompStruct);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4365 6240 6326 6386 6385 28182 28183 6387 6011 6001)
|
||||
|
||||
namespace jpeglibNamespace
|
||||
{
|
||||
#if JUCE_INCLUDE_JPEGLIB_CODE || ! defined (JUCE_INCLUDE_JPEGLIB_CODE)
|
||||
#if JUCE_MINGW
|
||||
typedef unsigned char boolean;
|
||||
#endif
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wconversion",
|
||||
"-Wdeprecated-register",
|
||||
"-Wdeprecated-declarations",
|
||||
"-Wsign-conversion",
|
||||
"-Wcast-align",
|
||||
"-Wswitch-enum",
|
||||
"-Wswitch-default",
|
||||
"-Wimplicit-fallthrough",
|
||||
"-Wzero-as-null-pointer-constant",
|
||||
"-Wshift-negative-value",
|
||||
"-Wcomma")
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#undef FAR
|
||||
#include "jpglib/jpeglib.h"
|
||||
|
||||
#include "jpglib/jcapimin.c"
|
||||
#include "jpglib/jcapistd.c"
|
||||
#include "jpglib/jccoefct.c"
|
||||
#include "jpglib/jccolor.c"
|
||||
#undef FIX
|
||||
#include "jpglib/jcdctmgr.c"
|
||||
#undef CONST_BITS
|
||||
#include "jpglib/jchuff.c"
|
||||
#undef emit_byte
|
||||
#include "jpglib/jcinit.c"
|
||||
#include "jpglib/jcmainct.c"
|
||||
#include "jpglib/jcmarker.c"
|
||||
#include "jpglib/jcmaster.c"
|
||||
#include "jpglib/jcomapi.c"
|
||||
#include "jpglib/jcparam.c"
|
||||
#include "jpglib/jcphuff.c"
|
||||
#include "jpglib/jcprepct.c"
|
||||
#include "jpglib/jcsample.c"
|
||||
#include "jpglib/jctrans.c"
|
||||
#include "jpglib/jdapistd.c"
|
||||
#include "jpglib/jdapimin.c"
|
||||
#include "jpglib/jdatasrc.c"
|
||||
#include "jpglib/jdcoefct.c"
|
||||
#undef FIX
|
||||
#include "jpglib/jdcolor.c"
|
||||
#undef FIX
|
||||
#include "jpglib/jddctmgr.c"
|
||||
#undef CONST_BITS
|
||||
#undef ASSIGN_STATE
|
||||
#include "jpglib/jdhuff.c"
|
||||
#include "jpglib/jdinput.c"
|
||||
#include "jpglib/jdmainct.c"
|
||||
#include "jpglib/jdmarker.c"
|
||||
#include "jpglib/jdmaster.c"
|
||||
#undef FIX
|
||||
#include "jpglib/jdmerge.c"
|
||||
#undef ASSIGN_STATE
|
||||
#include "jpglib/jdphuff.c"
|
||||
#include "jpglib/jdpostct.c"
|
||||
#undef FIX
|
||||
#include "jpglib/jdsample.c"
|
||||
#include "jpglib/jdtrans.c"
|
||||
#include "jpglib/jfdctflt.c"
|
||||
#include "jpglib/jfdctint.c"
|
||||
#undef CONST_BITS
|
||||
#undef MULTIPLY
|
||||
#undef FIX_0_541196100
|
||||
#include "jpglib/jfdctfst.c"
|
||||
#undef FIX_0_541196100
|
||||
#include "jpglib/jidctflt.c"
|
||||
#undef CONST_BITS
|
||||
#undef FIX_1_847759065
|
||||
#undef MULTIPLY
|
||||
#undef DEQUANTIZE
|
||||
#undef DESCALE
|
||||
#include "jpglib/jidctfst.c"
|
||||
#undef CONST_BITS
|
||||
#undef FIX_1_847759065
|
||||
#undef MULTIPLY
|
||||
#undef DEQUANTIZE
|
||||
#include "jpglib/jidctint.c"
|
||||
#include "jpglib/jidctred.c"
|
||||
#include "jpglib/jmemmgr.c"
|
||||
#include "jpglib/jmemnobs.c"
|
||||
#include "jpglib/jquant1.c"
|
||||
#include "jpglib/jquant2.c"
|
||||
#include "jpglib/jutils.c"
|
||||
#include "jpglib/transupp.c"
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
#else
|
||||
#define JPEG_INTERNALS
|
||||
#undef FAR
|
||||
#include <jpeglib.h>
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef max
|
||||
#undef min
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
|
||||
//==============================================================================
|
||||
namespace JPEGHelpers
|
||||
{
|
||||
using namespace jpeglibNamespace;
|
||||
|
||||
#if ! (JUCE_WINDOWS && (JUCE_MSVC || JUCE_CLANG))
|
||||
using jpeglibNamespace::boolean;
|
||||
#endif
|
||||
|
||||
static void fatalErrorHandler (j_common_ptr p) { *((bool*) (p->client_data)) = true; }
|
||||
static void silentErrorCallback1 (j_common_ptr) {}
|
||||
static void silentErrorCallback2 (j_common_ptr, int) {}
|
||||
static void silentErrorCallback3 (j_common_ptr, char*) {}
|
||||
|
||||
static void setupSilentErrorHandler (struct jpeg_error_mgr& err)
|
||||
{
|
||||
zerostruct (err);
|
||||
|
||||
err.error_exit = fatalErrorHandler;
|
||||
err.emit_message = silentErrorCallback2;
|
||||
err.output_message = silentErrorCallback1;
|
||||
err.format_message = silentErrorCallback3;
|
||||
err.reset_error_mgr = silentErrorCallback1;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if ! JUCE_USING_COREIMAGE_LOADER
|
||||
static void dummyCallback1 (j_decompress_ptr) {}
|
||||
|
||||
static void jpegSkip (j_decompress_ptr decompStruct, long num)
|
||||
{
|
||||
decompStruct->src->next_input_byte += num;
|
||||
|
||||
num = jmin (num, (long) decompStruct->src->bytes_in_buffer);
|
||||
decompStruct->src->bytes_in_buffer -= (size_t) num;
|
||||
}
|
||||
|
||||
static boolean jpegFill (j_decompress_ptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
const int jpegBufferSize = 512;
|
||||
|
||||
struct JuceJpegDest : public jpeg_destination_mgr
|
||||
{
|
||||
OutputStream* output;
|
||||
char* buffer;
|
||||
};
|
||||
|
||||
static void jpegWriteInit (j_compress_ptr) {}
|
||||
|
||||
static void jpegWriteTerminate (j_compress_ptr cinfo)
|
||||
{
|
||||
JuceJpegDest* const dest = static_cast<JuceJpegDest*> (cinfo->dest);
|
||||
|
||||
const size_t numToWrite = jpegBufferSize - dest->free_in_buffer;
|
||||
dest->output->write (dest->buffer, numToWrite);
|
||||
}
|
||||
|
||||
static boolean jpegWriteFlush (j_compress_ptr cinfo)
|
||||
{
|
||||
JuceJpegDest* const dest = static_cast<JuceJpegDest*> (cinfo->dest);
|
||||
|
||||
const int numToWrite = jpegBufferSize;
|
||||
|
||||
dest->next_output_byte = reinterpret_cast<JOCTET*> (dest->buffer);
|
||||
dest->free_in_buffer = jpegBufferSize;
|
||||
|
||||
return (boolean) dest->output->write (dest->buffer, (size_t) numToWrite);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
JPEGImageFormat::JPEGImageFormat()
|
||||
: quality (-1.0f)
|
||||
{
|
||||
}
|
||||
|
||||
JPEGImageFormat::~JPEGImageFormat() {}
|
||||
|
||||
void JPEGImageFormat::setQuality (const float newQuality)
|
||||
{
|
||||
quality = newQuality;
|
||||
}
|
||||
|
||||
String JPEGImageFormat::getFormatName() { return "JPEG"; }
|
||||
bool JPEGImageFormat::usesFileExtension (const File& f) { return f.hasFileExtension ("jpeg;jpg"); }
|
||||
|
||||
bool JPEGImageFormat::canUnderstand (InputStream& in)
|
||||
{
|
||||
const int bytesNeeded = 24;
|
||||
uint8 header [bytesNeeded];
|
||||
|
||||
if (in.read (header, bytesNeeded) == bytesNeeded
|
||||
&& header[0] == 0xff
|
||||
&& header[1] == 0xd8
|
||||
&& header[2] == 0xff)
|
||||
return true;
|
||||
|
||||
#if JUCE_USING_COREIMAGE_LOADER
|
||||
return header[20] == 'j'
|
||||
&& header[21] == 'p'
|
||||
&& header[22] == '2'
|
||||
&& header[23] == ' ';
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if JUCE_USING_COREIMAGE_LOADER
|
||||
Image juce_loadWithCoreImage (InputStream& input);
|
||||
#endif
|
||||
|
||||
Image JPEGImageFormat::decodeImage (InputStream& in)
|
||||
{
|
||||
#if JUCE_USING_COREIMAGE_LOADER
|
||||
return juce_loadWithCoreImage (in);
|
||||
#else
|
||||
using namespace jpeglibNamespace;
|
||||
using namespace JPEGHelpers;
|
||||
|
||||
MemoryOutputStream mb;
|
||||
mb << in;
|
||||
|
||||
Image image;
|
||||
|
||||
if (mb.getDataSize() > 16)
|
||||
{
|
||||
struct jpeg_decompress_struct jpegDecompStruct;
|
||||
|
||||
struct jpeg_error_mgr jerr;
|
||||
setupSilentErrorHandler (jerr);
|
||||
jpegDecompStruct.err = &jerr;
|
||||
|
||||
jpeg_create_decompress (&jpegDecompStruct);
|
||||
|
||||
jpegDecompStruct.src = (jpeg_source_mgr*)(jpegDecompStruct.mem->alloc_small)
|
||||
((j_common_ptr)(&jpegDecompStruct), JPOOL_PERMANENT, sizeof (jpeg_source_mgr));
|
||||
|
||||
bool hasFailed = false;
|
||||
jpegDecompStruct.client_data = &hasFailed;
|
||||
|
||||
jpegDecompStruct.src->init_source = dummyCallback1;
|
||||
jpegDecompStruct.src->fill_input_buffer = jpegFill;
|
||||
jpegDecompStruct.src->skip_input_data = jpegSkip;
|
||||
jpegDecompStruct.src->resync_to_restart = jpeg_resync_to_restart;
|
||||
jpegDecompStruct.src->term_source = dummyCallback1;
|
||||
|
||||
jpegDecompStruct.src->next_input_byte = static_cast<const unsigned char*> (mb.getData());
|
||||
jpegDecompStruct.src->bytes_in_buffer = mb.getDataSize();
|
||||
|
||||
jpeg_read_header (&jpegDecompStruct, TRUE);
|
||||
|
||||
if (! hasFailed)
|
||||
{
|
||||
jpeg_calc_output_dimensions (&jpegDecompStruct);
|
||||
|
||||
if (! hasFailed)
|
||||
{
|
||||
const int width = (int) jpegDecompStruct.output_width;
|
||||
const int height = (int) jpegDecompStruct.output_height;
|
||||
|
||||
jpegDecompStruct.out_color_space = JCS_RGB;
|
||||
|
||||
JSAMPARRAY buffer
|
||||
= (*jpegDecompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegDecompStruct,
|
||||
JPOOL_IMAGE,
|
||||
(JDIMENSION) width * 3, 1);
|
||||
|
||||
if (jpeg_start_decompress (&jpegDecompStruct) && ! hasFailed)
|
||||
{
|
||||
image = Image (Image::RGB, width, height, false);
|
||||
image.getProperties()->set ("originalImageHadAlpha", false);
|
||||
const bool hasAlphaChan = image.hasAlphaChannel(); // (the native image creator may not give back what we expect)
|
||||
|
||||
const Image::BitmapData destData (image, Image::BitmapData::writeOnly);
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
jpeg_read_scanlines (&jpegDecompStruct, buffer, 1);
|
||||
|
||||
if (hasFailed)
|
||||
break;
|
||||
|
||||
const uint8* src = *buffer;
|
||||
uint8* dest = destData.getLinePointer (y);
|
||||
|
||||
if (hasAlphaChan)
|
||||
{
|
||||
for (int i = width; --i >= 0;)
|
||||
{
|
||||
((PixelARGB*) dest)->setARGB (0xff, src[0], src[1], src[2]);
|
||||
((PixelARGB*) dest)->premultiply();
|
||||
dest += destData.pixelStride;
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = width; --i >= 0;)
|
||||
{
|
||||
((PixelRGB*) dest)->setARGB (0xff, src[0], src[1], src[2]);
|
||||
dest += destData.pixelStride;
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! hasFailed)
|
||||
jpeg_finish_decompress (&jpegDecompStruct);
|
||||
|
||||
in.setPosition (((char*) jpegDecompStruct.src->next_input_byte) - (char*) mb.getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jpeg_destroy_decompress (&jpegDecompStruct);
|
||||
}
|
||||
|
||||
return image;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool JPEGImageFormat::writeImageToStream (const Image& image, OutputStream& out)
|
||||
{
|
||||
using namespace jpeglibNamespace;
|
||||
using namespace JPEGHelpers;
|
||||
|
||||
jpeg_compress_struct jpegCompStruct;
|
||||
zerostruct (jpegCompStruct);
|
||||
jpeg_create_compress (&jpegCompStruct);
|
||||
|
||||
struct jpeg_error_mgr jerr;
|
||||
setupSilentErrorHandler (jerr);
|
||||
jpegCompStruct.err = &jerr;
|
||||
|
||||
JuceJpegDest dest;
|
||||
jpegCompStruct.dest = &dest;
|
||||
|
||||
dest.output = &out;
|
||||
HeapBlock<char> tempBuffer (jpegBufferSize);
|
||||
dest.buffer = tempBuffer;
|
||||
dest.next_output_byte = (JOCTET*) dest.buffer;
|
||||
dest.free_in_buffer = jpegBufferSize;
|
||||
dest.init_destination = jpegWriteInit;
|
||||
dest.empty_output_buffer = jpegWriteFlush;
|
||||
dest.term_destination = jpegWriteTerminate;
|
||||
|
||||
jpegCompStruct.image_width = (JDIMENSION) image.getWidth();
|
||||
jpegCompStruct.image_height = (JDIMENSION) image.getHeight();
|
||||
jpegCompStruct.input_components = 3;
|
||||
jpegCompStruct.in_color_space = JCS_RGB;
|
||||
jpegCompStruct.write_JFIF_header = 1;
|
||||
|
||||
jpegCompStruct.X_density = 72;
|
||||
jpegCompStruct.Y_density = 72;
|
||||
|
||||
jpeg_set_defaults (&jpegCompStruct);
|
||||
|
||||
jpegCompStruct.dct_method = JDCT_FLOAT;
|
||||
jpegCompStruct.optimize_coding = 1;
|
||||
|
||||
if (quality < 0.0f)
|
||||
quality = 0.85f;
|
||||
|
||||
jpeg_set_quality (&jpegCompStruct, jlimit (0, 100, roundToInt (quality * 100.0f)), TRUE);
|
||||
|
||||
jpeg_start_compress (&jpegCompStruct, TRUE);
|
||||
|
||||
const int strideBytes = (int) (jpegCompStruct.image_width * (unsigned int) jpegCompStruct.input_components);
|
||||
|
||||
JSAMPARRAY buffer = (*jpegCompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegCompStruct,
|
||||
JPOOL_IMAGE, (JDIMENSION) strideBytes, 1);
|
||||
|
||||
const Image::BitmapData srcData (image, Image::BitmapData::readOnly);
|
||||
|
||||
while (jpegCompStruct.next_scanline < jpegCompStruct.image_height)
|
||||
{
|
||||
uint8* dst = *buffer;
|
||||
|
||||
if (srcData.pixelFormat == Image::RGB)
|
||||
{
|
||||
const uint8* src = srcData.getLinePointer ((int) jpegCompStruct.next_scanline);
|
||||
|
||||
for (int i = srcData.width; --i >= 0;)
|
||||
{
|
||||
*dst++ = ((const PixelRGB*) src)->getRed();
|
||||
*dst++ = ((const PixelRGB*) src)->getGreen();
|
||||
*dst++ = ((const PixelRGB*) src)->getBlue();
|
||||
src += srcData.pixelStride;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int x = 0; x < srcData.width; ++x)
|
||||
{
|
||||
const Colour pixel (srcData.getPixelColour (x, (int) jpegCompStruct.next_scanline));
|
||||
*dst++ = pixel.getRed();
|
||||
*dst++ = pixel.getGreen();
|
||||
*dst++ = pixel.getBlue();
|
||||
}
|
||||
}
|
||||
|
||||
jpeg_write_scanlines (&jpegCompStruct, buffer, 1);
|
||||
}
|
||||
|
||||
jpeg_finish_compress (&jpegCompStruct);
|
||||
jpeg_destroy_compress (&jpegCompStruct);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user