Update bundled libjpeg-turbo to version 3.0.0
[ChangeLog][Third-Party Code] libjpeg-turbo was updated to version 3.0.0 Pick-to: 6.6 6.5 6.2 5.15 Change-Id: I960c4bfdef268eced93317ded814e2c84befa451 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>bb10
parent
b4a55e6db6
commit
3498baef76
|
|
@ -1,59 +1,103 @@
|
|||
set(JPEG16_SOURCES
|
||||
src/jcapistd.c
|
||||
src/jccolor.c
|
||||
src/jcdiffct.c
|
||||
src/jclossls.c
|
||||
src/jcmainct.c
|
||||
src/jcprepct.c
|
||||
src/jcsample.c
|
||||
src/jdapistd.c
|
||||
src/jdcolor.c
|
||||
src/jddiffct.c
|
||||
src/jdlossls.c
|
||||
src/jdmainct.c
|
||||
src/jdpostct.c
|
||||
src/jdsample.c
|
||||
src/jutils.c)
|
||||
|
||||
set(JPEG12_SOURCES
|
||||
${JPEG16_SOURCES}
|
||||
src/jccoefct.c
|
||||
src/jcdctmgr.c
|
||||
src/jdcoefct.c
|
||||
src/jddctmgr.c
|
||||
src/jdmerge.c
|
||||
src/jfdctfst.c
|
||||
src/jfdctint.c
|
||||
src/jidctflt.c
|
||||
src/jidctfst.c
|
||||
src/jidctint.c
|
||||
src/jidctred.c
|
||||
src/jquant1.c
|
||||
src/jquant2.c)
|
||||
|
||||
set(JPEG_SOURCES
|
||||
${JPEG12_SOURCES}
|
||||
src/jaricom.c
|
||||
src/jcapimin.c
|
||||
src/jcarith.c
|
||||
src/jchuff.c
|
||||
src/jcicc.c
|
||||
src/jcinit.c
|
||||
src/jclhuff.c
|
||||
src/jcmarker.c
|
||||
src/jcmaster.c
|
||||
src/jcomapi.c
|
||||
src/jcparam.c
|
||||
src/jcphuff.c
|
||||
src/jctrans.c
|
||||
src/jdapimin.c
|
||||
src/jdarith.c
|
||||
src/jdatadst.c
|
||||
src/jdatasrc.c
|
||||
src/jdhuff.c
|
||||
src/jdicc.c
|
||||
src/jdinput.c
|
||||
src/jdlhuff.c
|
||||
src/jdmarker.c
|
||||
src/jdmaster.c
|
||||
src/jdphuff.c
|
||||
src/jdtrans.c
|
||||
src/jerror.c
|
||||
src/jfdctflt.c
|
||||
src/jmemmgr.c
|
||||
src/jmemnobs.c)
|
||||
|
||||
qt_internal_add_3rdparty_library(BundledLibjpeg16bits
|
||||
STATIC
|
||||
SKIP_AUTOMOC
|
||||
SOURCES
|
||||
${JPEG16_SOURCES}
|
||||
DEFINES
|
||||
BITS_IN_JSAMPLE=16
|
||||
INCLUDE_DIRECTORIES
|
||||
src
|
||||
PUBLIC_INCLUDE_DIRECTORIES
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||
)
|
||||
|
||||
qt_internal_add_3rdparty_library(BundledLibjpeg12bits
|
||||
STATIC
|
||||
SKIP_AUTOMOC
|
||||
SOURCES
|
||||
${JPEG12_SOURCES}
|
||||
DEFINES
|
||||
BITS_IN_JSAMPLE=12
|
||||
INCLUDE_DIRECTORIES
|
||||
src
|
||||
PUBLIC_INCLUDE_DIRECTORIES
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||
)
|
||||
|
||||
qt_internal_add_3rdparty_library(BundledLibjpeg
|
||||
QMAKE_LIB_NAME libjpeg
|
||||
STATIC
|
||||
SKIP_AUTOMOC
|
||||
INSTALL
|
||||
SOURCES
|
||||
src/jaricom.c
|
||||
src/jcapimin.c
|
||||
src/jcapistd.c
|
||||
src/jcarith.c
|
||||
src/jccoefct.c
|
||||
src/jccolor.c
|
||||
src/jcdctmgr.c
|
||||
src/jchuff.c
|
||||
src/jcinit.c
|
||||
src/jcmainct.c
|
||||
src/jcmarker.c
|
||||
src/jcmaster.c
|
||||
src/jcomapi.c
|
||||
src/jcparam.c
|
||||
src/jcphuff.c
|
||||
src/jcprepct.c
|
||||
src/jcsample.c
|
||||
src/jctrans.c
|
||||
src/jdapimin.c
|
||||
src/jdapistd.c
|
||||
src/jdarith.c
|
||||
src/jdatadst.c
|
||||
src/jdatasrc.c
|
||||
src/jdcoefct.c
|
||||
src/jdcolor.c
|
||||
src/jddctmgr.c
|
||||
src/jdhuff.c
|
||||
src/jdinput.c
|
||||
src/jdmainct.c
|
||||
src/jdmarker.c
|
||||
src/jdmaster.c
|
||||
src/jdmerge.c
|
||||
src/jdphuff.c
|
||||
src/jdpostct.c
|
||||
src/jdsample.c
|
||||
src/jdtrans.c
|
||||
src/jerror.c
|
||||
src/jfdctflt.c
|
||||
src/jfdctfst.c
|
||||
src/jfdctint.c
|
||||
src/jidctflt.c
|
||||
src/jidctfst.c
|
||||
src/jidctint.c
|
||||
src/jidctred.c
|
||||
src/jmemmgr.c
|
||||
src/jmemnobs.c
|
||||
src/jquant1.c
|
||||
src/jquant2.c
|
||||
src/jsimd_none.c
|
||||
src/jutils.c
|
||||
${JPEG_SOURCES}
|
||||
$<TARGET_OBJECTS:BundledLibjpeg12bits>
|
||||
$<TARGET_OBJECTS:BundledLibjpeg16bits>
|
||||
INCLUDE_DIRECTORIES
|
||||
src
|
||||
PUBLIC_INCLUDE_DIRECTORIES
|
||||
|
|
@ -69,7 +113,11 @@ qt_internal_add_3rdparty_header_module(JpegPrivate
|
|||
)
|
||||
|
||||
qt_disable_warnings(BundledLibjpeg)
|
||||
qt_disable_warnings(BundledLibjpeg12bits)
|
||||
qt_disable_warnings(BundledLibjpeg16bits)
|
||||
qt_set_symbol_visibility_hidden(BundledLibjpeg)
|
||||
qt_set_symbol_visibility_hidden(BundledLibjpeg12bits)
|
||||
qt_set_symbol_visibility_hidden(BundledLibjpeg16bits)
|
||||
|
||||
qt_internal_extend_target(BundledLibjpeg CONDITION MSVC
|
||||
DEFINES
|
||||
|
|
|
|||
|
|
@ -9,4 +9,5 @@ Copyright (C) 2013-2014 MIPS Technologies, Inc.
|
|||
Copyright (C) 2009, 2012 Pierre Ossman for Cendio AB
|
||||
Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)
|
||||
Copyright (C) 1999-2006 MIYASAKA Masaru
|
||||
Copyright (C) 1999 Ken Murchison
|
||||
Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding
|
||||
|
|
|
|||
|
|
@ -57,12 +57,17 @@ FILES="
|
|||
jccolext.c
|
||||
jccolor.c
|
||||
jcdctmgr.c
|
||||
jcdiffct.c
|
||||
jchuff.c
|
||||
jchuff.h
|
||||
jcicc.c
|
||||
jcinit.c
|
||||
jclhuff.c
|
||||
jclossls.c
|
||||
jcmainct.c
|
||||
jcmarker.c
|
||||
jcmaster.c
|
||||
jcmaster.h
|
||||
jcomapi.c
|
||||
jcparam.c
|
||||
jcphuff.c
|
||||
|
|
@ -81,10 +86,15 @@ FILES="
|
|||
jdcolor.c
|
||||
jdct.h
|
||||
jddctmgr.c
|
||||
jddiffct.c
|
||||
jdhuff.c
|
||||
jdhuff.h
|
||||
jdicc.c
|
||||
jdphuff.c
|
||||
jdinput.c
|
||||
jdlhuff.c
|
||||
jdlossls.c
|
||||
jlossls.h
|
||||
jdmainct.c
|
||||
jdmainct.h
|
||||
jdmarker.c
|
||||
|
|
@ -108,7 +118,7 @@ FILES="
|
|||
jidctfst.c
|
||||
jidctint.c
|
||||
jinclude.h
|
||||
jpegcomp.h
|
||||
jpegapicomp.h
|
||||
jpegint.h
|
||||
jpeglib.h
|
||||
jmemmgr.c
|
||||
|
|
@ -118,8 +128,8 @@ FILES="
|
|||
jpeg_nbits_table.h
|
||||
jquant1.c
|
||||
jquant2.c
|
||||
jsamplecomp.h
|
||||
jsimd.h
|
||||
jsimd_none.c
|
||||
jsimddct.h
|
||||
jstdhuff.c
|
||||
jutils.c
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
"Description": "The Independent JPEG Group's JPEG software",
|
||||
"Homepage": "http://libjpeg-turbo.virtualgl.org/",
|
||||
"Version": "2.1.5",
|
||||
"DownloadLocation": "https://sourceforge.net/projects/libjpeg-turbo/files/2.1.5/libjpeg-turbo-2.1.5.tar.gz",
|
||||
"Version": "3.0.0",
|
||||
"DownloadLocation": "https://sourceforge.net/projects/libjpeg-turbo/files/3.0.0/libjpeg-turbo-3.0.0.tar.gz",
|
||||
|
||||
"License": "Independent JPEG Group License and BSD 3-Clause \"New\" or \"Revised\" License and zlib License",
|
||||
"LicenseId": "IJG AND BSD-3-Clause AND Zlib",
|
||||
|
|
|
|||
|
|
@ -1,3 +1,223 @@
|
|||
3.0.0
|
||||
=====
|
||||
|
||||
### Significant changes relative to 3.0 beta2:
|
||||
|
||||
1. The TurboJPEG API now supports 4:4:1 (transposed 4:1:1) chrominance
|
||||
subsampling, which allows losslessly transposed or rotated 4:1:1 JPEG images to
|
||||
be losslessly cropped, partially decompressed, or decompressed to planar YUV
|
||||
images.
|
||||
|
||||
2. Fixed various segfaults and buffer overruns (CVE-2023-2804) that occurred
|
||||
when attempting to decompress various specially-crafted malformed
|
||||
12-bit-per-component and 16-bit-per-component lossless JPEG images using color
|
||||
quantization or merged chroma upsampling/color conversion. The underlying
|
||||
cause of these issues was that the color quantization and merged chroma
|
||||
upsampling/color conversion algorithms were not designed with lossless
|
||||
decompression in mind. Since libjpeg-turbo explicitly does not support color
|
||||
conversion when compressing or decompressing lossless JPEG images, merged
|
||||
chroma upsampling/color conversion never should have been enabled for such
|
||||
images. Color quantization is a legacy feature that serves little or no
|
||||
purpose with lossless JPEG images, so it is also now disabled when
|
||||
decompressing such images. (As a result, djpeg can no longer decompress a
|
||||
lossless JPEG image into a GIF image.)
|
||||
|
||||
3. Fixed an oversight in 1.4 beta1[8] that caused various segfaults and buffer
|
||||
overruns when attempting to decompress various specially-crafted malformed
|
||||
12-bit-per-component JPEG images using djpeg with both color quantization and
|
||||
RGB565 color conversion enabled.
|
||||
|
||||
4. Fixed an issue whereby `jpeg_crop_scanline()` sometimes miscalculated the
|
||||
downsampled width for components with 4x2 or 2x4 subsampling factors if
|
||||
decompression scaling was enabled. This caused the components to be upsampled
|
||||
incompletely, which caused the color converter to read from uninitialized
|
||||
memory. With 12-bit data precision, this caused a buffer overrun or underrun
|
||||
and subsequent segfault if the sample value read from uninitialized memory was
|
||||
outside of the valid sample range.
|
||||
|
||||
5. Fixed a long-standing issue whereby the `tj3Transform()` function, when used
|
||||
with the `TJXOP_TRANSPOSE`, `TJXOP_TRANSVERSE`, `TJXOP_ROT90`, or
|
||||
`TJXOP_ROT270` transform operation and without automatic JPEG destination
|
||||
buffer (re)allocation or lossless cropping, computed the worst-case transformed
|
||||
JPEG image size based on the source image dimensions rather than the
|
||||
transformed image dimensions. If a calling program allocated the JPEG
|
||||
destination buffer based on the transformed image dimensions, as the API
|
||||
documentation instructs, and attempted to transform a specially-crafted 4:2:2,
|
||||
4:4:0, 4:1:1, or 4:4:1 JPEG source image containing a large amount of metadata,
|
||||
the issue caused `tj3Transform()` to overflow the JPEG destination buffer
|
||||
rather than fail gracefully. The issue could be worked around by setting
|
||||
`TJXOPT_COPYNONE`. Note that, irrespective of this issue, `tj3Transform()`
|
||||
cannot reliably transform JPEG source images that contain a large amount of
|
||||
metadata unless automatic JPEG destination buffer (re)allocation is used or
|
||||
`TJXOPT_COPYNONE` is set.
|
||||
|
||||
6. Fixed a regression introduced by 3.0 beta2[6] that prevented the djpeg
|
||||
`-map` option from working when decompressing 12-bit-per-component lossy JPEG
|
||||
images.
|
||||
|
||||
7. Fixed an issue that caused the C Huffman encoder (which is not used by
|
||||
default on x86 and Arm CPUs) to read from uninitialized memory when attempting
|
||||
to transform a specially-crafted malformed arithmetic-coded JPEG source image
|
||||
into a baseline Huffman-coded JPEG destination image.
|
||||
|
||||
|
||||
2.1.91 (3.0 beta2)
|
||||
==================
|
||||
|
||||
### Significant changes relative to 2.1.5.1:
|
||||
|
||||
1. Significantly sped up the computation of optimal Huffman tables. This
|
||||
speeds up the compression of tiny images by as much as 2x and provides a
|
||||
noticeable speedup for images as large as 256x256 when using optimal Huffman
|
||||
tables.
|
||||
|
||||
2. All deprecated fields, constructors, and methods in the TurboJPEG Java API
|
||||
have been removed.
|
||||
|
||||
3. Arithmetic entropy coding is now supported with 12-bit-per-component JPEG
|
||||
images.
|
||||
|
||||
4. Overhauled the TurboJPEG API to address long-standing limitations and to
|
||||
make the API more extensible and intuitive:
|
||||
|
||||
- All C function names are now prefixed with `tj3`, and all version
|
||||
suffixes have been removed from the function names. Future API overhauls will
|
||||
increment the prefix to `tj4`, etc., thus retaining backward API/ABI
|
||||
compatibility without versioning each individual function.
|
||||
- Stateless boolean flags have been replaced with stateful integer API
|
||||
parameters, the values of which persist between function calls. New
|
||||
functions/methods (`tj3Set()`/`TJCompressor.set()`/`TJDecompressor.set()` and
|
||||
`tj3Get()`/`TJCompressor.get()`/`TJDecompressor.get()`) can be used to set and
|
||||
query the value of a particular API parameter.
|
||||
- The JPEG quality and subsampling are now implemented using API
|
||||
parameters rather than stateless function arguments (C) or dedicated set/get
|
||||
methods (Java.)
|
||||
- `tj3DecompressHeader()` now stores all relevant information about the
|
||||
JPEG image, including the width, height, subsampling type, entropy coding
|
||||
algorithm, etc., in API parameters rather than returning that information
|
||||
through pointer arguments.
|
||||
- `TJFLAG_LIMITSCANS`/`TJ.FLAG_LIMITSCANS` has been reimplemented as an
|
||||
API parameter (`TJPARAM_SCANLIMIT`/`TJ.PARAM_SCANLIMIT`) that allows the number
|
||||
of scans to be specified.
|
||||
- Optimized baseline entropy coding (the computation of optimal Huffman
|
||||
tables, as opposed to using the default Huffman tables) can now be specified,
|
||||
using a new API parameter (`TJPARAM_OPTIMIZE`/`TJ.PARAM_OPTIMIZE`), a new
|
||||
transform option (`TJXOPT_OPTIMIZE`/`TJTransform.OPT_OPTIMIZE`), and a new
|
||||
TJBench option (`-optimize`.)
|
||||
- Arithmetic entropy coding can now be specified or queried, using a new
|
||||
API parameter (`TJPARAM_ARITHMETIC`/`TJ.PARAM_ARITHMETIC`), a new transform
|
||||
option (`TJXOPT_ARITHMETIC`/`TJTransform.OPT_ARITHMETIC`), and a new TJBench
|
||||
option (`-arithmetic`.)
|
||||
- The restart marker interval can now be specified, using new API
|
||||
parameters (`TJPARAM_RESTARTROWS`/`TJ.PARAM_RESTARTROWS` and
|
||||
`TJPARAM_RESTARTBLOCKS`/`TJ.PARAM_RESTARTBLOCKS`) and a new TJBench option
|
||||
(`-restart`.)
|
||||
- Pixel density can now be specified or queried, using new API parameters
|
||||
(`TJPARAM_XDENSITY`/`TJ.PARAM_XDENSITY`,
|
||||
`TJPARAM_YDENSITY`/`TJ.PARAM_YDENSITY`, and
|
||||
`TJPARAM_DENSITYUNITS`/`TJ.PARAM_DENSITYUNITS`.)
|
||||
- The accurate DCT/IDCT algorithms are now the default for both
|
||||
compression and decompression, since the "fast" algorithms are considered to be
|
||||
a legacy feature. (The "fast" algorithms do not pass the ISO compliance tests,
|
||||
and those algorithms are not any faster than the accurate algorithms on modern
|
||||
x86 CPUs.)
|
||||
- All C initialization functions have been combined into a single function
|
||||
(`tj3Init()`) that accepts an integer argument specifying the subsystems to
|
||||
initialize.
|
||||
- All C functions now use the `const` keyword for pointer arguments that
|
||||
point to unmodified buffers (and for both dimensions of pointer arguments that
|
||||
point to sets of unmodified buffers.)
|
||||
- All C functions now use `size_t` rather than `unsigned long` to
|
||||
represent buffer sizes, for compatibility with `malloc()` and to avoid
|
||||
disparities in the size of `unsigned long` between LP64 (Un*x) and LLP64
|
||||
(Windows) operating systems.
|
||||
- All C buffer size functions now return 0 if an error occurs, rather than
|
||||
trying to awkwardly return -1 in an unsigned data type (which could easily be
|
||||
misinterpreted as a very large value.)
|
||||
- Decompression scaling is now enabled explicitly, using a new
|
||||
function/method (`tj3SetScalingFactor()`/`TJDecompressor.setScalingFactor()`),
|
||||
rather than implicitly using awkward "desired width"/"desired height"
|
||||
arguments.
|
||||
- Partial image decompression has been implemented, using a new
|
||||
function/method (`tj3SetCroppingRegion()`/`TJDecompressor.setCroppingRegion()`)
|
||||
and a new TJBench option (`-crop`.)
|
||||
- The JPEG colorspace can now be specified explicitly when compressing,
|
||||
using a new API parameter (`TJPARAM_COLORSPACE`/`TJ.PARAM_COLORSPACE`.) This
|
||||
allows JPEG images with the RGB and CMYK colorspaces to be created.
|
||||
- TJBench no longer generates error/difference images, since identical
|
||||
functionality is already available in ImageMagick.
|
||||
- JPEG images with unknown subsampling configurations can now be
|
||||
fully decompressed into packed-pixel images or losslessly transformed (with the
|
||||
exception of lossless cropping.) They cannot currently be partially
|
||||
decompressed or decompressed into planar YUV images.
|
||||
- `tj3Destroy()` now silently accepts a NULL handle.
|
||||
- `tj3Alloc()` and `tj3Free()` now return/accept void pointers, as
|
||||
`malloc()` and `free()` do.
|
||||
- The C image I/O functions now accept a TurboJPEG instance handle, which
|
||||
is used to transmit/receive API parameter values and to receive error
|
||||
information.
|
||||
|
||||
5. Added support for 8-bit-per-component, 12-bit-per-component, and
|
||||
16-bit-per-component lossless JPEG images. A new libjpeg API function
|
||||
(`jpeg_enable_lossless()`), TurboJPEG API parameters
|
||||
(`TJPARAM_LOSSLESS`/`TJ.PARAM_LOSSLESS`,
|
||||
`TJPARAM_LOSSLESSPSV`/`TJ.PARAM_LOSSLESSPSV`, and
|
||||
`TJPARAM_LOSSLESSPT`/`TJ.PARAM_LOSSLESSPT`), and a cjpeg/TJBench option
|
||||
(`-lossless`) can be used to create a lossless JPEG image. (Decompression of
|
||||
lossless JPEG images is handled automatically.) Refer to
|
||||
[libjpeg.txt](libjpeg.txt), [usage.txt](usage.txt), and the TurboJPEG API
|
||||
documentation for more details.
|
||||
|
||||
6. Added support for 12-bit-per-component (lossy and lossless) and
|
||||
16-bit-per-component (lossless) JPEG images to the libjpeg and TurboJPEG APIs:
|
||||
|
||||
- The existing `data_precision` field in `jpeg_compress_struct` and
|
||||
`jpeg_decompress_struct` has been repurposed to enable the creation of
|
||||
12-bit-per-component and 16-bit-per-component JPEG images or to detect whether
|
||||
a 12-bit-per-component or 16-bit-per-component JPEG image is being
|
||||
decompressed.
|
||||
- New 12-bit-per-component and 16-bit-per-component versions of
|
||||
`jpeg_write_scanlines()` and `jpeg_read_scanlines()`, as well as new
|
||||
12-bit-per-component versions of `jpeg_write_raw_data()`,
|
||||
`jpeg_skip_scanlines()`, `jpeg_crop_scanline()`, and `jpeg_read_raw_data()`,
|
||||
provide interfaces for compressing from/decompressing to 12-bit-per-component
|
||||
and 16-bit-per-component packed-pixel and planar YUV image buffers.
|
||||
- New 12-bit-per-component and 16-bit-per-component compression,
|
||||
decompression, and image I/O functions/methods have been added to the TurboJPEG
|
||||
API, and a new API parameter (`TJPARAM_PRECISION`/`TJ.PARAM_PRECISION`) can be
|
||||
used to query the data precision of a JPEG image. (YUV functions are currently
|
||||
limited to 8-bit data precision but can be expanded to accommodate 12-bit data
|
||||
precision in the future, if such is deemed beneficial.)
|
||||
- A new cjpeg and TJBench command-line argument (`-precision`) can be used
|
||||
to create a 12-bit-per-component or 16-bit-per-component JPEG image.
|
||||
(Decompression and transformation of 12-bit-per-component and
|
||||
16-bit-per-component JPEG images is handled automatically.)
|
||||
|
||||
Refer to [libjpeg.txt](libjpeg.txt), [usage.txt](usage.txt), and the
|
||||
TurboJPEG API documentation for more details.
|
||||
|
||||
|
||||
2.1.5.1
|
||||
=======
|
||||
|
||||
### Significant changes relative to 2.1.5:
|
||||
|
||||
1. The SIMD dispatchers in libjpeg-turbo 2.1.4 and prior stored the list of
|
||||
supported SIMD instruction sets in a global variable, which caused an innocuous
|
||||
race condition whereby the variable could have been initialized multiple times
|
||||
if `jpeg_start_*compress()` was called simultaneously in multiple threads.
|
||||
libjpeg-turbo 2.1.5 included an undocumented attempt to fix this race condition
|
||||
by making the SIMD support variable thread-local. However, that caused another
|
||||
issue whereby, if `jpeg_start_*compress()` was called in one thread and
|
||||
`jpeg_read_*()` or `jpeg_write_*()` was called in a second thread, the SIMD
|
||||
support variable was never initialized in the second thread. On x86 systems,
|
||||
this led the second thread to incorrectly assume that AVX2 instructions were
|
||||
always available, and when it attempted to use those instructions on older x86
|
||||
CPUs that do not support them, an illegal instruction error occurred. The SIMD
|
||||
dispatchers now ensure that the SIMD support variable is initialized before
|
||||
dispatching based on its value.
|
||||
|
||||
|
||||
2.1.5
|
||||
=====
|
||||
|
||||
|
|
@ -1419,7 +1639,7 @@ features (such as the colorspace extensions), but in general, it performs no
|
|||
faster than libjpeg v6b.
|
||||
|
||||
14. Added ARM 64-bit SIMD acceleration for the YCC-to-RGB color conversion
|
||||
and IDCT algorithms (both are used during JPEG decompression.) For unknown
|
||||
and IDCT algorithms (both are used during JPEG decompression.) For
|
||||
reasons (probably related to clang), this code cannot currently be compiled for
|
||||
iOS.
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ User documentation:
|
|||
change.log Version-to-version change highlights.
|
||||
Programmer and internal documentation:
|
||||
libjpeg.txt How to use the JPEG library in your own programs.
|
||||
example.txt Sample code for calling the JPEG library.
|
||||
example.c Sample code for calling the JPEG library.
|
||||
structure.txt Overview of the JPEG library's internal structure.
|
||||
coderules.txt Coding style rules --- please read if you contribute code.
|
||||
|
||||
|
|
@ -68,17 +68,17 @@ other abrupt features may not compress well with JPEG, and a higher JPEG
|
|||
quality may have to be used to avoid visible compression artifacts with such
|
||||
images.
|
||||
|
||||
JPEG is lossy, meaning that the output pixels are not necessarily identical to
|
||||
the input pixels. However, on photographic content and other "smooth" images,
|
||||
very good compression ratios can be obtained with no visible compression
|
||||
artifacts, and extremely high compression ratios are possible if you are
|
||||
willing to sacrifice image quality (by reducing the "quality" setting in the
|
||||
compressor.)
|
||||
JPEG is normally lossy, meaning that the output pixels are not necessarily
|
||||
identical to the input pixels. However, on photographic content and other
|
||||
"smooth" images, very good compression ratios can be obtained with no visible
|
||||
compression artifacts, and extremely high compression ratios are possible if
|
||||
you are willing to sacrifice image quality (by reducing the "quality" setting
|
||||
in the compressor.)
|
||||
|
||||
This software implements JPEG baseline, extended-sequential, and progressive
|
||||
compression processes. Provision is made for supporting all variants of these
|
||||
processes, although some uncommon parameter settings aren't implemented yet.
|
||||
We have made no provision for supporting the hierarchical or lossless
|
||||
This software implements JPEG baseline, extended-sequential, progressive, and
|
||||
lossless compression processes. Provision is made for supporting all variants
|
||||
of these processes, although some uncommon parameter settings aren't
|
||||
implemented yet. We have made no provision for supporting the hierarchical
|
||||
processes defined in the standard.
|
||||
|
||||
We provide a set of library routines for reading and writing JPEG image files,
|
||||
|
|
@ -241,7 +241,7 @@ This software implements ITU T.81 | ISO/IEC 10918 with some extensions from
|
|||
ITU T.871 | ISO/IEC 10918-5 (JPEG File Interchange Format-- see REFERENCES).
|
||||
Informally, the term "JPEG image" or "JPEG file" most often refers to JFIF or
|
||||
a subset thereof, but there are other formats containing the name "JPEG" that
|
||||
are incompatible with the DCT-based JPEG standard or with JFIF (for instance,
|
||||
are incompatible with the original JPEG standard or with JFIF (for instance,
|
||||
JPEG 2000 and JPEG XR). This software therefore does not support these
|
||||
formats. Indeed, one of the original reasons for developing this free software
|
||||
was to help force convergence on a common, interoperable format standard for
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ early 2010, libjpeg-turbo spun off into an independent project, with the goal
|
|||
of making high-speed JPEG compression/decompression technology available to a
|
||||
broader range of users and developers.
|
||||
|
||||
More information about libjpeg-turbo can be found at
|
||||
<https://libjpeg-turbo.org>.
|
||||
|
||||
License
|
||||
=======
|
||||
|
|
@ -245,16 +247,6 @@ programs that need them, without breaking ABI compatibility for programs that
|
|||
don't, and it allows those functions to be provided in the "official"
|
||||
libjpeg-turbo binaries.
|
||||
|
||||
Those who are concerned about maintaining strict conformance with the libjpeg
|
||||
v6b or v7 API can pass an argument of `-DWITH_MEM_SRCDST=0` to `cmake` prior to
|
||||
building libjpeg-turbo. This will restore the pre-1.3 behavior, in which
|
||||
`jpeg_mem_src()` and `jpeg_mem_dest()` are only included when emulating the
|
||||
libjpeg v8 API/ABI.
|
||||
|
||||
On Un*x systems, including the in-memory source/destination managers changes
|
||||
the dynamic library version from 62.2.0 to 62.3.0 if using libjpeg v6b API/ABI
|
||||
emulation and from 7.2.0 to 7.3.0 if using libjpeg v7 API/ABI emulation.
|
||||
|
||||
Note that, on most Un*x systems, the dynamic linker will not look for a
|
||||
function in a library until that function is actually used. Thus, if a program
|
||||
is built against libjpeg-turbo 1.3+ and uses `jpeg_mem_src()` or
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jcmaster.h"
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -90,8 +91,18 @@ jpeg_CreateCompress(j_compress_ptr cinfo, int version, size_t structsize)
|
|||
|
||||
cinfo->input_gamma = 1.0; /* in case application forgets */
|
||||
|
||||
cinfo->data_precision = BITS_IN_JSAMPLE;
|
||||
|
||||
/* OK, I'm ready */
|
||||
cinfo->global_state = CSTATE_START;
|
||||
|
||||
/* The master struct is used to store extension parameters, so we allocate it
|
||||
* here.
|
||||
*/
|
||||
cinfo->master = (struct jpeg_comp_master *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,
|
||||
sizeof(my_comp_master));
|
||||
memset(cinfo->master, 0, sizeof(my_comp_master));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -183,8 +194,20 @@ jpeg_finish_compress(j_compress_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);
|
||||
if (cinfo->data_precision == 16) {
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
if (!(*cinfo->coef->compress_data_16) (cinfo, (J16SAMPIMAGE)NULL))
|
||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
||||
#else
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
#endif
|
||||
} else if (cinfo->data_precision == 12) {
|
||||
if (!(*cinfo->coef->compress_data_12) (cinfo, (J12SAMPIMAGE)NULL))
|
||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
||||
} else {
|
||||
if (!(*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE)NULL))
|
||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
||||
}
|
||||
}
|
||||
(*cinfo->master->finish_pass) (cinfo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* jcapistd.c
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -18,8 +20,11 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
|
||||
/*
|
||||
* Compression initialization.
|
||||
* Before calling this, all parameters and a data destination must be set up.
|
||||
|
|
@ -51,13 +56,15 @@ jpeg_start_compress(j_compress_ptr cinfo, boolean write_all_tables)
|
|||
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.
|
||||
/* 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);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Write some scanlines of data to the JPEG compressor.
|
||||
|
|
@ -67,7 +74,7 @@ jpeg_start_compress(j_compress_ptr cinfo, boolean write_all_tables)
|
|||
* 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
|
||||
* 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
|
||||
|
|
@ -75,11 +82,15 @@ jpeg_start_compress(j_compress_ptr cinfo, boolean write_all_tables)
|
|||
*/
|
||||
|
||||
GLOBAL(JDIMENSION)
|
||||
jpeg_write_scanlines(j_compress_ptr cinfo, JSAMPARRAY scanlines,
|
||||
JDIMENSION num_lines)
|
||||
_jpeg_write_scanlines(j_compress_ptr cinfo, _JSAMPARRAY scanlines,
|
||||
JDIMENSION num_lines)
|
||||
{
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
|
||||
JDIMENSION row_ctr, rows_left;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
if (cinfo->global_state != CSTATE_SCANNING)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
if (cinfo->next_scanline >= cinfo->image_height)
|
||||
|
|
@ -93,9 +104,9 @@ jpeg_write_scanlines(j_compress_ptr cinfo, JSAMPARRAY scanlines,
|
|||
}
|
||||
|
||||
/* Give master control module another chance if this is first call to
|
||||
* jpeg_write_scanlines. This lets output of the frame/scan headers be
|
||||
* _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.
|
||||
* jpeg_start_compress and _jpeg_write_scanlines.
|
||||
*/
|
||||
if (cinfo->master->call_pass_startup)
|
||||
(*cinfo->master->pass_startup) (cinfo);
|
||||
|
|
@ -106,23 +117,35 @@ jpeg_write_scanlines(j_compress_ptr cinfo, JSAMPARRAY scanlines,
|
|||
num_lines = rows_left;
|
||||
|
||||
row_ctr = 0;
|
||||
(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
|
||||
(*cinfo->main->_process_data) (cinfo, scanlines, &row_ctr, num_lines);
|
||||
cinfo->next_scanline += row_ctr;
|
||||
return row_ctr;
|
||||
#else
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
|
||||
/*
|
||||
* 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)
|
||||
_jpeg_write_raw_data(j_compress_ptr cinfo, _JSAMPIMAGE data,
|
||||
JDIMENSION num_lines)
|
||||
{
|
||||
JDIMENSION lines_per_iMCU_row;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
if (cinfo->master->lossless)
|
||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
||||
|
||||
if (cinfo->global_state != CSTATE_RAW_OK)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
if (cinfo->next_scanline >= cinfo->image_height) {
|
||||
|
|
@ -138,9 +161,9 @@ jpeg_write_raw_data(j_compress_ptr cinfo, JSAMPIMAGE data,
|
|||
}
|
||||
|
||||
/* 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
|
||||
* _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.
|
||||
* jpeg_start_compress and _jpeg_write_raw_data.
|
||||
*/
|
||||
if (cinfo->master->call_pass_startup)
|
||||
(*cinfo->master->pass_startup) (cinfo);
|
||||
|
|
@ -151,7 +174,7 @@ jpeg_write_raw_data(j_compress_ptr cinfo, JSAMPIMAGE data,
|
|||
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
||||
|
||||
/* Directly compress the row. */
|
||||
if (!(*cinfo->coef->compress_data) (cinfo, data)) {
|
||||
if (!(*cinfo->coef->_compress_data) (cinfo, data)) {
|
||||
/* If compressor did not consume the whole row, suspend processing. */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -160,3 +183,5 @@ jpeg_write_raw_data(j_compress_ptr cinfo, JSAMPIMAGE data,
|
|||
cinfo->next_scanline += lines_per_iMCU_row;
|
||||
return lines_per_iMCU_row;
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 */
|
||||
|
|
|
|||
|
|
@ -3,19 +3,20 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||
* It was modified by The libjpeg-turbo Project to include only code and
|
||||
* information relevant to libjpeg-turbo.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file contains the coefficient buffer controller for compression.
|
||||
* This controller is the top level of the JPEG compressor proper.
|
||||
* This controller is the top level of the lossy JPEG compressor proper.
|
||||
* The coefficient buffer lies between forward-DCT and entropy encoding steps.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
/* We use a full-image coefficient buffer when doing Huffman optimization,
|
||||
|
|
@ -58,11 +59,12 @@ typedef my_coef_controller *my_coef_ptr;
|
|||
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(boolean) compress_data(j_compress_ptr cinfo, JSAMPIMAGE input_buf);
|
||||
METHODDEF(boolean) compress_data(j_compress_ptr cinfo, _JSAMPIMAGE input_buf);
|
||||
#ifdef FULL_COEF_BUFFER_SUPPORTED
|
||||
METHODDEF(boolean) compress_first_pass(j_compress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf);
|
||||
METHODDEF(boolean) compress_output(j_compress_ptr cinfo, JSAMPIMAGE input_buf);
|
||||
_JSAMPIMAGE input_buf);
|
||||
METHODDEF(boolean) compress_output(j_compress_ptr cinfo,
|
||||
_JSAMPIMAGE input_buf);
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -106,18 +108,18 @@ start_pass_coef(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
|||
case JBUF_PASS_THRU:
|
||||
if (coef->whole_image[0] != NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
coef->pub.compress_data = compress_data;
|
||||
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;
|
||||
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;
|
||||
coef->pub._compress_data = compress_output;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
|
@ -138,7 +140,7 @@ start_pass_coef(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
|||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
compress_data(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
||||
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 */
|
||||
|
|
@ -172,10 +174,10 @@ compress_data(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
|||
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);
|
||||
(*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 *)coef->MCU_buffer[blkn + blockcnt],
|
||||
|
|
@ -242,7 +244,7 @@ compress_data(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
|||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
compress_first_pass(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
||||
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;
|
||||
|
|
@ -279,10 +281,10 @@ compress_first_pass(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
|||
*/
|
||||
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);
|
||||
(*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 */
|
||||
|
|
@ -338,7 +340,7 @@ compress_first_pass(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
|||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
compress_output(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
||||
compress_output(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 */
|
||||
|
|
@ -402,10 +404,13 @@ compress_output(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_c_coef_controller(j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
_jinit_c_coef_controller(j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_coef_ptr coef;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
coef = (my_coef_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_coef_controller));
|
||||
|
|
|
|||
|
|
@ -29,15 +29,16 @@
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
rgb_ycc_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
rgb_ycc_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows)
|
||||
{
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
|
||||
register int r, g, b;
|
||||
register JLONG *ctab = cconvert->rgb_ycc_tab;
|
||||
register JSAMPROW inptr;
|
||||
register JSAMPROW outptr0, outptr1, outptr2;
|
||||
register _JSAMPROW inptr;
|
||||
register _JSAMPROW outptr0, outptr1, outptr2;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
|
||||
|
|
@ -52,22 +53,25 @@ rgb_ycc_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
g = RANGE_LIMIT(inptr[RGB_GREEN]);
|
||||
b = RANGE_LIMIT(inptr[RGB_BLUE]);
|
||||
inptr += RGB_PIXELSIZE;
|
||||
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
|
||||
/* 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);
|
||||
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);
|
||||
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);
|
||||
outptr2[col] = (_JSAMPLE)((ctab[r + R_CR_OFF] + ctab[g + G_CR_OFF] +
|
||||
ctab[b + B_CR_OFF]) >> SCALEBITS);
|
||||
}
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -83,15 +87,16 @@ rgb_ycc_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
rgb_gray_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
rgb_gray_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows)
|
||||
{
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
|
||||
register int r, g, b;
|
||||
register JLONG *ctab = cconvert->rgb_ycc_tab;
|
||||
register JSAMPROW inptr;
|
||||
register JSAMPROW outptr;
|
||||
register _JSAMPROW inptr;
|
||||
register _JSAMPROW outptr;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
|
||||
|
|
@ -105,10 +110,13 @@ rgb_gray_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
b = RANGE_LIMIT(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);
|
||||
outptr[col] = (_JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
|
||||
ctab[b + B_Y_OFF]) >> SCALEBITS);
|
||||
}
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -119,12 +127,12 @@ rgb_gray_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
rgb_rgb_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
rgb_rgb_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows)
|
||||
{
|
||||
register JSAMPROW inptr;
|
||||
register JSAMPROW outptr0, outptr1, outptr2;
|
||||
register _JSAMPROW inptr;
|
||||
register _JSAMPROW outptr0, outptr1, outptr2;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,15 +17,20 @@
|
|||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsimd.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
|
||||
|
||||
/* Private subobject */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_color_converter pub; /* public fields */
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
/* Private state for RGB->YCC conversion */
|
||||
JLONG *rgb_ycc_tab; /* => table for RGB to YCbCr conversion */
|
||||
#endif
|
||||
} my_color_converter;
|
||||
|
||||
typedef my_color_converter *my_cconvert_ptr;
|
||||
|
|
@ -35,14 +40,14 @@ typedef my_color_converter *my_cconvert_ptr;
|
|||
|
||||
/*
|
||||
* 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.
|
||||
* 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
|
||||
* 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
|
||||
* 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.
|
||||
|
|
@ -53,16 +58,16 @@ typedef my_color_converter *my_cconvert_ptr;
|
|||
*
|
||||
* 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 8-bit samples 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
|
||||
* 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 ((JLONG)CENTERJSAMPLE << SCALEBITS)
|
||||
#define CBCR_OFFSET ((JLONG)_CENTERJSAMPLE << SCALEBITS)
|
||||
#define ONE_HALF ((JLONG)1 << (SCALEBITS - 1))
|
||||
#define FIX(x) ((JLONG)((x) * (1L << SCALEBITS) + 0.5))
|
||||
|
||||
|
|
@ -73,15 +78,15 @@ typedef my_color_converter *my_cconvert_ptr;
|
|||
*/
|
||||
|
||||
#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 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))
|
||||
#define G_CR_OFF (6 * (_MAXJSAMPLE + 1))
|
||||
#define B_CR_OFF (7 * (_MAXJSAMPLE + 1))
|
||||
#define TABLE_SIZE (8 * (_MAXJSAMPLE + 1))
|
||||
|
||||
/* 12-bit samples use a 16-bit data type, so it is possible to pass
|
||||
* out-of-range sample values (< 0 or > 4095) to jpeg_write_scanlines().
|
||||
|
|
@ -208,6 +213,7 @@ typedef my_color_converter *my_cconvert_ptr;
|
|||
METHODDEF(void)
|
||||
rgb_ycc_start(j_compress_ptr cinfo)
|
||||
{
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
|
||||
JLONG *rgb_ycc_tab;
|
||||
JLONG i;
|
||||
|
|
@ -217,15 +223,15 @@ rgb_ycc_start(j_compress_ptr cinfo)
|
|||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(TABLE_SIZE * sizeof(JLONG)));
|
||||
|
||||
for (i = 0; i <= MAXJSAMPLE; i++) {
|
||||
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.
|
||||
* 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
|
||||
|
|
@ -234,6 +240,9 @@ rgb_ycc_start(j_compress_ptr cinfo)
|
|||
rgb_ycc_tab[i + G_CR_OFF] = (-FIX(0.41869)) * i;
|
||||
rgb_ycc_tab[i + B_CR_OFF] = (-FIX(0.08131)) * i;
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -242,8 +251,8 @@ rgb_ycc_start(j_compress_ptr cinfo)
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
|
||||
rgb_ycc_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
switch (cinfo->in_color_space) {
|
||||
case JCS_EXT_RGB:
|
||||
|
|
@ -290,8 +299,8 @@ rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
|
||||
rgb_gray_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
switch (cinfo->in_color_space) {
|
||||
case JCS_EXT_RGB:
|
||||
|
|
@ -335,8 +344,8 @@ rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
rgb_rgb_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
|
||||
rgb_rgb_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
switch (cinfo->in_color_space) {
|
||||
case JCS_EXT_RGB:
|
||||
|
|
@ -384,14 +393,15 @@ rgb_rgb_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
cmyk_ycck_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
|
||||
cmyk_ycck_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
|
||||
register int r, g, b;
|
||||
register JLONG *ctab = cconvert->rgb_ycc_tab;
|
||||
register JSAMPROW inptr;
|
||||
register JSAMPROW outptr0, outptr1, outptr2, outptr3;
|
||||
register _JSAMPROW inptr;
|
||||
register _JSAMPROW outptr0, outptr1, outptr2, outptr3;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
|
||||
|
|
@ -403,28 +413,31 @@ cmyk_ycck_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
outptr3 = output_buf[3][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
r = MAXJSAMPLE - RANGE_LIMIT(inptr[0]);
|
||||
g = MAXJSAMPLE - RANGE_LIMIT(inptr[1]);
|
||||
b = MAXJSAMPLE - RANGE_LIMIT(inptr[2]);
|
||||
r = _MAXJSAMPLE - RANGE_LIMIT(inptr[0]);
|
||||
g = _MAXJSAMPLE - RANGE_LIMIT(inptr[1]);
|
||||
b = _MAXJSAMPLE - RANGE_LIMIT(inptr[2]);
|
||||
/* K passes through as-is */
|
||||
outptr3[col] = inptr[3];
|
||||
inptr += 4;
|
||||
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
|
||||
/* 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);
|
||||
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);
|
||||
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);
|
||||
outptr2[col] = (_JSAMPLE)((ctab[r + R_CR_OFF] + ctab[g + G_CR_OFF] +
|
||||
ctab[b + B_CR_OFF]) >> SCALEBITS);
|
||||
}
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -435,11 +448,11 @@ cmyk_ycck_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
grayscale_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
|
||||
grayscale_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
register JSAMPROW inptr;
|
||||
register JSAMPROW outptr;
|
||||
register _JSAMPROW inptr;
|
||||
register _JSAMPROW outptr;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
int instride = cinfo->input_components;
|
||||
|
|
@ -463,11 +476,11 @@ grayscale_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
null_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
null_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
register JSAMPROW inptr;
|
||||
register JSAMPROW outptr, outptr0, outptr1, outptr2, outptr3;
|
||||
register _JSAMPROW inptr;
|
||||
register _JSAMPROW outptr, outptr0, outptr1, outptr2, outptr3;
|
||||
register JDIMENSION col;
|
||||
register int ci;
|
||||
int nc = cinfo->num_components;
|
||||
|
|
@ -535,10 +548,13 @@ null_method(j_compress_ptr cinfo)
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_color_converter(j_compress_ptr cinfo)
|
||||
_jinit_color_converter(j_compress_ptr cinfo)
|
||||
{
|
||||
my_cconvert_ptr cconvert;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
cconvert = (my_cconvert_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_color_converter));
|
||||
|
|
@ -585,123 +601,116 @@ jinit_color_converter(j_compress_ptr cinfo)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Check num_components, set conversion method based on requested space */
|
||||
/* Check num_components, set conversion method based on requested space.
|
||||
* NOTE: We do not allow any lossy color conversion algorithms in lossless
|
||||
* mode.
|
||||
*/
|
||||
switch (cinfo->jpeg_color_space) {
|
||||
case JCS_GRAYSCALE:
|
||||
if (cinfo->master->lossless &&
|
||||
cinfo->in_color_space != cinfo->jpeg_color_space)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
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 ||
|
||||
cinfo->in_color_space == JCS_EXT_RGB ||
|
||||
cinfo->in_color_space == JCS_EXT_RGBX ||
|
||||
cinfo->in_color_space == JCS_EXT_BGR ||
|
||||
cinfo->in_color_space == JCS_EXT_BGRX ||
|
||||
cinfo->in_color_space == JCS_EXT_XBGR ||
|
||||
cinfo->in_color_space == JCS_EXT_XRGB ||
|
||||
cinfo->in_color_space == JCS_EXT_RGBA ||
|
||||
cinfo->in_color_space == JCS_EXT_BGRA ||
|
||||
cinfo->in_color_space == JCS_EXT_ABGR ||
|
||||
cinfo->in_color_space == JCS_EXT_ARGB) {
|
||||
cconvert->pub._color_convert = grayscale_convert;
|
||||
else if (IsExtRGB(cinfo->in_color_space)) {
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_rgb_gray())
|
||||
cconvert->pub.color_convert = jsimd_rgb_gray_convert;
|
||||
else {
|
||||
cconvert->pub._color_convert = jsimd_rgb_gray_convert;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
cconvert->pub.start_pass = rgb_ycc_start;
|
||||
cconvert->pub.color_convert = rgb_gray_convert;
|
||||
cconvert->pub._color_convert = rgb_gray_convert;
|
||||
}
|
||||
} else if (cinfo->in_color_space == JCS_YCbCr)
|
||||
cconvert->pub.color_convert = grayscale_convert;
|
||||
cconvert->pub._color_convert = grayscale_convert;
|
||||
else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_RGB:
|
||||
if (cinfo->master->lossless && !IsExtRGB(cinfo->in_color_space))
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
if (cinfo->num_components != 3)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (rgb_red[cinfo->in_color_space] == 0 &&
|
||||
rgb_green[cinfo->in_color_space] == 1 &&
|
||||
rgb_blue[cinfo->in_color_space] == 2 &&
|
||||
rgb_pixelsize[cinfo->in_color_space] == 3) {
|
||||
#if defined(__mips__)
|
||||
#if defined(WITH_SIMD) && defined(__mips__)
|
||||
if (jsimd_c_can_null_convert())
|
||||
cconvert->pub.color_convert = jsimd_c_null_convert;
|
||||
cconvert->pub._color_convert = jsimd_c_null_convert;
|
||||
else
|
||||
#endif
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
} else if (cinfo->in_color_space == JCS_RGB ||
|
||||
cinfo->in_color_space == JCS_EXT_RGB ||
|
||||
cinfo->in_color_space == JCS_EXT_RGBX ||
|
||||
cinfo->in_color_space == JCS_EXT_BGR ||
|
||||
cinfo->in_color_space == JCS_EXT_BGRX ||
|
||||
cinfo->in_color_space == JCS_EXT_XBGR ||
|
||||
cinfo->in_color_space == JCS_EXT_XRGB ||
|
||||
cinfo->in_color_space == JCS_EXT_RGBA ||
|
||||
cinfo->in_color_space == JCS_EXT_BGRA ||
|
||||
cinfo->in_color_space == JCS_EXT_ABGR ||
|
||||
cinfo->in_color_space == JCS_EXT_ARGB)
|
||||
cconvert->pub.color_convert = rgb_rgb_convert;
|
||||
cconvert->pub._color_convert = null_convert;
|
||||
} else if (IsExtRGB(cinfo->in_color_space))
|
||||
cconvert->pub._color_convert = rgb_rgb_convert;
|
||||
else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_YCbCr:
|
||||
if (cinfo->master->lossless &&
|
||||
cinfo->in_color_space != cinfo->jpeg_color_space)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
if (cinfo->num_components != 3)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_RGB ||
|
||||
cinfo->in_color_space == JCS_EXT_RGB ||
|
||||
cinfo->in_color_space == JCS_EXT_RGBX ||
|
||||
cinfo->in_color_space == JCS_EXT_BGR ||
|
||||
cinfo->in_color_space == JCS_EXT_BGRX ||
|
||||
cinfo->in_color_space == JCS_EXT_XBGR ||
|
||||
cinfo->in_color_space == JCS_EXT_XRGB ||
|
||||
cinfo->in_color_space == JCS_EXT_RGBA ||
|
||||
cinfo->in_color_space == JCS_EXT_BGRA ||
|
||||
cinfo->in_color_space == JCS_EXT_ABGR ||
|
||||
cinfo->in_color_space == JCS_EXT_ARGB) {
|
||||
if (IsExtRGB(cinfo->in_color_space)) {
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_rgb_ycc())
|
||||
cconvert->pub.color_convert = jsimd_rgb_ycc_convert;
|
||||
else {
|
||||
cconvert->pub.start_pass = rgb_ycc_start;
|
||||
cconvert->pub.color_convert = rgb_ycc_convert;
|
||||
}
|
||||
} else if (cinfo->in_color_space == JCS_YCbCr) {
|
||||
#if defined(__mips__)
|
||||
if (jsimd_c_can_null_convert())
|
||||
cconvert->pub.color_convert = jsimd_c_null_convert;
|
||||
cconvert->pub._color_convert = jsimd_rgb_ycc_convert;
|
||||
else
|
||||
#endif
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
{
|
||||
cconvert->pub.start_pass = rgb_ycc_start;
|
||||
cconvert->pub._color_convert = rgb_ycc_convert;
|
||||
}
|
||||
} else if (cinfo->in_color_space == JCS_YCbCr) {
|
||||
#if defined(WITH_SIMD) && defined(__mips__)
|
||||
if (jsimd_c_can_null_convert())
|
||||
cconvert->pub._color_convert = jsimd_c_null_convert;
|
||||
else
|
||||
#endif
|
||||
cconvert->pub._color_convert = null_convert;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
if (cinfo->master->lossless &&
|
||||
cinfo->in_color_space != cinfo->jpeg_color_space)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
if (cinfo->num_components != 4)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_CMYK) {
|
||||
#if defined(__mips__)
|
||||
#if defined(WITH_SIMD) && defined(__mips__)
|
||||
if (jsimd_c_can_null_convert())
|
||||
cconvert->pub.color_convert = jsimd_c_null_convert;
|
||||
cconvert->pub._color_convert = jsimd_c_null_convert;
|
||||
else
|
||||
#endif
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
cconvert->pub._color_convert = null_convert;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_YCCK:
|
||||
if (cinfo->master->lossless &&
|
||||
cinfo->in_color_space != cinfo->jpeg_color_space)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
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;
|
||||
cconvert->pub._color_convert = cmyk_ycck_convert;
|
||||
} else if (cinfo->in_color_space == JCS_YCCK) {
|
||||
#if defined(__mips__)
|
||||
#if defined(WITH_SIMD) && defined(__mips__)
|
||||
if (jsimd_c_can_null_convert())
|
||||
cconvert->pub.color_convert = jsimd_c_null_convert;
|
||||
cconvert->pub._color_convert = jsimd_c_null_convert;
|
||||
else
|
||||
#endif
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
cconvert->pub._color_convert = null_convert;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
|
@ -710,12 +719,14 @@ jinit_color_converter(j_compress_ptr cinfo)
|
|||
if (cinfo->jpeg_color_space != cinfo->in_color_space ||
|
||||
cinfo->num_components != cinfo->input_components)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
#if defined(__mips__)
|
||||
#if defined(WITH_SIMD) && defined(__mips__)
|
||||
if (jsimd_c_can_null_convert())
|
||||
cconvert->pub.color_convert = jsimd_c_null_convert;
|
||||
cconvert->pub._color_convert = jsimd_c_null_convert;
|
||||
else
|
||||
#endif
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
cconvert->pub._color_convert = null_convert;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2011, 2014-2015, D. R. Commander.
|
||||
* Copyright (C) 2011, 2014-2015, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -28,10 +28,10 @@
|
|||
typedef void (*forward_DCT_method_ptr) (DCTELEM *data);
|
||||
typedef void (*float_DCT_method_ptr) (FAST_FLOAT *data);
|
||||
|
||||
typedef void (*convsamp_method_ptr) (JSAMPARRAY sample_data,
|
||||
typedef void (*convsamp_method_ptr) (_JSAMPARRAY sample_data,
|
||||
JDIMENSION start_col,
|
||||
DCTELEM *workspace);
|
||||
typedef void (*float_convsamp_method_ptr) (JSAMPARRAY sample_data,
|
||||
typedef void (*float_convsamp_method_ptr) (_JSAMPARRAY sample_data,
|
||||
JDIMENSION start_col,
|
||||
FAST_FLOAT *workspace);
|
||||
|
||||
|
|
@ -265,9 +265,13 @@ start_pass_fdctmgr(j_compress_ptr cinfo)
|
|||
dtbl = fdct->divisors[qtblno];
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#ifdef WITH_SIMD
|
||||
if (!compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i]) &&
|
||||
fdct->quantize == jsimd_quantize)
|
||||
fdct->quantize = quantize;
|
||||
#else
|
||||
compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i]);
|
||||
#endif
|
||||
#else
|
||||
dtbl[i] = ((DCTELEM)qtbl->quantval[i]) << 3;
|
||||
#endif
|
||||
|
|
@ -305,12 +309,19 @@ start_pass_fdctmgr(j_compress_ptr cinfo)
|
|||
dtbl = fdct->divisors[qtblno];
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#ifdef WITH_SIMD
|
||||
if (!compute_reciprocal(
|
||||
DESCALE(MULTIPLY16V16((JLONG)qtbl->quantval[i],
|
||||
(JLONG)aanscales[i]),
|
||||
CONST_BITS - 3), &dtbl[i]) &&
|
||||
fdct->quantize == jsimd_quantize)
|
||||
fdct->quantize = quantize;
|
||||
#else
|
||||
compute_reciprocal(
|
||||
DESCALE(MULTIPLY16V16((JLONG)qtbl->quantval[i],
|
||||
(JLONG)aanscales[i]),
|
||||
CONST_BITS-3), &dtbl[i]);
|
||||
#endif
|
||||
#else
|
||||
dtbl[i] = (DCTELEM)
|
||||
DESCALE(MULTIPLY16V16((JLONG)qtbl->quantval[i],
|
||||
|
|
@ -370,10 +381,10 @@ start_pass_fdctmgr(j_compress_ptr cinfo)
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
convsamp(JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM *workspace)
|
||||
convsamp(_JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM *workspace)
|
||||
{
|
||||
register DCTELEM *workspaceptr;
|
||||
register JSAMPROW elemptr;
|
||||
register _JSAMPROW elemptr;
|
||||
register int elemr;
|
||||
|
||||
workspaceptr = workspace;
|
||||
|
|
@ -381,19 +392,19 @@ convsamp(JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM *workspace)
|
|||
elemptr = sample_data[elemr] + start_col;
|
||||
|
||||
#if DCTSIZE == 8 /* unroll the inner loop */
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
|
||||
#else
|
||||
{
|
||||
register int elemc;
|
||||
for (elemc = DCTSIZE; elemc > 0; elemc--)
|
||||
*workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -488,7 +499,7 @@ quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
|
|||
|
||||
METHODDEF(void)
|
||||
forward_DCT(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
_JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col, JDIMENSION num_blocks)
|
||||
/* This version is used for integer DCT implementations. */
|
||||
{
|
||||
|
|
@ -522,30 +533,30 @@ forward_DCT(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
|
||||
METHODDEF(void)
|
||||
convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
|
||||
convsamp_float(_JSAMPARRAY sample_data, JDIMENSION start_col,
|
||||
FAST_FLOAT *workspace)
|
||||
{
|
||||
register FAST_FLOAT *workspaceptr;
|
||||
register JSAMPROW elemptr;
|
||||
register _JSAMPROW elemptr;
|
||||
register 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)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
|
||||
#else
|
||||
{
|
||||
register int elemc;
|
||||
for (elemc = DCTSIZE; elemc > 0; elemc--)
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)((*elemptr++) - _CENTERJSAMPLE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -577,7 +588,7 @@ quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
|
|||
|
||||
METHODDEF(void)
|
||||
forward_DCT_float(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
_JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks)
|
||||
/* This version is used for floating-point DCT implementations. */
|
||||
|
|
@ -617,11 +628,14 @@ forward_DCT_float(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_forward_dct(j_compress_ptr cinfo)
|
||||
_jinit_forward_dct(j_compress_ptr cinfo)
|
||||
{
|
||||
my_fdct_ptr fdct;
|
||||
int i;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
fdct = (my_fdct_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_fdct_controller));
|
||||
|
|
@ -632,28 +646,34 @@ jinit_forward_dct(j_compress_ptr cinfo)
|
|||
switch (cinfo->dct_method) {
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
case JDCT_ISLOW:
|
||||
fdct->pub.forward_DCT = forward_DCT;
|
||||
fdct->pub._forward_DCT = forward_DCT;
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_fdct_islow())
|
||||
fdct->dct = jsimd_fdct_islow;
|
||||
else
|
||||
fdct->dct = jpeg_fdct_islow;
|
||||
#endif
|
||||
fdct->dct = _jpeg_fdct_islow;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
fdct->pub.forward_DCT = forward_DCT;
|
||||
fdct->pub._forward_DCT = forward_DCT;
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_fdct_ifast())
|
||||
fdct->dct = jsimd_fdct_ifast;
|
||||
else
|
||||
fdct->dct = jpeg_fdct_ifast;
|
||||
#endif
|
||||
fdct->dct = _jpeg_fdct_ifast;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
fdct->pub.forward_DCT = forward_DCT_float;
|
||||
fdct->pub._forward_DCT = forward_DCT_float;
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_fdct_float())
|
||||
fdct->float_dct = jsimd_fdct_float;
|
||||
else
|
||||
#endif
|
||||
fdct->float_dct = jpeg_fdct_float;
|
||||
break;
|
||||
#endif
|
||||
|
|
@ -671,25 +691,33 @@ jinit_forward_dct(j_compress_ptr cinfo)
|
|||
case JDCT_IFAST:
|
||||
#endif
|
||||
#if defined(DCT_ISLOW_SUPPORTED) || defined(DCT_IFAST_SUPPORTED)
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_convsamp())
|
||||
fdct->convsamp = jsimd_convsamp;
|
||||
else
|
||||
#endif
|
||||
fdct->convsamp = convsamp;
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_quantize())
|
||||
fdct->quantize = jsimd_quantize;
|
||||
else
|
||||
#endif
|
||||
fdct->quantize = quantize;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_convsamp_float())
|
||||
fdct->float_convsamp = jsimd_convsamp_float;
|
||||
else
|
||||
#endif
|
||||
fdct->float_convsamp = convsamp_float;
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_quantize_float())
|
||||
fdct->float_quantize = jsimd_quantize_float;
|
||||
else
|
||||
#endif
|
||||
fdct->float_quantize = quantize_float;
|
||||
break;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,411 @@
|
|||
/*
|
||||
* jcdiffct.c
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file contains the difference buffer controller for compression.
|
||||
* This controller is the top level of the lossless JPEG compressor proper.
|
||||
* The difference buffer lies between the prediction/differencing and entropy
|
||||
* encoding steps.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jlossls.h" /* Private declarations for lossless codec */
|
||||
|
||||
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
|
||||
/* We use a full-image sample buffer when doing Huffman optimization,
|
||||
* and also for writing multiple-scan JPEG files. In all cases, the
|
||||
* full-image buffer is filled during the first pass, and the scaling,
|
||||
* prediction and differencing steps are run during subsequent passes.
|
||||
*/
|
||||
#ifdef ENTROPY_OPT_SUPPORTED
|
||||
#define FULL_SAMP_BUFFER_SUPPORTED
|
||||
#else
|
||||
#ifdef C_MULTISCAN_FILES_SUPPORTED
|
||||
#define FULL_SAMP_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 */
|
||||
|
||||
_JSAMPROW cur_row[MAX_COMPONENTS]; /* row of point-transformed samples */
|
||||
_JSAMPROW prev_row[MAX_COMPONENTS]; /* previous row of Pt'd samples */
|
||||
JDIFFARRAY diff_buf[MAX_COMPONENTS]; /* iMCU row of differences */
|
||||
|
||||
/* In multi-pass modes, we need a virtual sample array for each component. */
|
||||
jvirt_sarray_ptr whole_image[MAX_COMPONENTS];
|
||||
} my_diff_controller;
|
||||
|
||||
typedef my_diff_controller *my_diff_ptr;
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(boolean) compress_data(j_compress_ptr cinfo, _JSAMPIMAGE input_buf);
|
||||
#ifdef FULL_SAMP_BUFFER_SUPPORTED
|
||||
METHODDEF(boolean) compress_first_pass(j_compress_ptr cinfo,
|
||||
_JSAMPIMAGE input_buf);
|
||||
METHODDEF(boolean) compress_output(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_diff_ptr diff = (my_diff_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) {
|
||||
diff->MCU_rows_per_iMCU_row = 1;
|
||||
} else {
|
||||
if (diff->iMCU_row_num < (cinfo->total_iMCU_rows-1))
|
||||
diff->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
|
||||
else
|
||||
diff->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
|
||||
}
|
||||
|
||||
diff->mcu_ctr = 0;
|
||||
diff->MCU_vert_offset = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_diff(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
||||
{
|
||||
my_diff_ptr diff = (my_diff_ptr)cinfo->coef;
|
||||
|
||||
/* Because it is hitching a ride on the jpeg_forward_dct struct,
|
||||
* start_pass_lossless() will be called at the start of the initial pass.
|
||||
* This ensures that it will be called at the start of the Huffman
|
||||
* optimization and output passes as well.
|
||||
*/
|
||||
if (pass_mode == JBUF_CRANK_DEST)
|
||||
(*cinfo->fdct->start_pass) (cinfo);
|
||||
|
||||
diff->iMCU_row_num = 0;
|
||||
start_iMCU_row(cinfo);
|
||||
|
||||
switch (pass_mode) {
|
||||
case JBUF_PASS_THRU:
|
||||
if (diff->whole_image[0] != NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
diff->pub._compress_data = compress_data;
|
||||
break;
|
||||
#ifdef FULL_SAMP_BUFFER_SUPPORTED
|
||||
case JBUF_SAVE_AND_PASS:
|
||||
if (diff->whole_image[0] == NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
diff->pub._compress_data = compress_first_pass;
|
||||
break;
|
||||
case JBUF_CRANK_DEST:
|
||||
if (diff->whole_image[0] == NULL)
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
diff->pub._compress_data = compress_output;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define SWAP_ROWS(rowa, rowb) { \
|
||||
_JSAMPROW temp = rowa; \
|
||||
rowa = rowb; rowb = temp; \
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 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_diff_ptr diff = (my_diff_ptr)cinfo->coef;
|
||||
lossless_comp_ptr losslessc = (lossless_comp_ptr)cinfo->fdct;
|
||||
JDIMENSION MCU_col_num; /* index of current MCU within row */
|
||||
JDIMENSION MCU_count; /* number of MCUs encoded */
|
||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
||||
int ci, compi, yoffset, samp_row, samp_rows, samps_across;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Loop to write as much as one whole iMCU row */
|
||||
for (yoffset = diff->MCU_vert_offset; yoffset < diff->MCU_rows_per_iMCU_row;
|
||||
yoffset++) {
|
||||
|
||||
MCU_col_num = diff->mcu_ctr;
|
||||
|
||||
/* Scale and predict each scanline of the MCU row separately.
|
||||
*
|
||||
* Note: We only do this if we are at the start of an MCU row, ie,
|
||||
* we don't want to reprocess a row suspended by the output.
|
||||
*/
|
||||
if (MCU_col_num == 0) {
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
compi = compptr->component_index;
|
||||
if (diff->iMCU_row_num < last_iMCU_row)
|
||||
samp_rows = compptr->v_samp_factor;
|
||||
else {
|
||||
/* NB: can't use last_row_height here, since may not be set! */
|
||||
samp_rows =
|
||||
(int)(compptr->height_in_blocks % compptr->v_samp_factor);
|
||||
if (samp_rows == 0) samp_rows = compptr->v_samp_factor;
|
||||
else {
|
||||
/* Fill dummy difference rows at the bottom edge with zeros, which
|
||||
* will encode to the smallest amount of data.
|
||||
*/
|
||||
for (samp_row = samp_rows; samp_row < compptr->v_samp_factor;
|
||||
samp_row++)
|
||||
memset(diff->diff_buf[compi][samp_row], 0,
|
||||
jround_up((long)compptr->width_in_blocks,
|
||||
(long)compptr->h_samp_factor) * sizeof(JDIFF));
|
||||
}
|
||||
}
|
||||
samps_across = compptr->width_in_blocks;
|
||||
|
||||
for (samp_row = 0; samp_row < samp_rows; samp_row++) {
|
||||
(*losslessc->scaler_scale) (cinfo,
|
||||
input_buf[compi][samp_row],
|
||||
diff->cur_row[compi],
|
||||
samps_across);
|
||||
(*losslessc->predict_difference[compi])
|
||||
(cinfo, compi, diff->cur_row[compi], diff->prev_row[compi],
|
||||
diff->diff_buf[compi][samp_row], samps_across);
|
||||
SWAP_ROWS(diff->cur_row[compi], diff->prev_row[compi]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Try to write the MCU row (or remaining portion of suspended MCU row). */
|
||||
MCU_count =
|
||||
(*cinfo->entropy->encode_mcus) (cinfo,
|
||||
diff->diff_buf, yoffset, MCU_col_num,
|
||||
cinfo->MCUs_per_row - MCU_col_num);
|
||||
if (MCU_count != cinfo->MCUs_per_row - MCU_col_num) {
|
||||
/* Suspension forced; update state counters and exit */
|
||||
diff->MCU_vert_offset = yoffset;
|
||||
diff->mcu_ctr += MCU_col_num;
|
||||
return FALSE;
|
||||
}
|
||||
/* Completed an MCU row, but perhaps not an iMCU row */
|
||||
diff->mcu_ctr = 0;
|
||||
}
|
||||
/* Completed the iMCU row, advance counters for next one */
|
||||
diff->iMCU_row_num++;
|
||||
start_iMCU_row(cinfo);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef FULL_SAMP_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 rows for each component in the image.
|
||||
* This amount of data is read from the source buffer and saved into the
|
||||
* virtual arrays.
|
||||
*
|
||||
* We must also emit the data to the compressor. 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 loaded into the virtual arrays in this pass. However, it may be that
|
||||
* only a subset of the components are emitted to the compressor 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_diff_ptr diff = (my_diff_ptr)cinfo->coef;
|
||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
||||
JDIMENSION samps_across;
|
||||
int ci, samp_row, samp_rows;
|
||||
_JSAMPARRAY buffer;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Align the virtual buffer for this component. */
|
||||
buffer = (_JSAMPARRAY)(*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr)cinfo, diff->whole_image[ci],
|
||||
diff->iMCU_row_num * compptr->v_samp_factor,
|
||||
(JDIMENSION)compptr->v_samp_factor, TRUE);
|
||||
|
||||
/* Count non-dummy sample rows in this iMCU row. */
|
||||
if (diff->iMCU_row_num < last_iMCU_row)
|
||||
samp_rows = compptr->v_samp_factor;
|
||||
else {
|
||||
/* NB: can't use last_row_height here, since may not be set! */
|
||||
samp_rows = (int)(compptr->height_in_blocks % compptr->v_samp_factor);
|
||||
if (samp_rows == 0) samp_rows = compptr->v_samp_factor;
|
||||
}
|
||||
samps_across = compptr->width_in_blocks;
|
||||
|
||||
/* Perform point transform scaling and prediction/differencing for all
|
||||
* non-dummy rows in this iMCU row. Each call on these functions
|
||||
* processes a complete row of samples.
|
||||
*/
|
||||
for (samp_row = 0; samp_row < samp_rows; samp_row++) {
|
||||
memcpy(buffer[samp_row], input_buf[ci][samp_row],
|
||||
samps_across * sizeof(_JSAMPLE));
|
||||
}
|
||||
}
|
||||
/* 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 compressor, 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 rows for each component in the scan.
|
||||
* The data is obtained from the virtual arrays and fed to the compressor.
|
||||
* 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 input_buf)
|
||||
{
|
||||
my_diff_ptr diff = (my_diff_ptr)cinfo->coef;
|
||||
int ci, compi;
|
||||
_JSAMPARRAY buffer[MAX_COMPS_IN_SCAN];
|
||||
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];
|
||||
compi = compptr->component_index;
|
||||
buffer[compi] = (_JSAMPARRAY)(*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr)cinfo, diff->whole_image[compi],
|
||||
diff->iMCU_row_num * compptr->v_samp_factor,
|
||||
(JDIMENSION)compptr->v_samp_factor, FALSE);
|
||||
}
|
||||
|
||||
return compress_data(cinfo, buffer);
|
||||
}
|
||||
|
||||
#endif /* FULL_SAMP_BUFFER_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize difference buffer controller.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
_jinit_c_diff_controller(j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_diff_ptr diff;
|
||||
int ci, row;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
diff = (my_diff_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_diff_controller));
|
||||
cinfo->coef = (struct jpeg_c_coef_controller *)diff;
|
||||
diff->pub.start_pass = start_pass_diff;
|
||||
|
||||
/* Create the prediction row buffers. */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
diff->cur_row[ci] = *(_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION)jround_up((long)compptr->width_in_blocks,
|
||||
(long)compptr->h_samp_factor),
|
||||
(JDIMENSION)1);
|
||||
diff->prev_row[ci] = *(_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION)jround_up((long)compptr->width_in_blocks,
|
||||
(long)compptr->h_samp_factor),
|
||||
(JDIMENSION)1);
|
||||
}
|
||||
|
||||
/* Create the difference buffer. */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
diff->diff_buf[ci] =
|
||||
ALLOC_DARRAY(JPOOL_IMAGE,
|
||||
(JDIMENSION)jround_up((long)compptr->width_in_blocks,
|
||||
(long)compptr->h_samp_factor),
|
||||
(JDIMENSION)compptr->v_samp_factor);
|
||||
/* Prefill difference rows with zeros. We do this because only actual
|
||||
* data is placed in the buffers during prediction/differencing, leaving
|
||||
* any dummy differences at the right edge as zeros, which will encode
|
||||
* to the smallest amount of data.
|
||||
*/
|
||||
for (row = 0; row < compptr->v_samp_factor; row++)
|
||||
memset(diff->diff_buf[ci][row], 0,
|
||||
jround_up((long)compptr->width_in_blocks,
|
||||
(long)compptr->h_samp_factor) * sizeof(JDIFF));
|
||||
}
|
||||
|
||||
/* Create the sample buffer. */
|
||||
if (need_full_buffer) {
|
||||
#ifdef FULL_SAMP_BUFFER_SUPPORTED
|
||||
/* Allocate a full-image virtual array for each component, */
|
||||
/* padded to a multiple of samp_factor differences in each direction. */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
diff->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
|
||||
((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
|
||||
diff->whole_image[0] = NULL; /* flag for no virtual arrays */
|
||||
}
|
||||
|
||||
#endif /* C_LOSSLESS_SUPPORTED */
|
||||
|
|
@ -3,11 +3,14 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009-2011, 2014-2016, 2018-2022, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2014-2016, 2018-2023, D. R. Commander.
|
||||
* Copyright (C) 2015, Matthieu Darbois.
|
||||
* Copyright (C) 2018, Matthias Räncker.
|
||||
* Copyright (C) 2020, Arm Limited.
|
||||
* Copyright (C) 2022, Felix Hanau.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -26,7 +29,11 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#ifdef WITH_SIMD
|
||||
#include "jsimd.h"
|
||||
#else
|
||||
#include "jchuff.h" /* Declarations shared with jc*huff.c */
|
||||
#endif
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
|
|
@ -179,7 +186,9 @@ start_pass_huff(j_compress_ptr cinfo, boolean gather_statistics)
|
|||
entropy->pub.finish_pass = finish_pass_huff;
|
||||
}
|
||||
|
||||
#ifdef WITH_SIMD
|
||||
entropy->simd = jsimd_can_huff_encode_one_block();
|
||||
#endif
|
||||
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
|
|
@ -219,6 +228,7 @@ start_pass_huff(j_compress_ptr cinfo, boolean gather_statistics)
|
|||
}
|
||||
|
||||
/* Initialize bit buffer to empty */
|
||||
#ifdef WITH_SIMD
|
||||
if (entropy->simd) {
|
||||
entropy->saved.put_buffer.simd = 0;
|
||||
#if defined(__aarch64__) && !defined(NEON_INTRINSICS)
|
||||
|
|
@ -226,7 +236,9 @@ start_pass_huff(j_compress_ptr cinfo, boolean gather_statistics)
|
|||
#else
|
||||
entropy->saved.free_bits = SIMD_BIT_BUF_SIZE;
|
||||
#endif
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
entropy->saved.put_buffer.c = 0;
|
||||
entropy->saved.free_bits = BIT_BUF_SIZE;
|
||||
}
|
||||
|
|
@ -241,7 +253,7 @@ start_pass_huff(j_compress_ptr cinfo, boolean gather_statistics)
|
|||
* Compute the derived values for a Huffman table.
|
||||
* This routine also performs some validation checks on the table.
|
||||
*
|
||||
* Note this is also used by jcphuff.c.
|
||||
* Note this is also used by jcphuff.c and jclhuff.c.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
|
|
@ -317,12 +329,12 @@ jpeg_make_c_derived_tbl(j_compress_ptr cinfo, boolean isDC, int tblno,
|
|||
memset(dtbl->ehufco, 0, sizeof(dtbl->ehufco));
|
||||
memset(dtbl->ehufsi, 0, sizeof(dtbl->ehufsi));
|
||||
|
||||
/* This is also a convenient place to check for out-of-range
|
||||
* and duplicated VAL entries. We allow 0..255 for AC symbols
|
||||
* but only 0..15 for DC. (We could constrain them further
|
||||
* based on data depth and mode, but this seems enough.)
|
||||
/* This is also a convenient place to check for out-of-range and duplicated
|
||||
* VAL entries. We allow 0..255 for AC symbols but only 0..15 for DC in
|
||||
* lossy mode and 0..16 for DC in lossless mode. (We could constrain them
|
||||
* further based on data depth and mode, but this seems enough.)
|
||||
*/
|
||||
maxsymbol = isDC ? 15 : 255;
|
||||
maxsymbol = isDC ? (cinfo->master->lossless ? 16 : 15) : 255;
|
||||
|
||||
for (p = 0; p < lastp; p++) {
|
||||
i = htbl->huffval[p];
|
||||
|
|
@ -541,6 +553,8 @@ flush_bits(working_state *state)
|
|||
}
|
||||
|
||||
|
||||
#ifdef WITH_SIMD
|
||||
|
||||
/* Encode a single block's worth of coefficients */
|
||||
|
||||
LOCAL(boolean)
|
||||
|
|
@ -560,6 +574,8 @@ encode_one_block_simd(working_state *state, JCOEFPTR block, int last_dc_val,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
LOCAL(boolean)
|
||||
encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val,
|
||||
c_derived_tbl *dctbl, c_derived_tbl *actbl)
|
||||
|
|
@ -568,6 +584,7 @@ encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val,
|
|||
bit_buf_type put_buffer;
|
||||
JOCTET _buffer[BUFSIZE], *buffer;
|
||||
int localbuf = 0;
|
||||
int max_coef_bits = state->cinfo->data_precision + 2;
|
||||
|
||||
free_bits = state->cur.free_bits;
|
||||
put_buffer = state->cur.put_buffer.c;
|
||||
|
|
@ -588,6 +605,11 @@ encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val,
|
|||
|
||||
/* Find the number of bits needed for the magnitude of the coefficient */
|
||||
nbits = JPEG_NBITS(nbits);
|
||||
/* Check for out-of-range coefficient values.
|
||||
* Since we're encoding a difference, the range limit is twice as much.
|
||||
*/
|
||||
if (nbits > max_coef_bits + 1)
|
||||
ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
|
||||
|
||||
/* Emit the Huffman-coded symbol for the number of bits.
|
||||
* Emit that number of bits of the value, if positive,
|
||||
|
|
@ -613,6 +635,9 @@ encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val,
|
|||
temp += nbits; \
|
||||
nbits ^= temp; \
|
||||
nbits = JPEG_NBITS_NONZERO(nbits); \
|
||||
/* Check for out-of-range coefficient values */ \
|
||||
if (nbits > max_coef_bits) \
|
||||
ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); \
|
||||
/* if run length > 15, must emit special run-length-16 codes (0xF0) */ \
|
||||
while (r >= 16 * 16) { \
|
||||
r -= 16 * 16; \
|
||||
|
|
@ -704,6 +729,7 @@ encode_mcu_huff(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
|||
}
|
||||
|
||||
/* Encode the MCU data blocks */
|
||||
#ifdef WITH_SIMD
|
||||
if (entropy->simd) {
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
ci = cinfo->MCU_membership[blkn];
|
||||
|
|
@ -716,7 +742,9 @@ encode_mcu_huff(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
|||
/* Update last_dc_val */
|
||||
state.cur.last_dc_val[ci] = MCU_data[blkn][0][0];
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
ci = cinfo->MCU_membership[blkn];
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
|
|
@ -800,6 +828,7 @@ htest_one_block(j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
|
|||
register int temp;
|
||||
register int nbits;
|
||||
register int k, r;
|
||||
int max_coef_bits = cinfo->data_precision + 2;
|
||||
|
||||
/* Encode the DC coefficient difference per section F.1.2.1 */
|
||||
|
||||
|
|
@ -816,7 +845,7 @@ htest_one_block(j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
|
|||
/* Check for out-of-range coefficient values.
|
||||
* Since we're encoding a difference, the range limit is twice as much.
|
||||
*/
|
||||
if (nbits > MAX_COEF_BITS + 1)
|
||||
if (nbits > max_coef_bits + 1)
|
||||
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
|
||||
|
||||
/* Count the Huffman symbol for the number of bits */
|
||||
|
|
@ -845,7 +874,7 @@ htest_one_block(j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
|
|||
while ((temp >>= 1))
|
||||
nbits++;
|
||||
/* Check for out-of-range coefficient values */
|
||||
if (nbits > MAX_COEF_BITS)
|
||||
if (nbits > max_coef_bits)
|
||||
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
|
||||
|
||||
/* Count Huffman symbol for run length / number of bits */
|
||||
|
|
@ -900,7 +929,7 @@ encode_mcu_gather(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
|||
|
||||
/*
|
||||
* Generate the best Huffman code table for the given counts, fill htbl.
|
||||
* Note this is also used by jcphuff.c.
|
||||
* Note this is also used by jcphuff.c and jclhuff.c.
|
||||
*
|
||||
* The JPEG standard requires that no symbol be assigned a codeword of all
|
||||
* one bits (so that padding bits added at the end of a compressed segment
|
||||
|
|
@ -932,11 +961,15 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
|
|||
{
|
||||
#define MAX_CLEN 32 /* assumed maximum initial code length */
|
||||
UINT8 bits[MAX_CLEN + 1]; /* bits[k] = # of symbols with code length k */
|
||||
int bit_pos[MAX_CLEN + 1]; /* # of symbols with smaller code length */
|
||||
int codesize[257]; /* codesize[k] = code length of symbol k */
|
||||
int nz_index[257]; /* index of nonzero symbol in the original freq
|
||||
array */
|
||||
int others[257]; /* next symbol in current branch of tree */
|
||||
int c1, c2;
|
||||
int p, i, j;
|
||||
long v;
|
||||
int num_nz_symbols;
|
||||
long v, v2;
|
||||
|
||||
/* This algorithm is explained in section K.2 of the JPEG standard */
|
||||
|
||||
|
|
@ -951,28 +984,41 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
|
|||
* will be placed last in the largest codeword category.
|
||||
*/
|
||||
|
||||
/* Group nonzero frequencies together so we can more easily find the
|
||||
* smallest.
|
||||
*/
|
||||
num_nz_symbols = 0;
|
||||
for (i = 0; i < 257; i++) {
|
||||
if (freq[i]) {
|
||||
nz_index[num_nz_symbols] = i;
|
||||
freq[num_nz_symbols] = freq[i];
|
||||
num_nz_symbols++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Huffman's basic algorithm to assign optimal code lengths to symbols */
|
||||
|
||||
for (;;) {
|
||||
/* Find the smallest nonzero frequency, set c1 = its symbol */
|
||||
/* In case of ties, take the larger symbol number */
|
||||
/* Find the two smallest nonzero frequencies; set c1, c2 = their symbols */
|
||||
/* In case of ties, take the larger symbol number. Since we have grouped
|
||||
* the nonzero symbols together, checking for zero symbols is not
|
||||
* necessary.
|
||||
*/
|
||||
c1 = -1;
|
||||
v = 1000000000L;
|
||||
for (i = 0; i <= 256; i++) {
|
||||
if (freq[i] && freq[i] <= v) {
|
||||
v = freq[i];
|
||||
c1 = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the next smallest nonzero frequency, set c2 = its symbol */
|
||||
/* In case of ties, take the larger symbol number */
|
||||
c2 = -1;
|
||||
v = 1000000000L;
|
||||
for (i = 0; i <= 256; i++) {
|
||||
if (freq[i] && freq[i] <= v && i != c1) {
|
||||
v = freq[i];
|
||||
c2 = i;
|
||||
v2 = 1000000000L;
|
||||
for (i = 0; i < num_nz_symbols; i++) {
|
||||
if (freq[i] <= v2) {
|
||||
if (freq[i] <= v) {
|
||||
c2 = c1;
|
||||
v2 = v;
|
||||
v = freq[i];
|
||||
c1 = i;
|
||||
} else {
|
||||
v2 = freq[i];
|
||||
c2 = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -982,7 +1028,10 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
|
|||
|
||||
/* Else merge the two counts/trees */
|
||||
freq[c1] += freq[c2];
|
||||
freq[c2] = 0;
|
||||
/* Set the frequency to a very high value instead of zero, so we don't have
|
||||
* to check for zero values.
|
||||
*/
|
||||
freq[c2] = 1000000001L;
|
||||
|
||||
/* Increment the codesize of everything in c1's tree branch */
|
||||
codesize[c1]++;
|
||||
|
|
@ -1002,15 +1051,24 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
|
|||
}
|
||||
|
||||
/* Now count the number of symbols of each code length */
|
||||
for (i = 0; i <= 256; i++) {
|
||||
if (codesize[i]) {
|
||||
/* The JPEG standard seems to think that this can't happen, */
|
||||
/* but I'm paranoid... */
|
||||
if (codesize[i] > MAX_CLEN)
|
||||
ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
|
||||
for (i = 0; i < num_nz_symbols; i++) {
|
||||
/* The JPEG standard seems to think that this can't happen, */
|
||||
/* but I'm paranoid... */
|
||||
if (codesize[i] > MAX_CLEN)
|
||||
ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
|
||||
|
||||
bits[codesize[i]]++;
|
||||
}
|
||||
bits[codesize[i]]++;
|
||||
}
|
||||
|
||||
/* Count the number of symbols with a length smaller than i bits, so we can
|
||||
* construct the symbol table more efficiently. Note that this includes the
|
||||
* pseudo-symbol 256, but since it is the last symbol, it will not affect the
|
||||
* table.
|
||||
*/
|
||||
p = 0;
|
||||
for (i = 1; i <= MAX_CLEN; i++) {
|
||||
bit_pos[i] = p;
|
||||
p += bits[i];
|
||||
}
|
||||
|
||||
/* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
|
||||
|
|
@ -1050,14 +1108,9 @@ jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
|
|||
* changes made above, but Rec. ITU-T T.81 | ISO/IEC 10918-1 seems to think
|
||||
* this works.
|
||||
*/
|
||||
p = 0;
|
||||
for (i = 1; i <= MAX_CLEN; i++) {
|
||||
for (j = 0; j <= 255; j++) {
|
||||
if (codesize[j] == i) {
|
||||
htbl->huffval[p] = (UINT8)j;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < num_nz_symbols - 1; i++) {
|
||||
htbl->huffval[bit_pos[codesize[i]]] = (UINT8)nz_index[i];
|
||||
bit_pos[codesize[i]]++;
|
||||
}
|
||||
|
||||
/* Set sent_table FALSE so updated table will be written to JPEG file. */
|
||||
|
|
|
|||
|
|
@ -19,12 +19,6 @@
|
|||
* Hence the magnitude should always fit in 10 or 14 bits respectively.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define MAX_COEF_BITS 10
|
||||
#else
|
||||
#define MAX_COEF_BITS 14
|
||||
#endif
|
||||
|
||||
/* The progressive Huffman encoder uses an unsigned 16-bit data type to store
|
||||
* absolute values of coefficients, because it is possible to inject a
|
||||
* coefficient value of -32768 into the encoder by attempting to transform a
|
||||
|
|
|
|||
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* jcicc.c
|
||||
*
|
||||
* Copyright (C) 1997-1998, Thomas G. Lane, Todd Newman.
|
||||
* Copyright (C) 2017, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file provides code to write International Color Consortium (ICC) device
|
||||
* profiles embedded in JFIF JPEG image files. The ICC has defined a standard
|
||||
* for including such data in JPEG "APP2" markers. The code given here does
|
||||
* not know anything about the internal structure of the ICC profile data; it
|
||||
* just knows how to embed the profile data in a JPEG file while writing it.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jerror.h"
|
||||
|
||||
|
||||
/*
|
||||
* Since an ICC profile can be larger than the maximum size of a JPEG marker
|
||||
* (64K), we need provisions to split it into multiple markers. The format
|
||||
* defined by the ICC specifies one or more APP2 markers containing the
|
||||
* following data:
|
||||
* Identifying string ASCII "ICC_PROFILE\0" (12 bytes)
|
||||
* Marker sequence number 1 for first APP2, 2 for next, etc (1 byte)
|
||||
* Number of markers Total number of APP2's used (1 byte)
|
||||
* Profile data (remainder of APP2 data)
|
||||
* Decoders should use the marker sequence numbers to reassemble the profile,
|
||||
* rather than assuming that the APP2 markers appear in the correct sequence.
|
||||
*/
|
||||
|
||||
#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */
|
||||
#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */
|
||||
#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */
|
||||
#define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)
|
||||
|
||||
|
||||
/*
|
||||
* This routine writes the given ICC profile data into a JPEG file. It *must*
|
||||
* be called AFTER calling jpeg_start_compress() and BEFORE the first call to
|
||||
* jpeg_write_scanlines(). (This ordering ensures that the APP2 marker(s) will
|
||||
* appear after the SOI and JFIF or Adobe markers, but before all else.)
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_write_icc_profile(j_compress_ptr cinfo, const JOCTET *icc_data_ptr,
|
||||
unsigned int icc_data_len)
|
||||
{
|
||||
unsigned int num_markers; /* total number of markers we'll write */
|
||||
int cur_marker = 1; /* per spec, counting starts at 1 */
|
||||
unsigned int length; /* number of bytes to write in this marker */
|
||||
|
||||
if (icc_data_ptr == NULL || icc_data_len == 0)
|
||||
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
||||
if (cinfo->global_state < CSTATE_SCANNING)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
/* Calculate the number of markers we'll need, rounding up of course */
|
||||
num_markers = icc_data_len / MAX_DATA_BYTES_IN_MARKER;
|
||||
if (num_markers * MAX_DATA_BYTES_IN_MARKER != icc_data_len)
|
||||
num_markers++;
|
||||
|
||||
while (icc_data_len > 0) {
|
||||
/* length of profile to put in this marker */
|
||||
length = icc_data_len;
|
||||
if (length > MAX_DATA_BYTES_IN_MARKER)
|
||||
length = MAX_DATA_BYTES_IN_MARKER;
|
||||
icc_data_len -= length;
|
||||
|
||||
/* Write the JPEG marker header (APP2 code and marker length) */
|
||||
jpeg_write_m_header(cinfo, ICC_MARKER,
|
||||
(unsigned int)(length + ICC_OVERHEAD_LEN));
|
||||
|
||||
/* Write the marker identifying string "ICC_PROFILE" (null-terminated). We
|
||||
* code it in this less-than-transparent way so that the code works even if
|
||||
* the local character set is not ASCII.
|
||||
*/
|
||||
jpeg_write_m_byte(cinfo, 0x49);
|
||||
jpeg_write_m_byte(cinfo, 0x43);
|
||||
jpeg_write_m_byte(cinfo, 0x43);
|
||||
jpeg_write_m_byte(cinfo, 0x5F);
|
||||
jpeg_write_m_byte(cinfo, 0x50);
|
||||
jpeg_write_m_byte(cinfo, 0x52);
|
||||
jpeg_write_m_byte(cinfo, 0x4F);
|
||||
jpeg_write_m_byte(cinfo, 0x46);
|
||||
jpeg_write_m_byte(cinfo, 0x49);
|
||||
jpeg_write_m_byte(cinfo, 0x4C);
|
||||
jpeg_write_m_byte(cinfo, 0x45);
|
||||
jpeg_write_m_byte(cinfo, 0x0);
|
||||
|
||||
/* Add the sequencing info */
|
||||
jpeg_write_m_byte(cinfo, cur_marker);
|
||||
jpeg_write_m_byte(cinfo, (int)num_markers);
|
||||
|
||||
/* Add the profile data */
|
||||
while (length--) {
|
||||
jpeg_write_m_byte(cinfo, *icc_data_ptr);
|
||||
icc_data_ptr++;
|
||||
}
|
||||
cur_marker++;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,8 +3,10 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2020, D. R. Commander.
|
||||
* Copyright (C) 2020, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -21,7 +23,7 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jpegcomp.h"
|
||||
#include "jpegapicomp.h"
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -38,34 +40,101 @@ jinit_compress_master(j_compress_ptr cinfo)
|
|||
|
||||
/* 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) {
|
||||
#ifdef C_ARITH_CODING_SUPPORTED
|
||||
jinit_arith_encoder(cinfo);
|
||||
if (cinfo->data_precision == 16) {
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
j16init_color_converter(cinfo);
|
||||
j16init_downsampler(cinfo);
|
||||
j16init_c_prep_controller(cinfo,
|
||||
FALSE /* never need full buffer here */);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
#endif
|
||||
} 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);
|
||||
} else if (cinfo->data_precision == 12) {
|
||||
j12init_color_converter(cinfo);
|
||||
j12init_downsampler(cinfo);
|
||||
j12init_c_prep_controller(cinfo,
|
||||
FALSE /* never need full buffer here */);
|
||||
} else {
|
||||
jinit_color_converter(cinfo);
|
||||
jinit_downsampler(cinfo);
|
||||
jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 */);
|
||||
if (cinfo->master->lossless) {
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
/* Prediction, sample differencing, and point transform */
|
||||
if (cinfo->data_precision == 16)
|
||||
j16init_lossless_compressor(cinfo);
|
||||
else if (cinfo->data_precision == 12)
|
||||
j12init_lossless_compressor(cinfo);
|
||||
else
|
||||
jinit_lossless_compressor(cinfo);
|
||||
/* Entropy encoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
} else {
|
||||
jinit_lhuff_encoder(cinfo);
|
||||
}
|
||||
|
||||
/* Need a full-image difference buffer in any multi-pass mode. */
|
||||
if (cinfo->data_precision == 16)
|
||||
j16init_c_diff_controller(cinfo, (boolean)(cinfo->num_scans > 1 ||
|
||||
cinfo->optimize_coding));
|
||||
else if (cinfo->data_precision == 12)
|
||||
j12init_c_diff_controller(cinfo, (boolean)(cinfo->num_scans > 1 ||
|
||||
cinfo->optimize_coding));
|
||||
else
|
||||
jinit_c_diff_controller(cinfo, (boolean)(cinfo->num_scans > 1 ||
|
||||
cinfo->optimize_coding));
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else {
|
||||
if (cinfo->data_precision == 16)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
/* Forward DCT */
|
||||
if (cinfo->data_precision == 12)
|
||||
j12init_forward_dct(cinfo);
|
||||
else
|
||||
jinit_forward_dct(cinfo);
|
||||
/* Entropy encoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
#ifdef C_ARITH_CODING_SUPPORTED
|
||||
jinit_arith_encoder(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
#endif
|
||||
} 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. */
|
||||
if (cinfo->data_precision == 12)
|
||||
j12init_c_coef_controller(cinfo, (boolean)(cinfo->num_scans > 1 ||
|
||||
cinfo->optimize_coding));
|
||||
else
|
||||
jinit_c_coef_controller(cinfo, (boolean)(cinfo->num_scans > 1 ||
|
||||
cinfo->optimize_coding));
|
||||
}
|
||||
|
||||
if (cinfo->data_precision == 16)
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
j16init_c_main_controller(cinfo, FALSE /* never need full buffer here */);
|
||||
#else
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
#endif
|
||||
else if (cinfo->data_precision == 12)
|
||||
j12init_c_main_controller(cinfo, FALSE /* never need full buffer here */);
|
||||
else
|
||||
jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
|
||||
|
||||
jinit_marker_writer(cinfo);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,587 @@
|
|||
/*
|
||||
* jclhuff.c
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file contains Huffman entropy encoding routines for lossless JPEG.
|
||||
*
|
||||
* Much of the complexity here has to do with supporting output suspension.
|
||||
* If the data destination module demands suspension, we want to be able to
|
||||
* back up to the start of the current MCU. To do this, we copy state
|
||||
* variables into local working storage, and update them back to the
|
||||
* permanent JPEG objects only upon successful completion of an MCU.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jlossls.h" /* Private declarations for lossless codec */
|
||||
#include "jchuff.h" /* Declarations shared with jc*huff.c */
|
||||
|
||||
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
|
||||
/* The legal range of a spatial difference is
|
||||
* -32767 .. +32768.
|
||||
* Hence the magnitude should always fit in 16 bits.
|
||||
*/
|
||||
|
||||
#define MAX_DIFF_BITS 16
|
||||
|
||||
|
||||
/* Expanded entropy encoder object for Huffman encoding in lossless mode.
|
||||
*
|
||||
* The savable_state subrecord contains fields that change within an MCU,
|
||||
* but must not be updated permanently until we complete the MCU.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
size_t put_buffer; /* current bit-accumulation buffer */
|
||||
int put_bits; /* # of bits now in it */
|
||||
} savable_state;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int ci, yoffset, MCU_width;
|
||||
} lhe_input_ptr_info;
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_entropy_encoder pub; /* public fields */
|
||||
|
||||
savable_state saved; /* Bit buffer at start of MCU */
|
||||
|
||||
/* These fields are NOT loaded into local working state. */
|
||||
unsigned int restarts_to_go; /* MCUs left in this restart interval */
|
||||
int next_restart_num; /* next restart number to write (0-7) */
|
||||
|
||||
/* Pointers to derived tables (these workspaces have image lifespan) */
|
||||
c_derived_tbl *derived_tbls[NUM_HUFF_TBLS];
|
||||
|
||||
/* Pointers to derived tables to be used for each data unit within an MCU */
|
||||
c_derived_tbl *cur_tbls[C_MAX_BLOCKS_IN_MCU];
|
||||
|
||||
#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */
|
||||
long *count_ptrs[NUM_HUFF_TBLS];
|
||||
|
||||
/* Pointers to stats tables to be used for each data unit within an MCU */
|
||||
long *cur_counts[C_MAX_BLOCKS_IN_MCU];
|
||||
#endif
|
||||
|
||||
/* Pointers to the proper input difference row for each group of data units
|
||||
* within an MCU. For each component, there are Vi groups of Hi data units.
|
||||
*/
|
||||
JDIFFROW input_ptr[C_MAX_BLOCKS_IN_MCU];
|
||||
|
||||
/* Number of input pointers in use for the current MCU. This is the sum
|
||||
* of all Vi in the MCU.
|
||||
*/
|
||||
int num_input_ptrs;
|
||||
|
||||
/* Information used for positioning the input pointers within the input
|
||||
* difference rows.
|
||||
*/
|
||||
lhe_input_ptr_info input_ptr_info[C_MAX_BLOCKS_IN_MCU];
|
||||
|
||||
/* Index of the proper input pointer for each data unit within an MCU */
|
||||
int input_ptr_index[C_MAX_BLOCKS_IN_MCU];
|
||||
|
||||
} lhuff_entropy_encoder;
|
||||
|
||||
typedef lhuff_entropy_encoder *lhuff_entropy_ptr;
|
||||
|
||||
/* Working state while writing an MCU.
|
||||
* This struct contains all the fields that are needed by subroutines.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
JOCTET *next_output_byte; /* => next byte to write in buffer */
|
||||
size_t free_in_buffer; /* # of byte spaces remaining in buffer */
|
||||
savable_state cur; /* Current bit buffer & DC state */
|
||||
j_compress_ptr cinfo; /* dump_buffer needs access to this */
|
||||
} working_state;
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(JDIMENSION) encode_mcus_huff(j_compress_ptr cinfo,
|
||||
JDIFFIMAGE diff_buf,
|
||||
JDIMENSION MCU_row_num,
|
||||
JDIMENSION MCU_col_num,
|
||||
JDIMENSION nMCU);
|
||||
METHODDEF(void) finish_pass_huff(j_compress_ptr cinfo);
|
||||
#ifdef ENTROPY_OPT_SUPPORTED
|
||||
METHODDEF(JDIMENSION) encode_mcus_gather(j_compress_ptr cinfo,
|
||||
JDIFFIMAGE diff_buf,
|
||||
JDIMENSION MCU_row_num,
|
||||
JDIMENSION MCU_col_num,
|
||||
JDIMENSION nMCU);
|
||||
METHODDEF(void) finish_pass_gather(j_compress_ptr cinfo);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a Huffman-compressed scan.
|
||||
* If gather_statistics is TRUE, we do not output anything during the scan,
|
||||
* just count the Huffman symbols used and generate Huffman code tables.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_lhuff(j_compress_ptr cinfo, boolean gather_statistics)
|
||||
{
|
||||
lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
|
||||
int ci, dctbl, sampn, ptrn, yoffset, xoffset;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
if (gather_statistics) {
|
||||
#ifdef ENTROPY_OPT_SUPPORTED
|
||||
entropy->pub.encode_mcus = encode_mcus_gather;
|
||||
entropy->pub.finish_pass = finish_pass_gather;
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else {
|
||||
entropy->pub.encode_mcus = encode_mcus_huff;
|
||||
entropy->pub.finish_pass = finish_pass_huff;
|
||||
}
|
||||
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
dctbl = compptr->dc_tbl_no;
|
||||
if (gather_statistics) {
|
||||
#ifdef ENTROPY_OPT_SUPPORTED
|
||||
/* Check for invalid table indexes */
|
||||
/* (make_c_derived_tbl does this in the other path) */
|
||||
if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
|
||||
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
|
||||
/* Allocate and zero the statistics tables */
|
||||
/* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
|
||||
if (entropy->count_ptrs[dctbl] == NULL)
|
||||
entropy->count_ptrs[dctbl] = (long *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
257 * sizeof(long));
|
||||
memset(entropy->count_ptrs[dctbl], 0, 257 * sizeof(long));
|
||||
#endif
|
||||
} else {
|
||||
/* Compute derived values for Huffman tables */
|
||||
/* We may do this more than once for a table, but it's not expensive */
|
||||
jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl,
|
||||
&entropy->derived_tbls[dctbl]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Precalculate encoding info for each sample in an MCU of this scan */
|
||||
for (sampn = 0, ptrn = 0; sampn < cinfo->blocks_in_MCU;) {
|
||||
compptr = cinfo->cur_comp_info[cinfo->MCU_membership[sampn]];
|
||||
ci = compptr->component_index;
|
||||
for (yoffset = 0; yoffset < compptr->MCU_height; yoffset++, ptrn++) {
|
||||
/* Precalculate the setup info for each input pointer */
|
||||
entropy->input_ptr_info[ptrn].ci = ci;
|
||||
entropy->input_ptr_info[ptrn].yoffset = yoffset;
|
||||
entropy->input_ptr_info[ptrn].MCU_width = compptr->MCU_width;
|
||||
for (xoffset = 0; xoffset < compptr->MCU_width; xoffset++, sampn++) {
|
||||
/* Precalculate the input pointer index for each sample */
|
||||
entropy->input_ptr_index[sampn] = ptrn;
|
||||
/* Precalculate which tables to use for each sample */
|
||||
entropy->cur_tbls[sampn] = entropy->derived_tbls[compptr->dc_tbl_no];
|
||||
entropy->cur_counts[sampn] = entropy->count_ptrs[compptr->dc_tbl_no];
|
||||
}
|
||||
}
|
||||
}
|
||||
entropy->num_input_ptrs = ptrn;
|
||||
|
||||
/* Initialize bit buffer to empty */
|
||||
entropy->saved.put_buffer = 0;
|
||||
entropy->saved.put_bits = 0;
|
||||
|
||||
/* Initialize restart stuff */
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
entropy->next_restart_num = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Outputting bytes to the file */
|
||||
|
||||
/* Emit a byte, taking 'action' if must suspend. */
|
||||
#define emit_byte(state, val, action) { \
|
||||
*(state)->next_output_byte++ = (JOCTET)(val); \
|
||||
if (--(state)->free_in_buffer == 0) \
|
||||
if (!dump_buffer(state)) \
|
||||
{ action; } \
|
||||
}
|
||||
|
||||
|
||||
LOCAL(boolean)
|
||||
dump_buffer(working_state *state)
|
||||
/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
|
||||
{
|
||||
struct jpeg_destination_mgr *dest = state->cinfo->dest;
|
||||
|
||||
if (!(*dest->empty_output_buffer) (state->cinfo))
|
||||
return FALSE;
|
||||
/* After a successful buffer dump, must reset buffer pointers */
|
||||
state->next_output_byte = dest->next_output_byte;
|
||||
state->free_in_buffer = dest->free_in_buffer;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Outputting bits to the file */
|
||||
|
||||
/* Only the right 24 bits of put_buffer are used; the valid bits are
|
||||
* left-justified in this part. At most 16 bits can be passed to emit_bits
|
||||
* in one call, and we never retain more than 7 bits in put_buffer
|
||||
* between calls, so 24 bits are sufficient.
|
||||
*/
|
||||
|
||||
INLINE
|
||||
LOCAL(boolean)
|
||||
emit_bits(working_state *state, unsigned int code, int size)
|
||||
/* Emit some bits; return TRUE if successful, FALSE if must suspend */
|
||||
{
|
||||
/* This routine is heavily used, so it's worth coding tightly. */
|
||||
register size_t put_buffer = (size_t)code;
|
||||
register int put_bits = state->cur.put_bits;
|
||||
|
||||
/* if size is 0, caller used an invalid Huffman table entry */
|
||||
if (size == 0)
|
||||
ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE);
|
||||
|
||||
put_buffer &= (((size_t)1) << size) - 1; /* mask off any extra bits in code */
|
||||
|
||||
put_bits += size; /* new number of bits in buffer */
|
||||
|
||||
put_buffer <<= 24 - put_bits; /* align incoming bits */
|
||||
|
||||
put_buffer |= state->cur.put_buffer; /* and merge with old buffer contents */
|
||||
|
||||
while (put_bits >= 8) {
|
||||
int c = (int)((put_buffer >> 16) & 0xFF);
|
||||
|
||||
emit_byte(state, c, return FALSE);
|
||||
if (c == 0xFF) { /* need to stuff a zero byte? */
|
||||
emit_byte(state, 0, return FALSE);
|
||||
}
|
||||
put_buffer <<= 8;
|
||||
put_bits -= 8;
|
||||
}
|
||||
|
||||
state->cur.put_buffer = put_buffer; /* update state variables */
|
||||
state->cur.put_bits = put_bits;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
LOCAL(boolean)
|
||||
flush_bits(working_state *state)
|
||||
{
|
||||
if (!emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */
|
||||
return FALSE;
|
||||
state->cur.put_buffer = 0; /* and reset bit-buffer to empty */
|
||||
state->cur.put_bits = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Emit a restart marker & resynchronize predictions.
|
||||
*/
|
||||
|
||||
LOCAL(boolean)
|
||||
emit_restart(working_state *state, int restart_num)
|
||||
{
|
||||
if (!flush_bits(state))
|
||||
return FALSE;
|
||||
|
||||
emit_byte(state, 0xFF, return FALSE);
|
||||
emit_byte(state, JPEG_RST0 + restart_num, return FALSE);
|
||||
|
||||
/* The restart counter is not updated until we successfully write the MCU. */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Encode and output nMCU MCUs' worth of Huffman-compressed differences.
|
||||
*/
|
||||
|
||||
METHODDEF(JDIMENSION)
|
||||
encode_mcus_huff(j_compress_ptr cinfo, JDIFFIMAGE diff_buf,
|
||||
JDIMENSION MCU_row_num, JDIMENSION MCU_col_num,
|
||||
JDIMENSION nMCU)
|
||||
{
|
||||
lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
|
||||
working_state state;
|
||||
int sampn, ci, yoffset, MCU_width, ptrn;
|
||||
JDIMENSION mcu_num;
|
||||
|
||||
/* Load up working state */
|
||||
state.next_output_byte = cinfo->dest->next_output_byte;
|
||||
state.free_in_buffer = cinfo->dest->free_in_buffer;
|
||||
state.cur = entropy->saved;
|
||||
state.cinfo = cinfo;
|
||||
|
||||
/* Emit restart marker if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0)
|
||||
if (!emit_restart(&state, entropy->next_restart_num))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set input pointer locations based on MCU_col_num */
|
||||
for (ptrn = 0; ptrn < entropy->num_input_ptrs; ptrn++) {
|
||||
ci = entropy->input_ptr_info[ptrn].ci;
|
||||
yoffset = entropy->input_ptr_info[ptrn].yoffset;
|
||||
MCU_width = entropy->input_ptr_info[ptrn].MCU_width;
|
||||
entropy->input_ptr[ptrn] =
|
||||
diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width);
|
||||
}
|
||||
|
||||
for (mcu_num = 0; mcu_num < nMCU; mcu_num++) {
|
||||
|
||||
/* Inner loop handles the samples in the MCU */
|
||||
for (sampn = 0; sampn < cinfo->blocks_in_MCU; sampn++) {
|
||||
register int temp, temp2;
|
||||
register int nbits;
|
||||
c_derived_tbl *dctbl = entropy->cur_tbls[sampn];
|
||||
|
||||
/* Encode the difference per section H.1.2.2 */
|
||||
|
||||
/* Input the sample difference */
|
||||
temp = *entropy->input_ptr[entropy->input_ptr_index[sampn]]++;
|
||||
|
||||
if (temp & 0x8000) { /* instead of temp < 0 */
|
||||
temp = (-temp) & 0x7FFF; /* absolute value, mod 2^16 */
|
||||
if (temp == 0) /* special case: magnitude = 32768 */
|
||||
temp2 = temp = 0x8000;
|
||||
temp2 = ~temp; /* one's complement of magnitude */
|
||||
} else {
|
||||
temp &= 0x7FFF; /* abs value mod 2^16 */
|
||||
temp2 = temp; /* magnitude */
|
||||
}
|
||||
|
||||
/* Find the number of bits needed for the magnitude of the difference */
|
||||
nbits = 0;
|
||||
while (temp) {
|
||||
nbits++;
|
||||
temp >>= 1;
|
||||
}
|
||||
/* Check for out-of-range difference values.
|
||||
*/
|
||||
if (nbits > MAX_DIFF_BITS)
|
||||
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
|
||||
|
||||
/* Emit the Huffman-coded symbol for the number of bits */
|
||||
if (!emit_bits(&state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
|
||||
return mcu_num;
|
||||
|
||||
/* Emit that number of bits of the value, if positive, */
|
||||
/* or the complement of its magnitude, if negative. */
|
||||
if (nbits && /* emit_bits rejects calls with size 0 */
|
||||
nbits != 16) /* special case: no bits should be emitted */
|
||||
if (!emit_bits(&state, (unsigned int)temp2, nbits))
|
||||
return mcu_num;
|
||||
}
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
cinfo->dest->next_output_byte = state.next_output_byte;
|
||||
cinfo->dest->free_in_buffer = state.free_in_buffer;
|
||||
entropy->saved = state.cur;
|
||||
|
||||
/* Update restart-interval state too */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0) {
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
entropy->next_restart_num++;
|
||||
entropy->next_restart_num &= 7;
|
||||
}
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nMCU;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish up at the end of a Huffman-compressed scan.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
finish_pass_huff(j_compress_ptr cinfo)
|
||||
{
|
||||
lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
|
||||
working_state state;
|
||||
|
||||
/* Load up working state ... flush_bits needs it */
|
||||
state.next_output_byte = cinfo->dest->next_output_byte;
|
||||
state.free_in_buffer = cinfo->dest->free_in_buffer;
|
||||
state.cur = entropy->saved;
|
||||
state.cinfo = cinfo;
|
||||
|
||||
/* Flush out the last data */
|
||||
if (!flush_bits(&state))
|
||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
||||
|
||||
/* Update state */
|
||||
cinfo->dest->next_output_byte = state.next_output_byte;
|
||||
cinfo->dest->free_in_buffer = state.free_in_buffer;
|
||||
entropy->saved = state.cur;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Huffman coding optimization.
|
||||
*
|
||||
* We first scan the supplied data and count the number of uses of each symbol
|
||||
* that is to be Huffman-coded. (This process MUST agree with the code above.)
|
||||
* Then we build a Huffman coding tree for the observed counts.
|
||||
* Symbols which are not needed at all for the particular image are not
|
||||
* assigned any code, which saves space in the DHT marker as well as in
|
||||
* the compressed data.
|
||||
*/
|
||||
|
||||
#ifdef ENTROPY_OPT_SUPPORTED
|
||||
|
||||
/*
|
||||
* Trial-encode nMCU MCUs' worth of Huffman-compressed differences.
|
||||
* No data is actually output, so no suspension return is possible.
|
||||
*/
|
||||
|
||||
METHODDEF(JDIMENSION)
|
||||
encode_mcus_gather(j_compress_ptr cinfo, JDIFFIMAGE diff_buf,
|
||||
JDIMENSION MCU_row_num, JDIMENSION MCU_col_num,
|
||||
JDIMENSION nMCU)
|
||||
{
|
||||
lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
|
||||
int sampn, ci, yoffset, MCU_width, ptrn;
|
||||
JDIMENSION mcu_num;
|
||||
|
||||
/* Take care of restart intervals if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0) {
|
||||
/* Update restart state */
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
}
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
/* Set input pointer locations based on MCU_col_num */
|
||||
for (ptrn = 0; ptrn < entropy->num_input_ptrs; ptrn++) {
|
||||
ci = entropy->input_ptr_info[ptrn].ci;
|
||||
yoffset = entropy->input_ptr_info[ptrn].yoffset;
|
||||
MCU_width = entropy->input_ptr_info[ptrn].MCU_width;
|
||||
entropy->input_ptr[ptrn] =
|
||||
diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width);
|
||||
}
|
||||
|
||||
for (mcu_num = 0; mcu_num < nMCU; mcu_num++) {
|
||||
|
||||
/* Inner loop handles the samples in the MCU */
|
||||
for (sampn = 0; sampn < cinfo->blocks_in_MCU; sampn++) {
|
||||
register int temp;
|
||||
register int nbits;
|
||||
long *counts = entropy->cur_counts[sampn];
|
||||
|
||||
/* Encode the difference per section H.1.2.2 */
|
||||
|
||||
/* Input the sample difference */
|
||||
temp = *entropy->input_ptr[entropy->input_ptr_index[sampn]]++;
|
||||
|
||||
if (temp & 0x8000) { /* instead of temp < 0 */
|
||||
temp = (-temp) & 0x7FFF; /* absolute value, mod 2^16 */
|
||||
if (temp == 0) /* special case: magnitude = 32768 */
|
||||
temp = 0x8000;
|
||||
} else
|
||||
temp &= 0x7FFF; /* abs value mod 2^16 */
|
||||
|
||||
/* Find the number of bits needed for the magnitude of the difference */
|
||||
nbits = 0;
|
||||
while (temp) {
|
||||
nbits++;
|
||||
temp >>= 1;
|
||||
}
|
||||
/* Check for out-of-range difference values.
|
||||
*/
|
||||
if (nbits > MAX_DIFF_BITS)
|
||||
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
|
||||
|
||||
/* Count the Huffman symbol for the number of bits */
|
||||
counts[nbits]++;
|
||||
}
|
||||
}
|
||||
|
||||
return nMCU;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish up a statistics-gathering pass and create the new Huffman tables.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
finish_pass_gather(j_compress_ptr cinfo)
|
||||
{
|
||||
lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
|
||||
int ci, dctbl;
|
||||
jpeg_component_info *compptr;
|
||||
JHUFF_TBL **htblptr;
|
||||
boolean did_dc[NUM_HUFF_TBLS];
|
||||
|
||||
/* It's important not to apply jpeg_gen_optimal_table more than once
|
||||
* per table, because it clobbers the input frequency counts!
|
||||
*/
|
||||
memset(did_dc, 0, sizeof(did_dc));
|
||||
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
dctbl = compptr->dc_tbl_no;
|
||||
if (!did_dc[dctbl]) {
|
||||
htblptr = &cinfo->dc_huff_tbl_ptrs[dctbl];
|
||||
if (*htblptr == NULL)
|
||||
*htblptr = jpeg_alloc_huff_table((j_common_ptr)cinfo);
|
||||
jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[dctbl]);
|
||||
did_dc[dctbl] = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* ENTROPY_OPT_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for Huffman entropy encoding.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_lhuff_encoder(j_compress_ptr cinfo)
|
||||
{
|
||||
lhuff_entropy_ptr entropy;
|
||||
int i;
|
||||
|
||||
entropy = (lhuff_entropy_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(lhuff_entropy_encoder));
|
||||
cinfo->entropy = (struct jpeg_entropy_encoder *)entropy;
|
||||
entropy->pub.start_pass = start_pass_lhuff;
|
||||
|
||||
/* Mark tables unallocated */
|
||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
||||
entropy->derived_tbls[i] = NULL;
|
||||
#ifdef ENTROPY_OPT_SUPPORTED
|
||||
entropy->count_ptrs[i] = NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* C_LOSSLESS_SUPPORTED */
|
||||
|
|
@ -0,0 +1,319 @@
|
|||
/*
|
||||
* jclossls.c
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1998, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file contains prediction, sample differencing, and point transform
|
||||
* routines for the lossless JPEG compressor.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jlossls.h"
|
||||
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
|
||||
|
||||
/************************** Sample differencing **************************/
|
||||
|
||||
/*
|
||||
* In order to avoid a performance penalty for checking which predictor is
|
||||
* being used and which row is being processed for each call of the
|
||||
* undifferencer, and to promote optimization, we have separate differencing
|
||||
* functions for each predictor selection value.
|
||||
*
|
||||
* We are able to avoid duplicating source code by implementing the predictors
|
||||
* and differencers as macros. Each of the differencing functions is simply a
|
||||
* wrapper around a DIFFERENCE macro with the appropriate PREDICTOR macro
|
||||
* passed as an argument.
|
||||
*/
|
||||
|
||||
/* Forward declarations */
|
||||
LOCAL(void) reset_predictor(j_compress_ptr cinfo, int ci);
|
||||
|
||||
|
||||
/* Predictor for the first column of the first row: 2^(P-Pt-1) */
|
||||
#define INITIAL_PREDICTORx (1 << (cinfo->data_precision - cinfo->Al - 1))
|
||||
|
||||
/* Predictor for the first column of the remaining rows: Rb */
|
||||
#define INITIAL_PREDICTOR2 prev_row[0]
|
||||
|
||||
|
||||
/*
|
||||
* 1-Dimensional differencer routine.
|
||||
*
|
||||
* This macro implements the 1-D horizontal predictor (1). INITIAL_PREDICTOR
|
||||
* is used as the special case predictor for the first column, which must be
|
||||
* either INITIAL_PREDICTOR2 or INITIAL_PREDICTORx. The remaining samples
|
||||
* use PREDICTOR1.
|
||||
*/
|
||||
|
||||
#define DIFFERENCE_1D(INITIAL_PREDICTOR) \
|
||||
lossless_comp_ptr losslessc = (lossless_comp_ptr)cinfo->fdct; \
|
||||
boolean restart = FALSE; \
|
||||
int samp, Ra; \
|
||||
\
|
||||
samp = *input_buf++; \
|
||||
*diff_buf++ = samp - INITIAL_PREDICTOR; \
|
||||
\
|
||||
while (--width) { \
|
||||
Ra = samp; \
|
||||
samp = *input_buf++; \
|
||||
*diff_buf++ = samp - PREDICTOR1; \
|
||||
} \
|
||||
\
|
||||
/* Account for restart interval (no-op if not using restarts) */ \
|
||||
if (cinfo->restart_interval) { \
|
||||
if (--(losslessc->restart_rows_to_go[ci]) == 0) { \
|
||||
reset_predictor(cinfo, ci); \
|
||||
restart = TRUE; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 2-Dimensional differencer routine.
|
||||
*
|
||||
* This macro implements the 2-D horizontal predictors (#2-7). PREDICTOR2 is
|
||||
* used as the special case predictor for the first column. The remaining
|
||||
* samples use PREDICTOR, which is a function of Ra, Rb, and Rc.
|
||||
*
|
||||
* Because prev_row and output_buf may point to the same storage area (in an
|
||||
* interleaved image with Vi=1, for example), we must take care to buffer Rb/Rc
|
||||
* before writing the current reconstructed sample value into output_buf.
|
||||
*/
|
||||
|
||||
#define DIFFERENCE_2D(PREDICTOR) \
|
||||
lossless_comp_ptr losslessc = (lossless_comp_ptr)cinfo->fdct; \
|
||||
int samp, Ra, Rb, Rc; \
|
||||
\
|
||||
Rb = *prev_row++; \
|
||||
samp = *input_buf++; \
|
||||
*diff_buf++ = samp - PREDICTOR2; \
|
||||
\
|
||||
while (--width) { \
|
||||
Rc = Rb; \
|
||||
Rb = *prev_row++; \
|
||||
Ra = samp; \
|
||||
samp = *input_buf++; \
|
||||
*diff_buf++ = samp - PREDICTOR; \
|
||||
} \
|
||||
\
|
||||
/* Account for restart interval (no-op if not using restarts) */ \
|
||||
if (cinfo->restart_interval) { \
|
||||
if (--losslessc->restart_rows_to_go[ci] == 0) \
|
||||
reset_predictor(cinfo, ci); \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Differencers for the second and subsequent rows in a scan or restart
|
||||
* interval. The first sample in the row is differenced using the vertical
|
||||
* predictor (2). The rest of the samples are differenced using the predictor
|
||||
* specified in the scan header.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_difference1(j_compress_ptr cinfo, int ci,
|
||||
_JSAMPROW input_buf, _JSAMPROW prev_row,
|
||||
JDIFFROW diff_buf, JDIMENSION width)
|
||||
{
|
||||
DIFFERENCE_1D(INITIAL_PREDICTOR2);
|
||||
(void)(restart);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_difference2(j_compress_ptr cinfo, int ci,
|
||||
_JSAMPROW input_buf, _JSAMPROW prev_row,
|
||||
JDIFFROW diff_buf, JDIMENSION width)
|
||||
{
|
||||
DIFFERENCE_2D(PREDICTOR2);
|
||||
(void)(Ra);
|
||||
(void)(Rc);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_difference3(j_compress_ptr cinfo, int ci,
|
||||
_JSAMPROW input_buf, _JSAMPROW prev_row,
|
||||
JDIFFROW diff_buf, JDIMENSION width)
|
||||
{
|
||||
DIFFERENCE_2D(PREDICTOR3);
|
||||
(void)(Ra);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_difference4(j_compress_ptr cinfo, int ci,
|
||||
_JSAMPROW input_buf, _JSAMPROW prev_row,
|
||||
JDIFFROW diff_buf, JDIMENSION width)
|
||||
{
|
||||
DIFFERENCE_2D(PREDICTOR4);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_difference5(j_compress_ptr cinfo, int ci,
|
||||
_JSAMPROW input_buf, _JSAMPROW prev_row,
|
||||
JDIFFROW diff_buf, JDIMENSION width)
|
||||
{
|
||||
DIFFERENCE_2D(PREDICTOR5);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_difference6(j_compress_ptr cinfo, int ci,
|
||||
_JSAMPROW input_buf, _JSAMPROW prev_row,
|
||||
JDIFFROW diff_buf, JDIMENSION width)
|
||||
{
|
||||
DIFFERENCE_2D(PREDICTOR6);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_difference7(j_compress_ptr cinfo, int ci,
|
||||
_JSAMPROW input_buf, _JSAMPROW prev_row,
|
||||
JDIFFROW diff_buf, JDIMENSION width)
|
||||
{
|
||||
DIFFERENCE_2D(PREDICTOR7);
|
||||
(void)(Rc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Differencer for the first row in a scan or restart interval. The first
|
||||
* sample in the row is differenced using the special predictor constant
|
||||
* x = 2 ^ (P-Pt-1). The rest of the samples are differenced using the
|
||||
* 1-D horizontal predictor (1).
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_difference_first_row(j_compress_ptr cinfo, int ci,
|
||||
_JSAMPROW input_buf, _JSAMPROW prev_row,
|
||||
JDIFFROW diff_buf, JDIMENSION width)
|
||||
{
|
||||
DIFFERENCE_1D(INITIAL_PREDICTORx);
|
||||
|
||||
/*
|
||||
* Now that we have differenced the first row, we want to use the
|
||||
* differencer that corresponds to the predictor specified in the
|
||||
* scan header.
|
||||
*
|
||||
* Note that we don't do this if we have just reset the predictor
|
||||
* for a new restart interval.
|
||||
*/
|
||||
if (!restart) {
|
||||
switch (cinfo->Ss) {
|
||||
case 1:
|
||||
losslessc->predict_difference[ci] = jpeg_difference1;
|
||||
break;
|
||||
case 2:
|
||||
losslessc->predict_difference[ci] = jpeg_difference2;
|
||||
break;
|
||||
case 3:
|
||||
losslessc->predict_difference[ci] = jpeg_difference3;
|
||||
break;
|
||||
case 4:
|
||||
losslessc->predict_difference[ci] = jpeg_difference4;
|
||||
break;
|
||||
case 5:
|
||||
losslessc->predict_difference[ci] = jpeg_difference5;
|
||||
break;
|
||||
case 6:
|
||||
losslessc->predict_difference[ci] = jpeg_difference6;
|
||||
break;
|
||||
case 7:
|
||||
losslessc->predict_difference[ci] = jpeg_difference7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset predictor at the start of a pass or restart interval.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
reset_predictor(j_compress_ptr cinfo, int ci)
|
||||
{
|
||||
lossless_comp_ptr losslessc = (lossless_comp_ptr)cinfo->fdct;
|
||||
|
||||
/* Initialize restart counter */
|
||||
losslessc->restart_rows_to_go[ci] =
|
||||
cinfo->restart_interval / cinfo->MCUs_per_row;
|
||||
|
||||
/* Set difference function to first row function */
|
||||
losslessc->predict_difference[ci] = jpeg_difference_first_row;
|
||||
}
|
||||
|
||||
|
||||
/********************** Sample downscaling by 2^Pt ***********************/
|
||||
|
||||
METHODDEF(void)
|
||||
simple_downscale(j_compress_ptr cinfo,
|
||||
_JSAMPROW input_buf, _JSAMPROW output_buf, JDIMENSION width)
|
||||
{
|
||||
do {
|
||||
*output_buf++ = (_JSAMPLE)RIGHT_SHIFT(*input_buf++, cinfo->Al);
|
||||
} while (--width);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
noscale(j_compress_ptr cinfo,
|
||||
_JSAMPROW input_buf, _JSAMPROW output_buf, JDIMENSION width)
|
||||
{
|
||||
memcpy(output_buf, input_buf, width * sizeof(_JSAMPLE));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_lossless(j_compress_ptr cinfo)
|
||||
{
|
||||
lossless_comp_ptr losslessc = (lossless_comp_ptr)cinfo->fdct;
|
||||
int ci;
|
||||
|
||||
/* Set scaler function based on Pt */
|
||||
if (cinfo->Al)
|
||||
losslessc->scaler_scale = simple_downscale;
|
||||
else
|
||||
losslessc->scaler_scale = noscale;
|
||||
|
||||
/* Check that the restart interval is an integer multiple of the number
|
||||
* of MCUs in an MCU row.
|
||||
*/
|
||||
if (cinfo->restart_interval % cinfo->MCUs_per_row != 0)
|
||||
ERREXIT2(cinfo, JERR_BAD_RESTART,
|
||||
cinfo->restart_interval, cinfo->MCUs_per_row);
|
||||
|
||||
/* Set predictors for start of pass */
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
reset_predictor(cinfo, ci);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the lossless compressor.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
_jinit_lossless_compressor(j_compress_ptr cinfo)
|
||||
{
|
||||
lossless_comp_ptr losslessc;
|
||||
|
||||
/* Create subobject in permanent pool */
|
||||
losslessc = (lossless_comp_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,
|
||||
sizeof(jpeg_lossless_compressor));
|
||||
cinfo->fdct = (struct jpeg_forward_dct *)losslessc;
|
||||
losslessc->pub.start_pass = start_pass_lossless;
|
||||
}
|
||||
|
||||
#endif /* C_LOSSLESS_SUPPORTED */
|
||||
|
|
@ -3,8 +3,10 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* It was modified by The libjpeg-turbo Project to include only code relevant
|
||||
* to libjpeg-turbo.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -16,8 +18,11 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -32,7 +37,7 @@ typedef struct {
|
|||
* (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];
|
||||
_JSAMPARRAY buffer[MAX_COMPONENTS];
|
||||
} my_main_controller;
|
||||
|
||||
typedef my_main_controller *my_main_ptr;
|
||||
|
|
@ -40,7 +45,7 @@ typedef my_main_controller *my_main_ptr;
|
|||
|
||||
/* Forward declarations */
|
||||
METHODDEF(void) process_data_simple_main(j_compress_ptr cinfo,
|
||||
JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY input_buf,
|
||||
JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail);
|
||||
|
||||
|
|
@ -65,7 +70,7 @@ start_pass_main(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
|||
main_ptr->rowgroup_ctr = 0;
|
||||
main_ptr->suspended = FALSE;
|
||||
main_ptr->pass_mode = pass_mode; /* save mode for use by process_data */
|
||||
main_ptr->pub.process_data = process_data_simple_main;
|
||||
main_ptr->pub._process_data = process_data_simple_main;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -76,28 +81,28 @@ start_pass_main(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
process_data_simple_main(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
process_data_simple_main(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)
|
||||
{
|
||||
my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
|
||||
JDIMENSION data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
|
||||
while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) {
|
||||
/* Read input data if we haven't filled the main buffer yet */
|
||||
if (main_ptr->rowgroup_ctr < DCTSIZE)
|
||||
(*cinfo->prep->pre_process_data) (cinfo, input_buf, in_row_ctr,
|
||||
in_rows_avail, main_ptr->buffer,
|
||||
&main_ptr->rowgroup_ctr,
|
||||
(JDIMENSION)DCTSIZE);
|
||||
if (main_ptr->rowgroup_ctr < data_unit)
|
||||
(*cinfo->prep->_pre_process_data) (cinfo, input_buf, in_row_ctr,
|
||||
in_rows_avail, main_ptr->buffer,
|
||||
&main_ptr->rowgroup_ctr, data_unit);
|
||||
|
||||
/* 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_ptr->rowgroup_ctr != DCTSIZE)
|
||||
if (main_ptr->rowgroup_ctr != data_unit)
|
||||
return;
|
||||
|
||||
/* Send the completed row to the compressor */
|
||||
if (!(*cinfo->coef->compress_data) (cinfo, main_ptr->buffer)) {
|
||||
if (!(*cinfo->coef->_compress_data) (cinfo, main_ptr->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
|
||||
|
|
@ -128,11 +133,15 @@ process_data_simple_main(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_c_main_controller(j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
_jinit_c_main_controller(j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_main_ptr main_ptr;
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
main_ptr = (my_main_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
|
|
@ -153,10 +162,12 @@ jinit_c_main_controller(j_compress_ptr cinfo, boolean need_full_buffer)
|
|||
/* Allocate a strip buffer for each component */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
main_ptr->buffer[ci] = (*cinfo->mem->alloc_sarray)
|
||||
main_ptr->buffer[ci] = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
compptr->width_in_blocks * DCTSIZE,
|
||||
(JDIMENSION)(compptr->v_samp_factor * DCTSIZE));
|
||||
compptr->width_in_blocks * data_unit,
|
||||
(JDIMENSION)(compptr->v_samp_factor * data_unit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modified 2003-2010 by Guido Vollbeding.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, D. R. Commander.
|
||||
* Copyright (C) 2010, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -15,7 +17,7 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jpegcomp.h"
|
||||
#include "jpegapicomp.h"
|
||||
|
||||
|
||||
typedef enum { /* JPEG marker codes */
|
||||
|
|
@ -497,25 +499,26 @@ write_file_header(j_compress_ptr cinfo)
|
|||
METHODDEF(void)
|
||||
write_frame_header(j_compress_ptr cinfo)
|
||||
{
|
||||
int ci, prec;
|
||||
int ci, prec = 0;
|
||||
boolean is_baseline;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Emit DQT for each quantization table.
|
||||
* Note that emit_dqt() suppresses any duplicate tables.
|
||||
*/
|
||||
prec = 0;
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
prec += emit_dqt(cinfo, compptr->quant_tbl_no);
|
||||
if (!cinfo->master->lossless) {
|
||||
/* Emit DQT for each quantization table.
|
||||
* Note that emit_dqt() suppresses any duplicate tables.
|
||||
*/
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
prec += emit_dqt(cinfo, compptr->quant_tbl_no);
|
||||
}
|
||||
/* now prec is nonzero iff there are any 16-bit quant tables. */
|
||||
}
|
||||
/* now prec is nonzero iff there are any 16-bit quant tables. */
|
||||
|
||||
/* Check for a non-baseline specification.
|
||||
* Note we assume that Huffman table numbers won't be changed later.
|
||||
*/
|
||||
if (cinfo->arith_code || cinfo->progressive_mode ||
|
||||
cinfo->data_precision != 8) {
|
||||
cinfo->master->lossless || cinfo->data_precision != 8) {
|
||||
is_baseline = FALSE;
|
||||
} else {
|
||||
is_baseline = TRUE;
|
||||
|
|
@ -540,6 +543,8 @@ write_frame_header(j_compress_ptr cinfo)
|
|||
} else {
|
||||
if (cinfo->progressive_mode)
|
||||
emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */
|
||||
else if (cinfo->master->lossless)
|
||||
emit_sof(cinfo, M_SOF3); /* SOF code for lossless Huffman */
|
||||
else if (is_baseline)
|
||||
emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */
|
||||
else
|
||||
|
|
@ -574,10 +579,11 @@ write_scan_header(j_compress_ptr cinfo)
|
|||
for (i = 0; i < cinfo->comps_in_scan; i++) {
|
||||
compptr = cinfo->cur_comp_info[i];
|
||||
/* DC needs no table for refinement scan */
|
||||
if (cinfo->Ss == 0 && cinfo->Ah == 0)
|
||||
if ((cinfo->Ss == 0 && cinfo->Ah == 0) || cinfo->master->lossless)
|
||||
emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
|
||||
/* AC needs no table when not present */
|
||||
if (cinfo->Se)
|
||||
/* AC needs no table when not present, and lossless mode uses only DC
|
||||
tables. */
|
||||
if (cinfo->Se && !cinfo->master->lossless)
|
||||
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2003-2010 by Guido Vollbeding.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2016, 2018, D. R. Commander.
|
||||
* Copyright (C) 2010, 2016, 2018, 2022-2023, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -18,39 +20,8 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jpegcomp.h"
|
||||
|
||||
|
||||
/* Private state */
|
||||
|
||||
typedef enum {
|
||||
main_pass, /* input data, also do first output step */
|
||||
huff_opt_pass, /* Huffman code optimization pass */
|
||||
output_pass /* data output pass */
|
||||
} c_pass_type;
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_comp_master pub; /* public fields */
|
||||
|
||||
c_pass_type pass_type; /* the type of the current pass */
|
||||
|
||||
int pass_number; /* # of passes completed */
|
||||
int total_passes; /* total # of passes needed */
|
||||
|
||||
int scan_number; /* current index in scan_info[] */
|
||||
|
||||
/*
|
||||
* This is here so we can add libjpeg-turbo version/build information to the
|
||||
* global string table without introducing a new global symbol. Adding this
|
||||
* information to the global string table allows one to examine a binary
|
||||
* object and determine which version of libjpeg-turbo it was built from or
|
||||
* linked against.
|
||||
*/
|
||||
const char *jpeg_version;
|
||||
|
||||
} my_comp_master;
|
||||
|
||||
typedef my_comp_master *my_master_ptr;
|
||||
#include "jpegapicomp.h"
|
||||
#include "jcmaster.h"
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -68,11 +39,13 @@ GLOBAL(void)
|
|||
jpeg_calc_jpeg_dimensions(j_compress_ptr cinfo)
|
||||
/* Do computations that are needed before master selection phase */
|
||||
{
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
|
||||
/* Hardwire it to "no scaling" */
|
||||
cinfo->jpeg_width = cinfo->image_width;
|
||||
cinfo->jpeg_height = cinfo->image_height;
|
||||
cinfo->min_DCT_h_scaled_size = DCTSIZE;
|
||||
cinfo->min_DCT_v_scaled_size = DCTSIZE;
|
||||
cinfo->min_DCT_h_scaled_size = data_unit;
|
||||
cinfo->min_DCT_v_scaled_size = data_unit;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -85,6 +58,7 @@ initial_setup(j_compress_ptr cinfo, boolean transcode_only)
|
|||
jpeg_component_info *compptr;
|
||||
long samplesperrow;
|
||||
JDIMENSION jd_samplesperrow;
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
#if JPEG_LIB_VERSION >= 80
|
||||
|
|
@ -109,8 +83,12 @@ initial_setup(j_compress_ptr cinfo, boolean transcode_only)
|
|||
if ((long)jd_samplesperrow != samplesperrow)
|
||||
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
|
||||
|
||||
/* For now, precision must match compiled-in value... */
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
if (cinfo->data_precision != 8 && cinfo->data_precision != 12 &&
|
||||
cinfo->data_precision != 16)
|
||||
#else
|
||||
if (cinfo->data_precision != 8 && cinfo->data_precision != 12)
|
||||
#endif
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
/* Check that number of components won't exceed internal array sizes */
|
||||
|
|
@ -141,17 +119,17 @@ initial_setup(j_compress_ptr cinfo, boolean transcode_only)
|
|||
compptr->component_index = ci;
|
||||
/* For compression, we never do DCT scaling. */
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = DCTSIZE;
|
||||
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = data_unit;
|
||||
#else
|
||||
compptr->DCT_scaled_size = DCTSIZE;
|
||||
compptr->DCT_scaled_size = data_unit;
|
||||
#endif
|
||||
/* Size in DCT blocks */
|
||||
/* Size in data units */
|
||||
compptr->width_in_blocks = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->_jpeg_width * (long)compptr->h_samp_factor,
|
||||
(long)(cinfo->max_h_samp_factor * DCTSIZE));
|
||||
(long)(cinfo->max_h_samp_factor * data_unit));
|
||||
compptr->height_in_blocks = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->_jpeg_height * (long)compptr->v_samp_factor,
|
||||
(long)(cinfo->max_v_samp_factor * DCTSIZE));
|
||||
(long)(cinfo->max_v_samp_factor * data_unit));
|
||||
/* Size in samples */
|
||||
compptr->downsampled_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->_jpeg_width * (long)compptr->h_samp_factor,
|
||||
|
|
@ -164,15 +142,19 @@ initial_setup(j_compress_ptr cinfo, boolean transcode_only)
|
|||
}
|
||||
|
||||
/* Compute number of fully interleaved MCU rows (number of times that
|
||||
* main controller will call coefficient controller).
|
||||
* main controller will call coefficient or difference controller).
|
||||
*/
|
||||
cinfo->total_iMCU_rows = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->_jpeg_height,
|
||||
(long)(cinfo->max_v_samp_factor * DCTSIZE));
|
||||
(long)(cinfo->max_v_samp_factor * data_unit));
|
||||
}
|
||||
|
||||
|
||||
#ifdef C_MULTISCAN_FILES_SUPPORTED
|
||||
#if defined(C_MULTISCAN_FILES_SUPPORTED) || defined(C_LOSSLESS_SUPPORTED)
|
||||
#define NEED_SCAN_SCRIPT
|
||||
#endif
|
||||
|
||||
#ifdef NEED_SCAN_SCRIPT
|
||||
|
||||
LOCAL(void)
|
||||
validate_script(j_compress_ptr cinfo)
|
||||
|
|
@ -193,13 +175,29 @@ validate_script(j_compress_ptr cinfo)
|
|||
if (cinfo->num_scans <= 0)
|
||||
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0);
|
||||
|
||||
#ifndef C_MULTISCAN_FILES_SUPPORTED
|
||||
if (cinfo->num_scans > 1)
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
|
||||
scanptr = cinfo->scan_info;
|
||||
if (scanptr->Ss != 0 && scanptr->Se == 0) {
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
cinfo->master->lossless = TRUE;
|
||||
cinfo->progressive_mode = FALSE;
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
component_sent[ci] = FALSE;
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
}
|
||||
/* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1;
|
||||
* for progressive JPEG, no scan can have this.
|
||||
*/
|
||||
scanptr = cinfo->scan_info;
|
||||
if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2 - 1) {
|
||||
else if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2 - 1) {
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
cinfo->progressive_mode = TRUE;
|
||||
cinfo->master->lossless = FALSE;
|
||||
last_bitpos_ptr = &last_bitpos[0][0];
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
for (coefi = 0; coefi < DCTSIZE2; coefi++)
|
||||
|
|
@ -208,7 +206,7 @@ validate_script(j_compress_ptr cinfo)
|
|||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else {
|
||||
cinfo->progressive_mode = FALSE;
|
||||
cinfo->progressive_mode = cinfo->master->lossless = FALSE;
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
component_sent[ci] = FALSE;
|
||||
}
|
||||
|
|
@ -240,13 +238,10 @@ validate_script(j_compress_ptr cinfo)
|
|||
* out-of-range reconstructed DC values during the first DC scan,
|
||||
* which might cause problems for some decoders.
|
||||
*/
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define MAX_AH_AL 10
|
||||
#else
|
||||
#define MAX_AH_AL 13
|
||||
#endif
|
||||
int max_Ah_Al = cinfo->data_precision == 12 ? 13 : 10;
|
||||
|
||||
if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 ||
|
||||
Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
|
||||
Ah < 0 || Ah > max_Ah_Al || Al < 0 || Al > max_Ah_Al)
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
if (Ss == 0) {
|
||||
if (Se != 0) /* DC and AC together not OK */
|
||||
|
|
@ -274,9 +269,25 @@ validate_script(j_compress_ptr cinfo)
|
|||
}
|
||||
#endif
|
||||
} else {
|
||||
/* For sequential JPEG, all progression parameters must be these: */
|
||||
if (Ss != 0 || Se != DCTSIZE2 - 1 || Ah != 0 || Al != 0)
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
if (cinfo->master->lossless) {
|
||||
/* The JPEG spec simply gives the range 0..15 for Al (Pt), but that
|
||||
* seems wrong: the upper bound ought to depend on data precision.
|
||||
* Perhaps they really meant 0..N-1 for N-bit precision, which is what
|
||||
* we allow here. Values greater than or equal to the data precision
|
||||
* will result in a blank image.
|
||||
*/
|
||||
if (Ss < 1 || Ss > 7 || /* predictor selection value */
|
||||
Se != 0 || Ah != 0 ||
|
||||
Al < 0 || Al >= cinfo->data_precision) /* point transform */
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* For sequential JPEG, all progression parameters must be these: */
|
||||
if (Ss != 0 || Se != DCTSIZE2 - 1 || Ah != 0 || Al != 0)
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
}
|
||||
/* Make sure components are not sent twice */
|
||||
for (ci = 0; ci < ncomps; ci++) {
|
||||
thisi = scanptr->component_index[ci];
|
||||
|
|
@ -308,7 +319,7 @@ validate_script(j_compress_ptr cinfo)
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* C_MULTISCAN_FILES_SUPPORTED */
|
||||
#endif /* NEED_SCAN_SCRIPT */
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
|
|
@ -317,7 +328,7 @@ select_scan_parameters(j_compress_ptr cinfo)
|
|||
{
|
||||
int ci;
|
||||
|
||||
#ifdef C_MULTISCAN_FILES_SUPPORTED
|
||||
#ifdef NEED_SCAN_SCRIPT
|
||||
if (cinfo->scan_info != NULL) {
|
||||
/* Prepare for current scan --- the script is already validated */
|
||||
my_master_ptr master = (my_master_ptr)cinfo->master;
|
||||
|
|
@ -343,10 +354,12 @@ select_scan_parameters(j_compress_ptr cinfo)
|
|||
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||
cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
|
||||
}
|
||||
cinfo->Ss = 0;
|
||||
cinfo->Se = DCTSIZE2 - 1;
|
||||
cinfo->Ah = 0;
|
||||
cinfo->Al = 0;
|
||||
if (!cinfo->master->lossless) {
|
||||
cinfo->Ss = 0;
|
||||
cinfo->Se = DCTSIZE2 - 1;
|
||||
cinfo->Ah = 0;
|
||||
cinfo->Al = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -358,6 +371,7 @@ per_scan_setup(j_compress_ptr cinfo)
|
|||
{
|
||||
int ci, mcublks, tmp;
|
||||
jpeg_component_info *compptr;
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
|
||||
if (cinfo->comps_in_scan == 1) {
|
||||
|
||||
|
|
@ -372,7 +386,7 @@ per_scan_setup(j_compress_ptr cinfo)
|
|||
compptr->MCU_width = 1;
|
||||
compptr->MCU_height = 1;
|
||||
compptr->MCU_blocks = 1;
|
||||
compptr->MCU_sample_width = DCTSIZE;
|
||||
compptr->MCU_sample_width = data_unit;
|
||||
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.
|
||||
|
|
@ -395,10 +409,10 @@ per_scan_setup(j_compress_ptr cinfo)
|
|||
/* Overall image size in MCUs */
|
||||
cinfo->MCUs_per_row = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->_jpeg_width,
|
||||
(long)(cinfo->max_h_samp_factor * DCTSIZE));
|
||||
(long)(cinfo->max_h_samp_factor * data_unit));
|
||||
cinfo->MCU_rows_in_scan = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->_jpeg_height,
|
||||
(long)(cinfo->max_v_samp_factor * DCTSIZE));
|
||||
(long)(cinfo->max_v_samp_factor * data_unit));
|
||||
|
||||
cinfo->blocks_in_MCU = 0;
|
||||
|
||||
|
|
@ -408,7 +422,7 @@ per_scan_setup(j_compress_ptr cinfo)
|
|||
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 * DCTSIZE;
|
||||
compptr->MCU_sample_width = compptr->MCU_width * data_unit;
|
||||
/* 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;
|
||||
|
|
@ -480,7 +494,8 @@ prepare_for_pass(j_compress_ptr cinfo)
|
|||
/* Do Huffman optimization for a scan after the first one. */
|
||||
select_scan_parameters(cinfo);
|
||||
per_scan_setup(cinfo);
|
||||
if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) {
|
||||
if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code ||
|
||||
cinfo->master->lossless) {
|
||||
(*cinfo->entropy->start_pass) (cinfo, TRUE);
|
||||
(*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
|
||||
master->pub.call_pass_startup = FALSE;
|
||||
|
|
@ -589,22 +604,15 @@ finish_pass_master(j_compress_ptr cinfo)
|
|||
GLOBAL(void)
|
||||
jinit_c_master_control(j_compress_ptr cinfo, boolean transcode_only)
|
||||
{
|
||||
my_master_ptr master;
|
||||
my_master_ptr master = (my_master_ptr)cinfo->master;
|
||||
|
||||
master = (my_master_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_comp_master));
|
||||
cinfo->master = (struct jpeg_comp_master *)master;
|
||||
master->pub.prepare_for_pass = prepare_for_pass;
|
||||
master->pub.pass_startup = pass_startup;
|
||||
master->pub.finish_pass = finish_pass_master;
|
||||
master->pub.is_last_pass = FALSE;
|
||||
|
||||
/* Validate parameters, determine derived values */
|
||||
initial_setup(cinfo, transcode_only);
|
||||
|
||||
if (cinfo->scan_info != NULL) {
|
||||
#ifdef C_MULTISCAN_FILES_SUPPORTED
|
||||
#ifdef NEED_SCAN_SCRIPT
|
||||
validate_script(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
|
|
@ -614,8 +622,33 @@ jinit_c_master_control(j_compress_ptr cinfo, boolean transcode_only)
|
|||
cinfo->num_scans = 1;
|
||||
}
|
||||
|
||||
if (cinfo->progressive_mode && !cinfo->arith_code) /* TEMPORARY HACK ??? */
|
||||
cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */
|
||||
/* Disable smoothing and subsampling in lossless mode, since those are lossy
|
||||
* algorithms. Set the JPEG colorspace to the input colorspace. Disable raw
|
||||
* (downsampled) data input, because it isn't particularly useful without
|
||||
* subsampling and has not been tested in lossless mode.
|
||||
*/
|
||||
if (cinfo->master->lossless) {
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
cinfo->raw_data_in = FALSE;
|
||||
cinfo->smoothing_factor = 0;
|
||||
jpeg_default_colorspace(cinfo);
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++)
|
||||
compptr->h_samp_factor = compptr->v_samp_factor = 1;
|
||||
}
|
||||
|
||||
/* Validate parameters, determine derived values */
|
||||
initial_setup(cinfo, transcode_only);
|
||||
|
||||
if (cinfo->master->lossless || /* TEMPORARY HACK ??? */
|
||||
(cinfo->progressive_mode && !cinfo->arith_code))
|
||||
cinfo->optimize_coding = TRUE; /* assume default tables no good for
|
||||
progressive mode or lossless mode */
|
||||
if (cinfo->data_precision == 12 && !cinfo->arith_code)
|
||||
cinfo->optimize_coding = TRUE; /* assume default tables no good for 12-bit
|
||||
data precision */
|
||||
|
||||
/* Initialize my private state */
|
||||
if (transcode_only) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* jcmaster.h
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1995, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2016, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file contains master control structure for the JPEG compressor.
|
||||
*/
|
||||
|
||||
/* Private state */
|
||||
|
||||
typedef enum {
|
||||
main_pass, /* input data, also do first output step */
|
||||
huff_opt_pass, /* Huffman code optimization pass */
|
||||
output_pass /* data output pass */
|
||||
} c_pass_type;
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_comp_master pub; /* public fields */
|
||||
|
||||
c_pass_type pass_type; /* the type of the current pass */
|
||||
|
||||
int pass_number; /* # of passes completed */
|
||||
int total_passes; /* total # of passes needed */
|
||||
|
||||
int scan_number; /* current index in scan_info[] */
|
||||
|
||||
/*
|
||||
* This is here so we can add libjpeg-turbo version/build information to the
|
||||
* global string table without introducing a new global symbol. Adding this
|
||||
* information to the global string table allows one to examine a binary
|
||||
* object and determine which version of libjpeg-turbo it was built from or
|
||||
* linked against.
|
||||
*/
|
||||
const char *jpeg_version;
|
||||
|
||||
} my_comp_master;
|
||||
|
||||
typedef my_comp_master *my_master_ptr;
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
#define JPEG_LIB_VERSION 80
|
||||
|
||||
#define LIBJPEG_TURBO_VERSION 2.1.5
|
||||
#define LIBJPEG_TURBO_VERSION 3.0.0
|
||||
|
||||
#define LIBJPEG_TURBO_VERSION_NUMBER 2001005
|
||||
#define LIBJPEG_TURBO_VERSION_NUMBER 3000000
|
||||
|
||||
#define C_ARITH_CODING_SUPPORTED 1
|
||||
|
||||
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#define MEM_SRCDST_SUPPORTED 1
|
||||
|
||||
#define BITS_IN_JSAMPLE 8
|
||||
#ifndef BITS_IN_JSAMPLE
|
||||
#define BITS_IN_JSAMPLE 8
|
||||
#endif
|
||||
|
||||
#define NO_PUTENV
|
||||
|
|
|
|||
|
|
@ -9,29 +9,52 @@
|
|||
/* libjpeg-turbo version in integer form */
|
||||
#define LIBJPEG_TURBO_VERSION_NUMBER @LIBJPEG_TURBO_VERSION_NUMBER@
|
||||
|
||||
/* Support arithmetic encoding */
|
||||
/* Support arithmetic encoding when using 8-bit samples */
|
||||
#cmakedefine C_ARITH_CODING_SUPPORTED 1
|
||||
|
||||
/* Support arithmetic decoding */
|
||||
/* Support arithmetic decoding when using 8-bit samples */
|
||||
#cmakedefine D_ARITH_CODING_SUPPORTED 1
|
||||
|
||||
/* Support in-memory source/destination managers */
|
||||
#cmakedefine MEM_SRCDST_SUPPORTED 1
|
||||
#define MEM_SRCDST_SUPPORTED 1
|
||||
|
||||
/* Use accelerated SIMD routines. */
|
||||
/* Use accelerated SIMD routines when using 8-bit samples */
|
||||
#cmakedefine WITH_SIMD 1
|
||||
|
||||
/*
|
||||
* 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.
|
||||
/* This version of libjpeg-turbo supports run-time selection of data precision,
|
||||
* so BITS_IN_JSAMPLE is no longer used to specify the data precision at build
|
||||
* time. However, some downstream software expects the macro to be defined.
|
||||
* Since 12-bit data precision is an opt-in feature that requires explicitly
|
||||
* calling 12-bit-specific libjpeg API functions and using 12-bit-specific data
|
||||
* types, the unmodified portion of the libjpeg API still behaves as if it were
|
||||
* built for 8-bit precision, and JSAMPLE is still literally an 8-bit data
|
||||
* type. Thus, it is correct to define BITS_IN_JSAMPLE to 8 here.
|
||||
*/
|
||||
#ifndef BITS_IN_JSAMPLE
|
||||
#define BITS_IN_JSAMPLE 8
|
||||
#endif
|
||||
|
||||
#define BITS_IN_JSAMPLE @BITS_IN_JSAMPLE@ /* use 8 or 12 */
|
||||
#ifdef _WIN32
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
/* 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 */
|
||||
|
||||
/* Define "INT32" as int, not long, per Windows custom */
|
||||
#if !(defined(_BASETSD_H_) || defined(_BASETSD_H)) /* don't conflict if basetsd.h already read */
|
||||
typedef short INT16;
|
||||
typedef signed int INT32;
|
||||
#endif
|
||||
#define XMD_H /* prevent jmorecfg.h from redefining it */
|
||||
|
||||
#else
|
||||
|
||||
/* Define if your (broken) compiler shifts signed values as if they were
|
||||
unsigned. */
|
||||
#cmakedefine RIGHT_SHIFT_IS_UNSIGNED 1
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#define PACKAGE_NAME "libjpeg-turbo"
|
||||
|
||||
#define VERSION "2.1.5"
|
||||
#define VERSION "3.0.0"
|
||||
|
||||
#if SIZE_MAX == 0xffffffff
|
||||
#define SIZEOF_SIZE_T 4
|
||||
|
|
@ -16,4 +16,33 @@
|
|||
#define SIZEOF_SIZE_T 8
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(HAVE_INTRIN_H)
|
||||
#if (SIZEOF_SIZE_T == 8)
|
||||
#define HAVE_BITSCANFORWARD64
|
||||
#elif (SIZEOF_SIZE_T == 4)
|
||||
#define HAVE_BITSCANFORWARD
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define FALLTHROUGH
|
||||
|
||||
#ifndef BITS_IN_JSAMPLE
|
||||
#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */
|
||||
#endif
|
||||
|
||||
#undef C_ARITH_CODING_SUPPORTED
|
||||
#undef D_ARITH_CODING_SUPPORTED
|
||||
#undef WITH_SIMD
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
|
||||
/* Support arithmetic encoding */
|
||||
#define C_ARITH_CODING_SUPPORTED 1
|
||||
|
||||
/* Support arithmetic decoding */
|
||||
#define D_ARITH_CODING_SUPPORTED 1
|
||||
|
||||
/* Use accelerated SIMD routines. */
|
||||
/* #undef WITH_SIMD */
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -42,3 +42,32 @@
|
|||
#else
|
||||
#define FALLTHROUGH
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
#ifndef BITS_IN_JSAMPLE
|
||||
#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */
|
||||
#endif
|
||||
|
||||
#undef C_ARITH_CODING_SUPPORTED
|
||||
#undef D_ARITH_CODING_SUPPORTED
|
||||
#undef WITH_SIMD
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
|
||||
/* Support arithmetic encoding */
|
||||
#cmakedefine C_ARITH_CODING_SUPPORTED 1
|
||||
|
||||
/* Support arithmetic decoding */
|
||||
#cmakedefine D_ARITH_CODING_SUPPORTED 1
|
||||
|
||||
/* Use accelerated SIMD routines. */
|
||||
#cmakedefine WITH_SIMD 1
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modified 2003-2008 by Guido Vollbeding.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009-2011, 2018, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2018, 2023, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -202,7 +204,6 @@ jpeg_set_defaults(j_compress_ptr cinfo)
|
|||
cinfo->scale_num = 1; /* 1:1 scaling */
|
||||
cinfo->scale_denom = 1;
|
||||
#endif
|
||||
cinfo->data_precision = BITS_IN_JSAMPLE;
|
||||
/* Set up two quantization tables using default quality of 75 */
|
||||
jpeg_set_quality(cinfo, 75, TRUE);
|
||||
/* Set up two Huffman tables */
|
||||
|
|
@ -232,7 +233,7 @@ jpeg_set_defaults(j_compress_ptr cinfo)
|
|||
* tables will be computed. This test can be removed if default tables
|
||||
* are supplied that are valid for the desired precision.
|
||||
*/
|
||||
if (cinfo->data_precision > 8)
|
||||
if (cinfo->data_precision == 12 && !cinfo->arith_code)
|
||||
cinfo->optimize_coding = TRUE;
|
||||
|
||||
/* By default, use the simpler non-cosited sampling alignment */
|
||||
|
|
@ -296,7 +297,10 @@ jpeg_default_colorspace(j_compress_ptr cinfo)
|
|||
case JCS_EXT_BGRA:
|
||||
case JCS_EXT_ABGR:
|
||||
case JCS_EXT_ARGB:
|
||||
jpeg_set_colorspace(cinfo, JCS_YCbCr);
|
||||
if (cinfo->master->lossless)
|
||||
jpeg_set_colorspace(cinfo, JCS_RGB);
|
||||
else
|
||||
jpeg_set_colorspace(cinfo, JCS_YCbCr);
|
||||
break;
|
||||
case JCS_YCbCr:
|
||||
jpeg_set_colorspace(cinfo, JCS_YCbCr);
|
||||
|
|
@ -475,6 +479,11 @@ jpeg_simple_progression(j_compress_ptr cinfo)
|
|||
if (cinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
if (cinfo->master->lossless) {
|
||||
cinfo->master->lossless = FALSE;
|
||||
jpeg_default_colorspace(cinfo);
|
||||
}
|
||||
|
||||
/* Figure space needed for script. Calculation must match code below! */
|
||||
if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
|
||||
/* Custom script for YCbCr color images. */
|
||||
|
|
@ -539,3 +548,38 @@ jpeg_simple_progression(j_compress_ptr cinfo)
|
|||
}
|
||||
|
||||
#endif /* C_PROGRESSIVE_SUPPORTED */
|
||||
|
||||
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
|
||||
/*
|
||||
* Enable lossless mode.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_enable_lossless(j_compress_ptr cinfo, int predictor_selection_value,
|
||||
int point_transform)
|
||||
{
|
||||
/* Safety check to ensure start_compress not called yet. */
|
||||
if (cinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
cinfo->master->lossless = TRUE;
|
||||
cinfo->Ss = predictor_selection_value;
|
||||
cinfo->Se = 0;
|
||||
cinfo->Ah = 0;
|
||||
cinfo->Al = point_transform;
|
||||
|
||||
/* The JPEG spec simply gives the range 0..15 for Al (Pt), but that seems
|
||||
* wrong: the upper bound ought to depend on data precision. Perhaps they
|
||||
* really meant 0..N-1 for N-bit precision, which is what we allow here.
|
||||
* Values greater than or equal to the data precision will result in a blank
|
||||
* image.
|
||||
*/
|
||||
if (cinfo->Ss < 1 || cinfo->Ss > 7 ||
|
||||
cinfo->Al < 0 || cinfo->Al >= cinfo->data_precision)
|
||||
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
|
||||
cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
|
||||
}
|
||||
|
||||
#endif /* C_LOSSLESS_SUPPORTED */
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1995-1997, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2011, 2015, 2018, 2021-2022, D. R. Commander.
|
||||
* Copyright (C) 2016, 2018, 2022, Matthieu Darbois.
|
||||
|
|
@ -21,7 +23,11 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#ifdef WITH_SIMD
|
||||
#include "jsimd.h"
|
||||
#else
|
||||
#include "jchuff.h" /* Declarations shared with jc*huff.c */
|
||||
#endif
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef HAVE_INTRIN_H
|
||||
|
|
@ -223,18 +229,22 @@ start_pass_phuff(j_compress_ptr cinfo, boolean gather_statistics)
|
|||
entropy->pub.encode_mcu = encode_mcu_DC_first;
|
||||
else
|
||||
entropy->pub.encode_mcu = encode_mcu_AC_first;
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_encode_mcu_AC_first_prepare())
|
||||
entropy->AC_first_prepare = jsimd_encode_mcu_AC_first_prepare;
|
||||
else
|
||||
#endif
|
||||
entropy->AC_first_prepare = encode_mcu_AC_first_prepare;
|
||||
} else {
|
||||
if (is_DC_band)
|
||||
entropy->pub.encode_mcu = encode_mcu_DC_refine;
|
||||
else {
|
||||
entropy->pub.encode_mcu = encode_mcu_AC_refine;
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_encode_mcu_AC_refine_prepare())
|
||||
entropy->AC_refine_prepare = jsimd_encode_mcu_AC_refine_prepare;
|
||||
else
|
||||
#endif
|
||||
entropy->AC_refine_prepare = encode_mcu_AC_refine_prepare;
|
||||
/* AC refinement needs a correction bit buffer */
|
||||
if (entropy->bit_buffer == NULL)
|
||||
|
|
@ -489,6 +499,7 @@ encode_mcu_DC_first(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
|||
JBLOCKROW block;
|
||||
jpeg_component_info *compptr;
|
||||
ISHIFT_TEMPS
|
||||
int max_coef_bits = cinfo->data_precision + 2;
|
||||
|
||||
entropy->next_output_byte = cinfo->dest->next_output_byte;
|
||||
entropy->free_in_buffer = cinfo->dest->free_in_buffer;
|
||||
|
|
@ -531,7 +542,7 @@ encode_mcu_DC_first(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
|||
/* Check for out-of-range coefficient values.
|
||||
* Since we're encoding a difference, the range limit is twice as much.
|
||||
*/
|
||||
if (nbits > MAX_COEF_BITS + 1)
|
||||
if (nbits > max_coef_bits + 1)
|
||||
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
|
||||
|
||||
/* Count/emit the Huffman-coded symbol for the number of bits */
|
||||
|
|
@ -642,7 +653,7 @@ label \
|
|||
/* Find the number of bits needed for the magnitude of the coefficient */ \
|
||||
nbits = JPEG_NBITS_NONZERO(temp); /* there must be at least one 1 bit */ \
|
||||
/* Check for out-of-range coefficient values */ \
|
||||
if (nbits > MAX_COEF_BITS) \
|
||||
if (nbits > max_coef_bits) \
|
||||
ERREXIT(cinfo, JERR_BAD_DCT_COEF); \
|
||||
\
|
||||
/* Count/emit Huffman symbol for run length / number of bits */ \
|
||||
|
|
@ -670,6 +681,7 @@ encode_mcu_AC_first(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
|||
const UJCOEF *cvalue;
|
||||
size_t zerobits;
|
||||
size_t bits[8 / SIZEOF_SIZE_T];
|
||||
int max_coef_bits = cinfo->data_precision + 2;
|
||||
|
||||
entropy->next_output_byte = cinfo->dest->next_output_byte;
|
||||
entropy->free_in_buffer = cinfo->dest->free_in_buffer;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* jcprepct.c
|
||||
*
|
||||
* This file is part of the Independent JPEG Group's software:
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
|
|
@ -20,8 +22,11 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
|
||||
|
||||
/* 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
|
||||
|
|
@ -59,7 +64,7 @@ typedef struct {
|
|||
/* Downsampling input buffer. This buffer holds color-converted data
|
||||
* until we have enough to do a downsample step.
|
||||
*/
|
||||
JSAMPARRAY color_buf[MAX_COMPONENTS];
|
||||
_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 */
|
||||
|
|
@ -106,14 +111,14 @@ start_pass_prep(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
|
|||
*/
|
||||
|
||||
LOCAL(void)
|
||||
expand_bottom_edge(JSAMPARRAY image_data, JDIMENSION num_cols, int input_rows,
|
||||
expand_bottom_edge(_JSAMPARRAY image_data, JDIMENSION num_cols, int input_rows,
|
||||
int output_rows)
|
||||
{
|
||||
register int row;
|
||||
|
||||
for (row = input_rows; row < output_rows; row++) {
|
||||
jcopy_sample_rows(image_data, input_rows - 1, image_data, row, 1,
|
||||
num_cols);
|
||||
_jcopy_sample_rows(image_data, input_rows - 1, image_data, row, 1,
|
||||
num_cols);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -128,15 +133,16 @@ expand_bottom_edge(JSAMPARRAY image_data, JDIMENSION num_cols, int input_rows,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
pre_process_data(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
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,
|
||||
_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;
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
|
||||
while (*in_row_ctr < in_rows_avail &&
|
||||
*out_row_group_ctr < out_row_groups_avail) {
|
||||
|
|
@ -144,10 +150,10 @@ pre_process_data(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
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);
|
||||
(*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;
|
||||
|
|
@ -162,9 +168,9 @@ pre_process_data(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
}
|
||||
/* 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);
|
||||
(*cinfo->downsample->_downsample) (cinfo,
|
||||
prep->color_buf, (JDIMENSION)0,
|
||||
output_buf, *out_row_group_ctr);
|
||||
prep->next_buf_row = 0;
|
||||
(*out_row_group_ctr)++;
|
||||
}
|
||||
|
|
@ -174,7 +180,8 @@ pre_process_data(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
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,
|
||||
expand_bottom_edge(output_buf[ci],
|
||||
compptr->width_in_blocks * data_unit,
|
||||
(int)(*out_row_group_ctr * compptr->v_samp_factor),
|
||||
(int)(out_row_groups_avail * compptr->v_samp_factor));
|
||||
}
|
||||
|
|
@ -192,9 +199,9 @@ pre_process_data(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
pre_process_context(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
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,
|
||||
_JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
|
||||
JDIMENSION out_row_groups_avail)
|
||||
{
|
||||
my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
|
||||
|
|
@ -208,17 +215,17 @@ pre_process_context(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
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);
|
||||
(*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);
|
||||
_jcopy_sample_rows(prep->color_buf[ci], 0, prep->color_buf[ci],
|
||||
-row, 1, cinfo->image_width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -240,9 +247,9 @@ pre_process_context(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
}
|
||||
/* 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);
|
||||
(*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;
|
||||
|
|
@ -267,15 +274,16 @@ create_context_buffer(j_compress_ptr cinfo)
|
|||
int rgroup_height = cinfo->max_v_samp_factor;
|
||||
int ci, i;
|
||||
jpeg_component_info *compptr;
|
||||
JSAMPARRAY true_buffer, fake_buffer;
|
||||
_JSAMPARRAY true_buffer, fake_buffer;
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
|
||||
/* 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)
|
||||
fake_buffer = (_JSAMPARRAY)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(cinfo->num_components * 5 * rgroup_height) *
|
||||
sizeof(JSAMPROW));
|
||||
sizeof(_JSAMPROW));
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
|
|
@ -283,14 +291,14 @@ create_context_buffer(j_compress_ptr cinfo)
|
|||
* 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)
|
||||
true_buffer = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION)(((long)compptr->width_in_blocks * DCTSIZE *
|
||||
(JDIMENSION)(((long)compptr->width_in_blocks * data_unit *
|
||||
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 */
|
||||
memcpy(fake_buffer + rgroup_height, true_buffer,
|
||||
3 * rgroup_height * sizeof(JSAMPROW));
|
||||
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];
|
||||
|
|
@ -309,11 +317,15 @@ create_context_buffer(j_compress_ptr cinfo)
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_c_prep_controller(j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
_jinit_c_prep_controller(j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_prep_ptr prep;
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
if (need_full_buffer) /* safety check */
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
|
|
@ -331,21 +343,23 @@ jinit_c_prep_controller(j_compress_ptr cinfo, boolean need_full_buffer)
|
|||
if (cinfo->downsample->need_context_rows) {
|
||||
/* Set up to provide context rows */
|
||||
#ifdef CONTEXT_ROWS_SUPPORTED
|
||||
prep->pub.pre_process_data = pre_process_context;
|
||||
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;
|
||||
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)
|
||||
prep->color_buf[ci] = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION)(((long)compptr->width_in_blocks * DCTSIZE *
|
||||
(JDIMENSION)(((long)compptr->width_in_blocks * data_unit *
|
||||
cinfo->max_h_samp_factor) / compptr->h_samp_factor),
|
||||
(JDIMENSION)cinfo->max_v_samp_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2014, MIPS Technologies, Inc., California.
|
||||
* Copyright (C) 2015, 2019, D. R. Commander.
|
||||
* Copyright (C) 2015, 2019, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -54,13 +56,16 @@
|
|||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsimd.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
|
||||
|
||||
/* Pointer to routine to downsample a single component */
|
||||
typedef void (*downsample1_ptr) (j_compress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data,
|
||||
JSAMPARRAY output_data);
|
||||
_JSAMPARRAY input_data,
|
||||
_JSAMPARRAY output_data);
|
||||
|
||||
/* Private subobject */
|
||||
|
||||
|
|
@ -91,11 +96,11 @@ start_pass_downsample(j_compress_ptr cinfo)
|
|||
*/
|
||||
|
||||
LOCAL(void)
|
||||
expand_right_edge(JSAMPARRAY image_data, int num_rows, JDIMENSION input_cols,
|
||||
expand_right_edge(_JSAMPARRAY image_data, int num_rows, JDIMENSION input_cols,
|
||||
JDIMENSION output_cols)
|
||||
{
|
||||
register JSAMPROW ptr;
|
||||
register JSAMPLE pixval;
|
||||
register _JSAMPROW ptr;
|
||||
register _JSAMPLE pixval;
|
||||
register int count;
|
||||
int row;
|
||||
int numcols = (int)(output_cols - input_cols);
|
||||
|
|
@ -118,14 +123,14 @@ expand_right_edge(JSAMPARRAY image_data, int num_rows, JDIMENSION input_cols,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
sep_downsample(j_compress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_index, JSAMPIMAGE output_buf,
|
||||
sep_downsample(j_compress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_index, _JSAMPIMAGE output_buf,
|
||||
JDIMENSION out_row_group_index)
|
||||
{
|
||||
my_downsample_ptr downsample = (my_downsample_ptr)cinfo->downsample;
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
JSAMPARRAY in_ptr, out_ptr;
|
||||
_JSAMPARRAY in_ptr, out_ptr;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
|
|
@ -145,12 +150,13 @@ sep_downsample(j_compress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
METHODDEF(void)
|
||||
int_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY output_data)
|
||||
{
|
||||
int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
|
||||
JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
|
||||
JSAMPROW inptr, outptr;
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * data_unit;
|
||||
_JSAMPROW inptr, outptr;
|
||||
JLONG outvalue;
|
||||
|
||||
h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
|
||||
|
|
@ -177,7 +183,7 @@ int_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
outvalue += (JLONG)(*inptr++);
|
||||
}
|
||||
}
|
||||
*outptr++ = (JSAMPLE)((outvalue + numpix2) / numpix);
|
||||
*outptr++ = (_JSAMPLE)((outvalue + numpix2) / numpix);
|
||||
}
|
||||
inrow += v_expand;
|
||||
}
|
||||
|
|
@ -192,14 +198,16 @@ int_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
|
||||
METHODDEF(void)
|
||||
fullsize_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY output_data)
|
||||
{
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
|
||||
/* Copy the data */
|
||||
jcopy_sample_rows(input_data, 0, output_data, 0, cinfo->max_v_samp_factor,
|
||||
cinfo->image_width);
|
||||
_jcopy_sample_rows(input_data, 0, output_data, 0, cinfo->max_v_samp_factor,
|
||||
cinfo->image_width);
|
||||
/* Edge-expand */
|
||||
expand_right_edge(output_data, cinfo->max_v_samp_factor, cinfo->image_width,
|
||||
compptr->width_in_blocks * DCTSIZE);
|
||||
compptr->width_in_blocks * data_unit);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -217,12 +225,13 @@ fullsize_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
|
||||
METHODDEF(void)
|
||||
h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY output_data)
|
||||
{
|
||||
int outrow;
|
||||
JDIMENSION outcol;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
|
||||
register JSAMPROW inptr, outptr;
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * data_unit;
|
||||
register _JSAMPROW inptr, outptr;
|
||||
register int bias;
|
||||
|
||||
/* Expand input data enough to let all the output samples be generated
|
||||
|
|
@ -237,7 +246,7 @@ h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
inptr = input_data[outrow];
|
||||
bias = 0; /* bias = 0,1,0,1,... for successive samples */
|
||||
for (outcol = 0; outcol < output_cols; outcol++) {
|
||||
*outptr++ = (JSAMPLE)((inptr[0] + inptr[1] + bias) >> 1);
|
||||
*outptr++ = (_JSAMPLE)((inptr[0] + inptr[1] + bias) >> 1);
|
||||
bias ^= 1; /* 0=>1, 1=>0 */
|
||||
inptr += 2;
|
||||
}
|
||||
|
|
@ -253,12 +262,13 @@ h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
|
||||
METHODDEF(void)
|
||||
h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY output_data)
|
||||
{
|
||||
int inrow, outrow;
|
||||
JDIMENSION outcol;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
|
||||
register JSAMPROW inptr0, inptr1, outptr;
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * data_unit;
|
||||
register _JSAMPROW inptr0, inptr1, outptr;
|
||||
register int bias;
|
||||
|
||||
/* Expand input data enough to let all the output samples be generated
|
||||
|
|
@ -275,8 +285,8 @@ h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
inptr1 = input_data[inrow + 1];
|
||||
bias = 1; /* bias = 1,2,1,2,... for successive samples */
|
||||
for (outcol = 0; outcol < output_cols; outcol++) {
|
||||
*outptr++ =
|
||||
(JSAMPLE)((inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1] + bias) >> 2);
|
||||
*outptr++ = (_JSAMPLE)
|
||||
((inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1] + bias) >> 2);
|
||||
bias ^= 3; /* 1=>2, 2=>1 */
|
||||
inptr0 += 2; inptr1 += 2;
|
||||
}
|
||||
|
|
@ -295,12 +305,13 @@ h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
|
||||
METHODDEF(void)
|
||||
h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY output_data)
|
||||
{
|
||||
int inrow, outrow;
|
||||
JDIMENSION colctr;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
|
||||
register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * data_unit;
|
||||
register _JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
|
||||
JLONG membersum, neighsum, memberscale, neighscale;
|
||||
|
||||
/* Expand input data enough to let all the output samples be generated
|
||||
|
|
@ -341,7 +352,7 @@ h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
neighsum += neighsum;
|
||||
neighsum += above_ptr[0] + above_ptr[2] + below_ptr[0] + below_ptr[2];
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
*outptr++ = (_JSAMPLE)((membersum + 32768) >> 16);
|
||||
inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
|
||||
|
||||
for (colctr = output_cols - 2; colctr > 0; colctr--) {
|
||||
|
|
@ -357,7 +368,7 @@ h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
/* form final output scaled up by 2^16 */
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
/* round, descale and output it */
|
||||
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
*outptr++ = (_JSAMPLE)((membersum + 32768) >> 16);
|
||||
inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
|
||||
}
|
||||
|
||||
|
|
@ -368,7 +379,7 @@ h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
neighsum += neighsum;
|
||||
neighsum += above_ptr[-1] + above_ptr[1] + below_ptr[-1] + below_ptr[1];
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
*outptr = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
*outptr = (_JSAMPLE)((membersum + 32768) >> 16);
|
||||
|
||||
inrow += 2;
|
||||
}
|
||||
|
|
@ -383,12 +394,13 @@ h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
|
||||
METHODDEF(void)
|
||||
fullsize_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY output_data)
|
||||
{
|
||||
int outrow;
|
||||
JDIMENSION colctr;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
|
||||
register JSAMPROW inptr, above_ptr, below_ptr, outptr;
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * data_unit;
|
||||
register _JSAMPROW inptr, above_ptr, below_ptr, outptr;
|
||||
JLONG membersum, neighsum, memberscale, neighscale;
|
||||
int colsum, lastcolsum, nextcolsum;
|
||||
|
||||
|
|
@ -420,7 +432,7 @@ fullsize_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
nextcolsum = above_ptr[0] + below_ptr[0] + inptr[0];
|
||||
neighsum = colsum + (colsum - membersum) + nextcolsum;
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
*outptr++ = (_JSAMPLE)((membersum + 32768) >> 16);
|
||||
lastcolsum = colsum; colsum = nextcolsum;
|
||||
|
||||
for (colctr = output_cols - 2; colctr > 0; colctr--) {
|
||||
|
|
@ -429,7 +441,7 @@ fullsize_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
nextcolsum = above_ptr[0] + below_ptr[0] + inptr[0];
|
||||
neighsum = lastcolsum + (colsum - membersum) + nextcolsum;
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
*outptr++ = (_JSAMPLE)((membersum + 32768) >> 16);
|
||||
lastcolsum = colsum; colsum = nextcolsum;
|
||||
}
|
||||
|
||||
|
|
@ -437,7 +449,7 @@ fullsize_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
membersum = *inptr;
|
||||
neighsum = lastcolsum + (colsum - membersum) + colsum;
|
||||
membersum = membersum * memberscale + neighsum * neighscale;
|
||||
*outptr = (JSAMPLE)((membersum + 32768) >> 16);
|
||||
*outptr = (_JSAMPLE)((membersum + 32768) >> 16);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -451,19 +463,22 @@ fullsize_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_downsampler(j_compress_ptr cinfo)
|
||||
_jinit_downsampler(j_compress_ptr cinfo)
|
||||
{
|
||||
my_downsample_ptr downsample;
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
boolean smoothok = TRUE;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
downsample = (my_downsample_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_downsampler));
|
||||
cinfo->downsample = (struct jpeg_downsampler *)downsample;
|
||||
downsample->pub.start_pass = start_pass_downsample;
|
||||
downsample->pub.downsample = sep_downsample;
|
||||
downsample->pub._downsample = sep_downsample;
|
||||
downsample->pub.need_context_rows = FALSE;
|
||||
|
||||
if (cinfo->CCIR601_sampling)
|
||||
|
|
@ -484,15 +499,17 @@ jinit_downsampler(j_compress_ptr cinfo)
|
|||
} else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
|
||||
compptr->v_samp_factor == cinfo->max_v_samp_factor) {
|
||||
smoothok = FALSE;
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_h2v1_downsample())
|
||||
downsample->methods[ci] = jsimd_h2v1_downsample;
|
||||
else
|
||||
#endif
|
||||
downsample->methods[ci] = h2v1_downsample;
|
||||
} else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
|
||||
compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
|
||||
#ifdef INPUT_SMOOTHING_SUPPORTED
|
||||
if (cinfo->smoothing_factor) {
|
||||
#if defined(__mips__)
|
||||
#if defined(WITH_SIMD) && defined(__mips__)
|
||||
if (jsimd_can_h2v2_smooth_downsample())
|
||||
downsample->methods[ci] = jsimd_h2v2_smooth_downsample;
|
||||
else
|
||||
|
|
@ -502,9 +519,11 @@ jinit_downsampler(j_compress_ptr cinfo)
|
|||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_h2v2_downsample())
|
||||
downsample->methods[ci] = jsimd_h2v2_downsample;
|
||||
else
|
||||
#endif
|
||||
downsample->methods[ci] = h2v2_downsample;
|
||||
}
|
||||
} else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
|
||||
|
|
@ -520,3 +539,5 @@ jinit_downsampler(j_compress_ptr cinfo)
|
|||
TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jpegcomp.h"
|
||||
#include "jpegapicomp.h"
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
|
|
@ -42,6 +42,9 @@ LOCAL(void) transencode_coef_controller(j_compress_ptr cinfo,
|
|||
GLOBAL(void)
|
||||
jpeg_write_coefficients(j_compress_ptr cinfo, jvirt_barray_ptr *coef_arrays)
|
||||
{
|
||||
if (cinfo->master->lossless)
|
||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
||||
|
||||
if (cinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
/* Mark all tables to be written */
|
||||
|
|
@ -72,6 +75,9 @@ jpeg_copy_critical_parameters(j_decompress_ptr srcinfo, j_compress_ptr dstinfo)
|
|||
JQUANT_TBL *c_quant, *slot_quant;
|
||||
int tblno, ci, coefi;
|
||||
|
||||
if (srcinfo->master->lossless)
|
||||
ERREXIT(dstinfo, JERR_NOTIMPL);
|
||||
|
||||
/* Safety check to ensure start_compress not called yet. */
|
||||
if (dstinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
|
||||
|
|
@ -364,6 +370,13 @@ compress_output(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
|||
}
|
||||
|
||||
|
||||
METHODDEF(boolean)
|
||||
compress_output_12(j_compress_ptr cinfo, J12SAMPIMAGE input_buf)
|
||||
{
|
||||
return compress_output(cinfo, (JSAMPIMAGE)input_buf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize coefficient buffer controller.
|
||||
*
|
||||
|
|
@ -386,6 +399,7 @@ transencode_coef_controller(j_compress_ptr cinfo,
|
|||
cinfo->coef = (struct jpeg_c_coef_controller *)coef;
|
||||
coef->pub.start_pass = start_pass_coef;
|
||||
coef->pub.compress_data = compress_output;
|
||||
coef->pub.compress_data_12 = compress_output_12;
|
||||
|
||||
/* Save pointer to virtual arrays */
|
||||
coef->whole_image = coef_arrays;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2016, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
|
|
@ -82,6 +84,8 @@ jpeg_CreateDecompress(j_decompress_ptr cinfo, int version, size_t structsize)
|
|||
/* And initialize the overall input controller. */
|
||||
jinit_input_controller(cinfo);
|
||||
|
||||
cinfo->data_precision = BITS_IN_JSAMPLE;
|
||||
|
||||
/* OK, I'm ready */
|
||||
cinfo->global_state = DSTATE_START;
|
||||
|
||||
|
|
@ -162,7 +166,10 @@ default_decompress_parms(j_decompress_ptr cinfo)
|
|||
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 */
|
||||
if (cinfo->master->lossless)
|
||||
cinfo->jpeg_color_space = JCS_RGB; /* assume it's RGB */
|
||||
else
|
||||
cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
|
||||
}
|
||||
}
|
||||
/* Always guess RGB is proper output colorspace. */
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2015-2020, 2022, D. R. Commander.
|
||||
* Copyright (C) 2010, 2015-2020, 2022-2023, D. R. Commander.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
|
|
@ -19,13 +19,20 @@
|
|||
*/
|
||||
|
||||
#include "jinclude.h"
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
|
||||
#include "jdmainct.h"
|
||||
#include "jdcoefct.h"
|
||||
#else
|
||||
#define JPEG_INTERNALS
|
||||
#include "jpeglib.h"
|
||||
#endif
|
||||
#include "jdmaster.h"
|
||||
#include "jdmerge.h"
|
||||
#include "jdsample.h"
|
||||
#include "jmemsys.h"
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
|
||||
/* Forward declarations */
|
||||
LOCAL(boolean) output_pass_setup(j_decompress_ptr cinfo);
|
||||
|
||||
|
|
@ -121,8 +128,20 @@ output_pass_setup(j_decompress_ptr cinfo)
|
|||
}
|
||||
/* Process some data */
|
||||
last_scanline = cinfo->output_scanline;
|
||||
(*cinfo->main->process_data) (cinfo, (JSAMPARRAY)NULL,
|
||||
&cinfo->output_scanline, (JDIMENSION)0);
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
if (cinfo->data_precision == 16)
|
||||
(*cinfo->main->process_data_16) (cinfo, (J16SAMPARRAY)NULL,
|
||||
&cinfo->output_scanline,
|
||||
(JDIMENSION)0);
|
||||
else
|
||||
#endif
|
||||
if (cinfo->data_precision == 12)
|
||||
(*cinfo->main->process_data_12) (cinfo, (J12SAMPARRAY)NULL,
|
||||
&cinfo->output_scanline,
|
||||
(JDIMENSION)0);
|
||||
else
|
||||
(*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 */
|
||||
}
|
||||
|
|
@ -135,25 +154,29 @@ output_pass_setup(j_decompress_ptr cinfo)
|
|||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
}
|
||||
/* Ready for application to drive output pass through
|
||||
* jpeg_read_scanlines or jpeg_read_raw_data.
|
||||
* _jpeg_read_scanlines or _jpeg_read_raw_data.
|
||||
*/
|
||||
cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 8 */
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
|
||||
/*
|
||||
* Enable partial scanline decompression
|
||||
*
|
||||
* Must be called after jpeg_start_decompress() and before any calls to
|
||||
* jpeg_read_scanlines() or jpeg_skip_scanlines().
|
||||
* _jpeg_read_scanlines() or _jpeg_skip_scanlines().
|
||||
*
|
||||
* Refer to libjpeg.txt for more information.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
|
||||
JDIMENSION *width)
|
||||
_jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
|
||||
JDIMENSION *width)
|
||||
{
|
||||
int ci, align, orig_downsampled_width;
|
||||
JDIMENSION input_xoffset;
|
||||
|
|
@ -163,6 +186,12 @@ jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
|
|||
my_master_ptr master = (my_master_ptr)cinfo->master;
|
||||
#endif
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
if (cinfo->master->lossless)
|
||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
||||
|
||||
if ((cinfo->global_state != DSTATE_SCANNING &&
|
||||
cinfo->global_state != DSTATE_BUFIMAGE) || cinfo->output_scanline != 0)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
|
@ -236,9 +265,11 @@ jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
|
|||
/* Set downsampled_width to the new output width. */
|
||||
orig_downsampled_width = compptr->downsampled_width;
|
||||
compptr->downsampled_width =
|
||||
(JDIMENSION)jdiv_round_up((long)(cinfo->output_width *
|
||||
compptr->h_samp_factor),
|
||||
(long)cinfo->max_h_samp_factor);
|
||||
(JDIMENSION)jdiv_round_up((long)cinfo->output_width *
|
||||
(long)(compptr->h_samp_factor *
|
||||
compptr->_DCT_scaled_size),
|
||||
(long)(cinfo->max_h_samp_factor *
|
||||
cinfo->_min_DCT_scaled_size));
|
||||
if (compptr->downsampled_width < 2 && orig_downsampled_width >= 2)
|
||||
reinit_upsampler = TRUE;
|
||||
|
||||
|
|
@ -254,11 +285,13 @@ jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
|
|||
|
||||
if (reinit_upsampler) {
|
||||
cinfo->master->jinit_upsampler_no_alloc = TRUE;
|
||||
jinit_upsampler(cinfo);
|
||||
_jinit_upsampler(cinfo);
|
||||
cinfo->master->jinit_upsampler_no_alloc = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 */
|
||||
|
||||
|
||||
/*
|
||||
* Read some scanlines of data from the JPEG decompressor.
|
||||
|
|
@ -268,17 +301,21 @@ jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
|
|||
* 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
|
||||
* 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)
|
||||
_jpeg_read_scanlines(j_decompress_ptr cinfo, _JSAMPARRAY scanlines,
|
||||
JDIMENSION max_lines)
|
||||
{
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
|
||||
JDIMENSION row_ctr;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
if (cinfo->global_state != DSTATE_SCANNING)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
if (cinfo->output_scanline >= cinfo->output_height) {
|
||||
|
|
@ -295,30 +332,36 @@ jpeg_read_scanlines(j_decompress_ptr cinfo, JSAMPARRAY scanlines,
|
|||
|
||||
/* Process some data */
|
||||
row_ctr = 0;
|
||||
(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
|
||||
(*cinfo->main->_process_data) (cinfo, scanlines, &row_ctr, max_lines);
|
||||
cinfo->output_scanline += row_ctr;
|
||||
return row_ctr;
|
||||
#else
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Dummy color convert function used by jpeg_skip_scanlines() */
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
|
||||
/* Dummy color convert function used by _jpeg_skip_scanlines() */
|
||||
LOCAL(void)
|
||||
noop_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
noop_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* Dummy quantize function used by jpeg_skip_scanlines() */
|
||||
/* Dummy quantize function used by _jpeg_skip_scanlines() */
|
||||
LOCAL(void)
|
||||
noop_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
noop_quantize(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* In some cases, it is best to call jpeg_read_scanlines() and discard the
|
||||
* In some cases, it is best to call _jpeg_read_scanlines() and discard the
|
||||
* output, rather than skipping the scanlines, because this allows us to
|
||||
* maintain the internal state of the context-based upsampler. In these cases,
|
||||
* we set up and tear down a dummy color converter in order to avoid valgrind
|
||||
|
|
@ -332,27 +375,27 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
|
|||
#ifdef UPSAMPLE_MERGING_SUPPORTED
|
||||
my_master_ptr master = (my_master_ptr)cinfo->master;
|
||||
#endif
|
||||
JSAMPLE dummy_sample[1] = { 0 };
|
||||
JSAMPROW dummy_row = dummy_sample;
|
||||
JSAMPARRAY scanlines = NULL;
|
||||
void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
_JSAMPLE dummy_sample[1] = { 0 };
|
||||
_JSAMPROW dummy_row = dummy_sample;
|
||||
_JSAMPARRAY scanlines = NULL;
|
||||
void (*color_convert) (j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf,
|
||||
int num_rows) = NULL;
|
||||
void (*color_quantize) (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows) = NULL;
|
||||
void (*color_quantize) (j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows) = NULL;
|
||||
|
||||
if (cinfo->cconvert && cinfo->cconvert->color_convert) {
|
||||
color_convert = cinfo->cconvert->color_convert;
|
||||
cinfo->cconvert->color_convert = noop_convert;
|
||||
if (cinfo->cconvert && cinfo->cconvert->_color_convert) {
|
||||
color_convert = cinfo->cconvert->_color_convert;
|
||||
cinfo->cconvert->_color_convert = noop_convert;
|
||||
/* This just prevents UBSan from complaining about adding 0 to a NULL
|
||||
* pointer. The pointer isn't actually used.
|
||||
*/
|
||||
scanlines = &dummy_row;
|
||||
}
|
||||
|
||||
if (cinfo->cquantize && cinfo->cquantize->color_quantize) {
|
||||
color_quantize = cinfo->cquantize->color_quantize;
|
||||
cinfo->cquantize->color_quantize = noop_quantize;
|
||||
if (cinfo->cquantize && cinfo->cquantize->_color_quantize) {
|
||||
color_quantize = cinfo->cquantize->_color_quantize;
|
||||
cinfo->cquantize->_color_quantize = noop_quantize;
|
||||
}
|
||||
|
||||
#ifdef UPSAMPLE_MERGING_SUPPORTED
|
||||
|
|
@ -363,19 +406,19 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
|
|||
#endif
|
||||
|
||||
for (n = 0; n < num_lines; n++)
|
||||
jpeg_read_scanlines(cinfo, scanlines, 1);
|
||||
_jpeg_read_scanlines(cinfo, scanlines, 1);
|
||||
|
||||
if (color_convert)
|
||||
cinfo->cconvert->color_convert = color_convert;
|
||||
cinfo->cconvert->_color_convert = color_convert;
|
||||
|
||||
if (color_quantize)
|
||||
cinfo->cquantize->color_quantize = color_quantize;
|
||||
cinfo->cquantize->_color_quantize = color_quantize;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called by jpeg_skip_scanlines(). This partially skips a decompress block by
|
||||
* incrementing the rowgroup counter.
|
||||
* Called by _jpeg_skip_scanlines(). This partially skips a decompress block
|
||||
* by incrementing the rowgroup counter.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
|
|
@ -414,7 +457,7 @@ increment_simple_rowgroup_ctr(j_decompress_ptr cinfo, JDIMENSION rows)
|
|||
*/
|
||||
|
||||
GLOBAL(JDIMENSION)
|
||||
jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
|
||||
_jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
|
||||
{
|
||||
my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
|
||||
my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
|
||||
|
|
@ -425,6 +468,12 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
|
|||
JDIMENSION lines_per_iMCU_row, lines_left_in_iMCU_row, lines_after_iMCU_row;
|
||||
JDIMENSION lines_to_skip, lines_to_read;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
if (cinfo->master->lossless)
|
||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
||||
|
||||
/* Two-pass color quantization is not supported. */
|
||||
if (cinfo->quantize_colors && cinfo->two_pass_quantize)
|
||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
||||
|
|
@ -597,11 +646,17 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
|
|||
*/
|
||||
|
||||
GLOBAL(JDIMENSION)
|
||||
jpeg_read_raw_data(j_decompress_ptr cinfo, JSAMPIMAGE data,
|
||||
JDIMENSION max_lines)
|
||||
_jpeg_read_raw_data(j_decompress_ptr cinfo, _JSAMPIMAGE data,
|
||||
JDIMENSION max_lines)
|
||||
{
|
||||
JDIMENSION lines_per_iMCU_row;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
if (cinfo->master->lossless)
|
||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
||||
|
||||
if (cinfo->global_state != DSTATE_RAW_OK)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
if (cinfo->output_scanline >= cinfo->output_height) {
|
||||
|
|
@ -622,7 +677,7 @@ jpeg_read_raw_data(j_decompress_ptr cinfo, JSAMPIMAGE data,
|
|||
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
||||
|
||||
/* Decompress directly into user's buffer. */
|
||||
if (!(*cinfo->coef->decompress_data) (cinfo, data))
|
||||
if (!(*cinfo->coef->_decompress_data) (cinfo, data))
|
||||
return 0; /* suspension forced, can do nothing more */
|
||||
|
||||
/* OK, we processed one iMCU row. */
|
||||
|
|
@ -630,6 +685,10 @@ jpeg_read_raw_data(j_decompress_ptr cinfo, JSAMPIMAGE data,
|
|||
return lines_per_iMCU_row;
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 */
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
|
||||
/* Additional entry points for buffered-image mode. */
|
||||
|
||||
|
|
@ -687,3 +746,5 @@ jpeg_finish_output(j_decompress_ptr cinfo)
|
|||
}
|
||||
|
||||
#endif /* D_MULTISCAN_FILES_SUPPORTED */
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 8 */
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ typedef my_destination_mgr *my_dest_ptr;
|
|||
#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */
|
||||
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
|
||||
/* Expanded data destination object for memory output */
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -52,7 +51,6 @@ typedef struct {
|
|||
} my_mem_destination_mgr;
|
||||
|
||||
typedef my_mem_destination_mgr *my_mem_dest_ptr;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -74,13 +72,11 @@ init_destination(j_compress_ptr cinfo)
|
|||
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
|
||||
}
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
|
||||
METHODDEF(void)
|
||||
init_mem_destination(j_compress_ptr cinfo)
|
||||
{
|
||||
/* no work necessary here */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -121,7 +117,6 @@ empty_output_buffer(j_compress_ptr cinfo)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
|
||||
METHODDEF(boolean)
|
||||
empty_mem_output_buffer(j_compress_ptr cinfo)
|
||||
{
|
||||
|
|
@ -150,7 +145,6 @@ empty_mem_output_buffer(j_compress_ptr cinfo)
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -179,7 +173,6 @@ term_destination(j_compress_ptr cinfo)
|
|||
ERREXIT(cinfo, JERR_FILE_WRITE);
|
||||
}
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
|
||||
METHODDEF(void)
|
||||
term_mem_destination(j_compress_ptr cinfo)
|
||||
{
|
||||
|
|
@ -188,7 +181,6 @@ term_mem_destination(j_compress_ptr cinfo)
|
|||
*dest->outbuffer = dest->buffer;
|
||||
*dest->outsize = (unsigned long)(dest->bufsize - dest->pub.free_in_buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -227,7 +219,6 @@ jpeg_stdio_dest(j_compress_ptr cinfo, FILE *outfile)
|
|||
}
|
||||
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
|
||||
/*
|
||||
* Prepare for output to a memory buffer.
|
||||
* The caller may supply an own initial buffer with appropriate size.
|
||||
|
|
@ -284,4 +275,3 @@ jpeg_mem_dest(j_compress_ptr cinfo, unsigned char **outbuffer,
|
|||
dest->pub.next_output_byte = dest->buffer = *outbuffer;
|
||||
dest->pub.free_in_buffer = dest->bufsize = *outsize;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -56,13 +56,11 @@ init_source(j_decompress_ptr cinfo)
|
|||
src->start_of_file = TRUE;
|
||||
}
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
|
||||
METHODDEF(void)
|
||||
init_mem_source(j_decompress_ptr cinfo)
|
||||
{
|
||||
/* no work necessary here */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -123,7 +121,6 @@ fill_input_buffer(j_decompress_ptr cinfo)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
|
||||
METHODDEF(boolean)
|
||||
fill_mem_input_buffer(j_decompress_ptr cinfo)
|
||||
{
|
||||
|
|
@ -144,7 +141,6 @@ fill_mem_input_buffer(j_decompress_ptr cinfo)
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -253,7 +249,6 @@ jpeg_stdio_src(j_decompress_ptr cinfo, FILE *infile)
|
|||
}
|
||||
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
|
||||
/*
|
||||
* Prepare for input from a supplied memory buffer.
|
||||
* The buffer must contain the whole JPEG data.
|
||||
|
|
@ -292,4 +287,3 @@ jpeg_mem_src(j_decompress_ptr cinfo, const unsigned char *inbuffer,
|
|||
src->bytes_in_buffer = (size_t)insize;
|
||||
src->next_input_byte = (const JOCTET *)inbuffer;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
* file.
|
||||
*
|
||||
* This file contains the coefficient buffer controller for decompression.
|
||||
* This controller is the top level of the JPEG decompressor proper.
|
||||
* This controller is the top level of the lossy JPEG decompressor proper.
|
||||
* The coefficient buffer lies between entropy decoding and inverse-DCT steps.
|
||||
*
|
||||
* In buffered-image mode, this controller is the interface between
|
||||
|
|
@ -21,19 +21,20 @@
|
|||
|
||||
#include "jinclude.h"
|
||||
#include "jdcoefct.h"
|
||||
#include "jpegcomp.h"
|
||||
#include "jpegapicomp.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(int) decompress_onepass(j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE output_buf);
|
||||
_JSAMPIMAGE output_buf);
|
||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
||||
METHODDEF(int) decompress_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf);
|
||||
METHODDEF(int) decompress_data(j_decompress_ptr cinfo, _JSAMPIMAGE output_buf);
|
||||
#endif
|
||||
#ifdef BLOCK_SMOOTHING_SUPPORTED
|
||||
LOCAL(boolean) smoothing_ok(j_decompress_ptr cinfo);
|
||||
METHODDEF(int) decompress_smooth_data(j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE output_buf);
|
||||
_JSAMPIMAGE output_buf);
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -62,9 +63,9 @@ start_output_pass(j_decompress_ptr cinfo)
|
|||
/* If multipass, check to see whether to use block smoothing on this pass */
|
||||
if (coef->pub.coef_arrays != NULL) {
|
||||
if (cinfo->do_block_smoothing && smoothing_ok(cinfo))
|
||||
coef->pub.decompress_data = decompress_smooth_data;
|
||||
coef->pub._decompress_data = decompress_smooth_data;
|
||||
else
|
||||
coef->pub.decompress_data = decompress_data;
|
||||
coef->pub._decompress_data = decompress_data;
|
||||
}
|
||||
#endif
|
||||
cinfo->output_iMCU_row = 0;
|
||||
|
|
@ -82,17 +83,17 @@ start_output_pass(j_decompress_ptr cinfo)
|
|||
*/
|
||||
|
||||
METHODDEF(int)
|
||||
decompress_onepass(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
decompress_onepass(j_decompress_ptr cinfo, _JSAMPIMAGE output_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, ci, xindex, yindex, yoffset, useful_width;
|
||||
JSAMPARRAY output_ptr;
|
||||
_JSAMPARRAY output_ptr;
|
||||
JDIMENSION start_col, output_col;
|
||||
jpeg_component_info *compptr;
|
||||
inverse_DCT_method_ptr inverse_DCT;
|
||||
_inverse_DCT_method_ptr inverse_DCT;
|
||||
|
||||
/* Loop to process as much as one whole iMCU row */
|
||||
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
|
||||
|
|
@ -129,7 +130,7 @@ decompress_onepass(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
|||
blkn += compptr->MCU_blocks;
|
||||
continue;
|
||||
}
|
||||
inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
|
||||
inverse_DCT = cinfo->idct->_inverse_DCT[compptr->component_index];
|
||||
useful_width = (MCU_col_num < last_MCU_col) ?
|
||||
compptr->MCU_width : compptr->last_col_width;
|
||||
output_ptr = output_buf[compptr->component_index] +
|
||||
|
|
@ -262,7 +263,7 @@ consume_data(j_decompress_ptr cinfo)
|
|||
*/
|
||||
|
||||
METHODDEF(int)
|
||||
decompress_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
decompress_data(j_decompress_ptr cinfo, _JSAMPIMAGE output_buf)
|
||||
{
|
||||
my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
|
||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
||||
|
|
@ -270,10 +271,10 @@ decompress_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
|||
int ci, block_row, block_rows;
|
||||
JBLOCKARRAY buffer;
|
||||
JBLOCKROW buffer_ptr;
|
||||
JSAMPARRAY output_ptr;
|
||||
_JSAMPARRAY output_ptr;
|
||||
JDIMENSION output_col;
|
||||
jpeg_component_info *compptr;
|
||||
inverse_DCT_method_ptr inverse_DCT;
|
||||
_inverse_DCT_method_ptr inverse_DCT;
|
||||
|
||||
/* Force some input to be done if we are getting ahead of the input. */
|
||||
while (cinfo->input_scan_number < cinfo->output_scan_number ||
|
||||
|
|
@ -302,7 +303,7 @@ decompress_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
|||
block_rows = (int)(compptr->height_in_blocks % compptr->v_samp_factor);
|
||||
if (block_rows == 0) block_rows = compptr->v_samp_factor;
|
||||
}
|
||||
inverse_DCT = cinfo->idct->inverse_DCT[ci];
|
||||
inverse_DCT = cinfo->idct->_inverse_DCT[ci];
|
||||
output_ptr = output_buf[ci];
|
||||
/* Loop over all DCT blocks to be processed. */
|
||||
for (block_row = 0; block_row < block_rows; block_row++) {
|
||||
|
|
@ -425,7 +426,7 @@ smoothing_ok(j_decompress_ptr cinfo)
|
|||
*/
|
||||
|
||||
METHODDEF(int)
|
||||
decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
decompress_smooth_data(j_decompress_ptr cinfo, _JSAMPIMAGE output_buf)
|
||||
{
|
||||
my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
|
||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
||||
|
|
@ -434,10 +435,10 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
|||
JBLOCKARRAY buffer;
|
||||
JBLOCKROW buffer_ptr, prev_prev_block_row, prev_block_row;
|
||||
JBLOCKROW next_block_row, next_next_block_row;
|
||||
JSAMPARRAY output_ptr;
|
||||
_JSAMPARRAY output_ptr;
|
||||
JDIMENSION output_col;
|
||||
jpeg_component_info *compptr;
|
||||
inverse_DCT_method_ptr inverse_DCT;
|
||||
_inverse_DCT_method_ptr inverse_DCT;
|
||||
boolean change_dc;
|
||||
JCOEF *workspace;
|
||||
int *coef_bits;
|
||||
|
|
@ -535,7 +536,7 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
|||
Q21 = quanttbl->quantval[Q21_POS];
|
||||
Q30 = quanttbl->quantval[Q30_POS];
|
||||
}
|
||||
inverse_DCT = cinfo->idct->inverse_DCT[ci];
|
||||
inverse_DCT = cinfo->idct->_inverse_DCT[ci];
|
||||
output_ptr = output_buf[ci];
|
||||
/* Loop over all DCT blocks to be processed. */
|
||||
for (block_row = 0; block_row < block_rows; block_row++) {
|
||||
|
|
@ -810,10 +811,13 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_d_coef_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
||||
_jinit_d_coef_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_coef_ptr coef;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
coef = (my_coef_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_coef_controller));
|
||||
|
|
@ -850,7 +854,7 @@ jinit_d_coef_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
|||
(JDIMENSION)access_rows);
|
||||
}
|
||||
coef->pub.consume_data = consume_data;
|
||||
coef->pub.decompress_data = decompress_data;
|
||||
coef->pub._decompress_data = decompress_data;
|
||||
coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
|
|
@ -867,7 +871,7 @@ jinit_d_coef_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
|||
coef->MCU_buffer[i] = buffer + i;
|
||||
}
|
||||
coef->pub.consume_data = dummy_consume_data;
|
||||
coef->pub.decompress_data = decompress_onepass;
|
||||
coef->pub._decompress_data = decompress_onepass;
|
||||
coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
* libjpeg-turbo Modifications:
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2020, Google, Inc.
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*/
|
||||
|
|
@ -14,6 +15,8 @@
|
|||
#include "jpeglib.h"
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
|
||||
|
||||
/* Block smoothing is only applicable for progressive JPEG, so: */
|
||||
#ifndef D_PROGRESSIVE_SUPPORTED
|
||||
#undef BLOCK_SMOOTHING_SUPPORTED
|
||||
|
|
@ -81,3 +84,5 @@ start_iMCU_row(j_decompress_ptr cinfo)
|
|||
coef->MCU_ctr = 0;
|
||||
coef->MCU_vert_offset = 0;
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modifications:
|
||||
* Copyright (C) 2013, Linaro Limited.
|
||||
* Copyright (C) 2014-2015, D. R. Commander.
|
||||
* Copyright (C) 2014-2015, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -17,18 +17,19 @@
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
ycc_rgb565_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
|
||||
register int y, cb, cr;
|
||||
register JSAMPROW outptr;
|
||||
register JSAMPROW inptr0, inptr1, inptr2;
|
||||
register _JSAMPROW outptr;
|
||||
register _JSAMPROW inptr0, inptr1, inptr2;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
/* copy these pointers into registers if possible */
|
||||
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
register int *Crrtab = cconvert->Cr_r_tab;
|
||||
register int *Cbbtab = cconvert->Cb_b_tab;
|
||||
register JLONG *Crgtab = cconvert->Cr_g_tab;
|
||||
|
|
@ -91,23 +92,27 @@ ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
*(INT16 *)outptr = (INT16)rgb;
|
||||
}
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
|
||||
register int y, cb, cr;
|
||||
register JSAMPROW outptr;
|
||||
register JSAMPROW inptr0, inptr1, inptr2;
|
||||
register _JSAMPROW outptr;
|
||||
register _JSAMPROW inptr0, inptr1, inptr2;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
/* copy these pointers into registers if possible */
|
||||
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
register int *Crrtab = cconvert->Cr_r_tab;
|
||||
register int *Cbbtab = cconvert->Cb_b_tab;
|
||||
register JLONG *Crgtab = cconvert->Cr_g_tab;
|
||||
|
|
@ -177,17 +182,20 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
*(INT16 *)outptr = (INT16)rgb;
|
||||
}
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
rgb_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
rgb_rgb565_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
register JSAMPROW outptr;
|
||||
register JSAMPROW inptr0, inptr1, inptr2;
|
||||
register _JSAMPROW outptr;
|
||||
register _JSAMPROW inptr0, inptr1, inptr2;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -237,14 +245,14 @@ rgb_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
register JSAMPROW outptr;
|
||||
register JSAMPROW inptr0, inptr1, inptr2;
|
||||
register _JSAMPROW outptr;
|
||||
register _JSAMPROW inptr0, inptr1, inptr2;
|
||||
register JDIMENSION col;
|
||||
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -296,11 +304,11 @@ rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
gray_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
gray_rgb565_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
register JSAMPROW inptr, outptr;
|
||||
register _JSAMPROW inptr, outptr;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
|
||||
|
|
@ -336,13 +344,13 @@ gray_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
gray_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
gray_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
register JSAMPROW inptr, outptr;
|
||||
register _JSAMPROW inptr, outptr;
|
||||
register JDIMENSION col;
|
||||
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009, 2011, 2015, 2023, D. R. Commander.
|
||||
* Copyright (C) 2009, 2011, 2015, 2022-2023, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -28,18 +28,19 @@
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
ycc_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
ycc_rgb_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
|
||||
register int y, cb, cr;
|
||||
register JSAMPROW outptr;
|
||||
register JSAMPROW inptr0, inptr1, inptr2;
|
||||
register _JSAMPROW outptr;
|
||||
register _JSAMPROW inptr0, inptr1, inptr2;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
/* copy these pointers into registers if possible */
|
||||
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
register int *Crrtab = cconvert->Cr_r_tab;
|
||||
register int *Cbbtab = cconvert->Cb_b_tab;
|
||||
register JLONG *Crgtab = cconvert->Cr_g_tab;
|
||||
|
|
@ -62,14 +63,17 @@ ycc_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
||||
SCALEBITS))];
|
||||
outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];
|
||||
/* Set unused byte to MAXJSAMPLE so it can be interpreted as an opaque */
|
||||
/* alpha channel value */
|
||||
/* Set unused byte to _MAXJSAMPLE so it can be interpreted as an */
|
||||
/* opaque alpha channel value */
|
||||
#ifdef RGB_ALPHA
|
||||
outptr[RGB_ALPHA] = MAXJSAMPLE;
|
||||
outptr[RGB_ALPHA] = _MAXJSAMPLE;
|
||||
#endif
|
||||
outptr += RGB_PIXELSIZE;
|
||||
}
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -81,11 +85,11 @@ ycc_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
gray_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
gray_rgb_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
register JSAMPROW inptr, outptr;
|
||||
register _JSAMPROW inptr, outptr;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
|
||||
|
|
@ -94,10 +98,10 @@ gray_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
outptr = *output_buf++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
|
||||
/* Set unused byte to MAXJSAMPLE so it can be interpreted as an opaque */
|
||||
/* alpha channel value */
|
||||
/* Set unused byte to _MAXJSAMPLE so it can be interpreted as an */
|
||||
/* opaque alpha channel value */
|
||||
#ifdef RGB_ALPHA
|
||||
outptr[RGB_ALPHA] = MAXJSAMPLE;
|
||||
outptr[RGB_ALPHA] = _MAXJSAMPLE;
|
||||
#endif
|
||||
outptr += RGB_PIXELSIZE;
|
||||
}
|
||||
|
|
@ -111,12 +115,12 @@ gray_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
rgb_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
rgb_rgb_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
register JSAMPROW inptr0, inptr1, inptr2;
|
||||
register JSAMPROW outptr;
|
||||
register _JSAMPROW inptr0, inptr1, inptr2;
|
||||
register _JSAMPROW outptr;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
|
||||
|
|
@ -130,10 +134,10 @@ rgb_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
outptr[RGB_RED] = inptr0[col];
|
||||
outptr[RGB_GREEN] = inptr1[col];
|
||||
outptr[RGB_BLUE] = inptr2[col];
|
||||
/* Set unused byte to MAXJSAMPLE so it can be interpreted as an opaque */
|
||||
/* alpha channel value */
|
||||
/* Set unused byte to _MAXJSAMPLE so it can be interpreted as an */
|
||||
/* opaque alpha channel value */
|
||||
#ifdef RGB_ALPHA
|
||||
outptr[RGB_ALPHA] = MAXJSAMPLE;
|
||||
outptr[RGB_ALPHA] = _MAXJSAMPLE;
|
||||
#endif
|
||||
outptr += RGB_PIXELSIZE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
* Modified 2011 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2009, 2011-2012, 2014-2015, D. R. Commander.
|
||||
* Copyright (C) 2009, 2011-2012, 2014-2015, 2022, D. R. Commander.
|
||||
* Copyright (C) 2013, Linaro Limited.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
|
|
@ -18,13 +18,17 @@
|
|||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsimd.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
|
||||
|
||||
/* Private subobject */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_color_deconverter pub; /* public fields */
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
/* 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 */
|
||||
|
|
@ -33,6 +37,7 @@ typedef struct {
|
|||
|
||||
/* Private state for RGB->Y conversion */
|
||||
JLONG *rgb_y_tab; /* => table for RGB to Y conversion */
|
||||
#endif
|
||||
} my_color_deconverter;
|
||||
|
||||
typedef my_color_deconverter *my_cconvert_ptr;
|
||||
|
|
@ -43,7 +48,7 @@ typedef my_color_deconverter *my_cconvert_ptr;
|
|||
|
||||
/*
|
||||
* 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.
|
||||
* 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
|
||||
|
|
@ -52,7 +57,7 @@ typedef my_color_deconverter *my_cconvert_ptr;
|
|||
*
|
||||
* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
|
||||
*
|
||||
* where Cb and Cr represent the incoming values less CENTERJSAMPLE.
|
||||
* 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
|
||||
|
|
@ -63,7 +68,7 @@ typedef my_color_deconverter *my_cconvert_ptr;
|
|||
*
|
||||
* 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 8-bit samples 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.
|
||||
|
|
@ -84,9 +89,9 @@ typedef my_color_deconverter *my_cconvert_ptr;
|
|||
*/
|
||||
|
||||
#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 TABLE_SIZE (3 * (MAXJSAMPLE + 1))
|
||||
#define G_Y_OFF (1 * (_MAXJSAMPLE + 1)) /* offset to G => Y section */
|
||||
#define B_Y_OFF (2 * (_MAXJSAMPLE + 1)) /* etc. */
|
||||
#define TABLE_SIZE (3 * (_MAXJSAMPLE + 1))
|
||||
|
||||
|
||||
/* Include inline routines for colorspace extensions */
|
||||
|
|
@ -209,6 +214,7 @@ typedef my_color_deconverter *my_cconvert_ptr;
|
|||
LOCAL(void)
|
||||
build_ycc_rgb_table(j_decompress_ptr cinfo)
|
||||
{
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
|
||||
int i;
|
||||
JLONG x;
|
||||
|
|
@ -216,20 +222,20 @@ build_ycc_rgb_table(j_decompress_ptr cinfo)
|
|||
|
||||
cconvert->Cr_r_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE + 1) * sizeof(int));
|
||||
(_MAXJSAMPLE + 1) * sizeof(int));
|
||||
cconvert->Cb_b_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE + 1) * sizeof(int));
|
||||
(_MAXJSAMPLE + 1) * sizeof(int));
|
||||
cconvert->Cr_g_tab = (JLONG *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE + 1) * sizeof(JLONG));
|
||||
(_MAXJSAMPLE + 1) * sizeof(JLONG));
|
||||
cconvert->Cb_g_tab = (JLONG *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE + 1) * sizeof(JLONG));
|
||||
(_MAXJSAMPLE + 1) * sizeof(JLONG));
|
||||
|
||||
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 */
|
||||
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);
|
||||
|
|
@ -242,6 +248,9 @@ build_ycc_rgb_table(j_decompress_ptr cinfo)
|
|||
/* 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;
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -250,8 +259,8 @@ build_ycc_rgb_table(j_decompress_ptr cinfo)
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
ycc_rgb_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
switch (cinfo->out_color_space) {
|
||||
case JCS_EXT_RGB:
|
||||
|
|
@ -300,6 +309,7 @@ ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
LOCAL(void)
|
||||
build_rgb_y_table(j_decompress_ptr cinfo)
|
||||
{
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
|
||||
JLONG *rgb_y_tab;
|
||||
JLONG i;
|
||||
|
|
@ -309,11 +319,14 @@ build_rgb_y_table(j_decompress_ptr cinfo)
|
|||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(TABLE_SIZE * sizeof(JLONG)));
|
||||
|
||||
for (i = 0; i <= MAXJSAMPLE; i++) {
|
||||
for (i = 0; i <= _MAXJSAMPLE; i++) {
|
||||
rgb_y_tab[i + R_Y_OFF] = FIX(0.29900) * i;
|
||||
rgb_y_tab[i + G_Y_OFF] = FIX(0.58700) * i;
|
||||
rgb_y_tab[i + B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -322,14 +335,15 @@ build_rgb_y_table(j_decompress_ptr cinfo)
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
rgb_gray_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
rgb_gray_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
|
||||
register int r, g, b;
|
||||
register JLONG *ctab = cconvert->rgb_y_tab;
|
||||
register JSAMPROW outptr;
|
||||
register JSAMPROW inptr0, inptr1, inptr2;
|
||||
register _JSAMPROW outptr;
|
||||
register _JSAMPROW inptr0, inptr1, inptr2;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
|
||||
|
|
@ -344,10 +358,13 @@ rgb_gray_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
g = inptr1[col];
|
||||
b = inptr2[col];
|
||||
/* Y */
|
||||
outptr[col] = (JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
|
||||
ctab[b + B_Y_OFF]) >> SCALEBITS);
|
||||
outptr[col] = (_JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
|
||||
ctab[b + B_Y_OFF]) >> SCALEBITS);
|
||||
}
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -357,10 +374,10 @@ rgb_gray_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
null_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
null_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
register JSAMPROW inptr, inptr0, inptr1, inptr2, inptr3, outptr;
|
||||
register _JSAMPROW inptr, inptr0, inptr1, inptr2, inptr3, outptr;
|
||||
register JDIMENSION col;
|
||||
register int num_components = cinfo->num_components;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
|
|
@ -418,11 +435,11 @@ null_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
grayscale_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
grayscale_convert(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);
|
||||
_jcopy_sample_rows(input_buf[0], (int)input_row, output_buf, 0, num_rows,
|
||||
cinfo->output_width);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -431,8 +448,8 @@ grayscale_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
gray_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
gray_rgb_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
switch (cinfo->out_color_space) {
|
||||
case JCS_EXT_RGB:
|
||||
|
|
@ -476,8 +493,8 @@ gray_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
rgb_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
rgb_rgb_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
switch (cinfo->out_color_space) {
|
||||
case JCS_EXT_RGB:
|
||||
|
|
@ -524,17 +541,18 @@ rgb_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
ycck_cmyk_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
ycck_cmyk_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
|
||||
register int y, cb, cr;
|
||||
register JSAMPROW outptr;
|
||||
register JSAMPROW inptr0, inptr1, inptr2, inptr3;
|
||||
register _JSAMPROW outptr;
|
||||
register _JSAMPROW inptr0, inptr1, inptr2, inptr3;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
/* copy these pointers into registers if possible */
|
||||
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
register int *Crrtab = cconvert->Cr_r_tab;
|
||||
register int *Cbbtab = cconvert->Cb_b_tab;
|
||||
register JLONG *Crgtab = cconvert->Cr_g_tab;
|
||||
|
|
@ -553,16 +571,19 @@ ycck_cmyk_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
cb = inptr1[col];
|
||||
cr = 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 */
|
||||
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 */
|
||||
outptr[2] = range_limit[_MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */
|
||||
/* K passes through unchanged */
|
||||
outptr[3] = inptr3[col];
|
||||
outptr += 4;
|
||||
}
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -652,8 +673,8 @@ static INLINE boolean is_big_endian(void)
|
|||
|
||||
|
||||
METHODDEF(void)
|
||||
ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
ycc_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
if (is_big_endian())
|
||||
ycc_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
|
||||
|
|
@ -663,8 +684,8 @@ ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
|
||||
METHODDEF(void)
|
||||
ycc_rgb565D_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
ycc_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
if (is_big_endian())
|
||||
ycc_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
|
||||
|
|
@ -674,8 +695,8 @@ ycc_rgb565D_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
|
||||
METHODDEF(void)
|
||||
rgb_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
rgb_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
if (is_big_endian())
|
||||
rgb_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
|
||||
|
|
@ -685,8 +706,8 @@ rgb_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
|
||||
METHODDEF(void)
|
||||
rgb_rgb565D_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
rgb_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
if (is_big_endian())
|
||||
rgb_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
|
||||
|
|
@ -696,8 +717,8 @@ rgb_rgb565D_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
|
||||
METHODDEF(void)
|
||||
gray_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
gray_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
if (is_big_endian())
|
||||
gray_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
|
||||
|
|
@ -707,8 +728,8 @@ gray_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
|
||||
METHODDEF(void)
|
||||
gray_rgb565D_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
|
||||
gray_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
if (is_big_endian())
|
||||
gray_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
|
||||
|
|
@ -733,11 +754,14 @@ start_pass_dcolor(j_decompress_ptr cinfo)
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_color_deconverter(j_decompress_ptr cinfo)
|
||||
_jinit_color_deconverter(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_cconvert_ptr cconvert;
|
||||
int ci;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
cconvert = (my_cconvert_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_color_deconverter));
|
||||
|
|
@ -772,19 +796,24 @@ jinit_color_deconverter(j_decompress_ptr cinfo)
|
|||
/* 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.
|
||||
* NOTE: We do not allow any lossy color conversion algorithms in lossless
|
||||
* mode.
|
||||
*/
|
||||
|
||||
switch (cinfo->out_color_space) {
|
||||
case JCS_GRAYSCALE:
|
||||
if (cinfo->master->lossless &&
|
||||
cinfo->jpeg_color_space != cinfo->out_color_space)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
cinfo->out_color_components = 1;
|
||||
if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
|
||||
cinfo->jpeg_color_space == JCS_YCbCr) {
|
||||
cconvert->pub.color_convert = grayscale_convert;
|
||||
cconvert->pub._color_convert = grayscale_convert;
|
||||
/* 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 if (cinfo->jpeg_color_space == JCS_RGB) {
|
||||
cconvert->pub.color_convert = rgb_gray_convert;
|
||||
cconvert->pub._color_convert = rgb_gray_convert;
|
||||
build_rgb_y_table(cinfo);
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
|
|
@ -801,65 +830,78 @@ jinit_color_deconverter(j_decompress_ptr cinfo)
|
|||
case JCS_EXT_BGRA:
|
||||
case JCS_EXT_ABGR:
|
||||
case JCS_EXT_ARGB:
|
||||
if (cinfo->master->lossless && cinfo->jpeg_color_space != JCS_RGB)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
|
||||
if (cinfo->jpeg_color_space == JCS_YCbCr) {
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_ycc_rgb())
|
||||
cconvert->pub.color_convert = jsimd_ycc_rgb_convert;
|
||||
else {
|
||||
cconvert->pub.color_convert = ycc_rgb_convert;
|
||||
cconvert->pub._color_convert = jsimd_ycc_rgb_convert;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
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;
|
||||
cconvert->pub._color_convert = gray_rgb_convert;
|
||||
} else if (cinfo->jpeg_color_space == JCS_RGB) {
|
||||
if (rgb_red[cinfo->out_color_space] == 0 &&
|
||||
rgb_green[cinfo->out_color_space] == 1 &&
|
||||
rgb_blue[cinfo->out_color_space] == 2 &&
|
||||
rgb_pixelsize[cinfo->out_color_space] == 3)
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
cconvert->pub._color_convert = null_convert;
|
||||
else
|
||||
cconvert->pub.color_convert = rgb_rgb_convert;
|
||||
cconvert->pub._color_convert = rgb_rgb_convert;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
||||
case JCS_RGB565:
|
||||
if (cinfo->master->lossless)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
cinfo->out_color_components = 3;
|
||||
if (cinfo->dither_mode == JDITHER_NONE) {
|
||||
if (cinfo->jpeg_color_space == JCS_YCbCr) {
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_ycc_rgb565())
|
||||
cconvert->pub.color_convert = jsimd_ycc_rgb565_convert;
|
||||
else {
|
||||
cconvert->pub.color_convert = ycc_rgb565_convert;
|
||||
cconvert->pub._color_convert = jsimd_ycc_rgb565_convert;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
cconvert->pub._color_convert = ycc_rgb565_convert;
|
||||
build_ycc_rgb_table(cinfo);
|
||||
}
|
||||
} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
|
||||
cconvert->pub.color_convert = gray_rgb565_convert;
|
||||
cconvert->pub._color_convert = gray_rgb565_convert;
|
||||
} else if (cinfo->jpeg_color_space == JCS_RGB) {
|
||||
cconvert->pub.color_convert = rgb_rgb565_convert;
|
||||
cconvert->pub._color_convert = rgb_rgb565_convert;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
} else {
|
||||
/* only ordered dithering is supported */
|
||||
if (cinfo->jpeg_color_space == JCS_YCbCr) {
|
||||
cconvert->pub.color_convert = ycc_rgb565D_convert;
|
||||
cconvert->pub._color_convert = ycc_rgb565D_convert;
|
||||
build_ycc_rgb_table(cinfo);
|
||||
} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
|
||||
cconvert->pub.color_convert = gray_rgb565D_convert;
|
||||
cconvert->pub._color_convert = gray_rgb565D_convert;
|
||||
} else if (cinfo->jpeg_color_space == JCS_RGB) {
|
||||
cconvert->pub.color_convert = rgb_rgb565D_convert;
|
||||
cconvert->pub._color_convert = rgb_rgb565D_convert;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
}
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
if (cinfo->master->lossless &&
|
||||
cinfo->jpeg_color_space != cinfo->out_color_space)
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
cinfo->out_color_components = 4;
|
||||
if (cinfo->jpeg_color_space == JCS_YCCK) {
|
||||
cconvert->pub.color_convert = ycck_cmyk_convert;
|
||||
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_convert;
|
||||
cconvert->pub._color_convert = null_convert;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
|
@ -868,7 +910,7 @@ jinit_color_deconverter(j_decompress_ptr cinfo)
|
|||
/* 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_convert;
|
||||
cconvert->pub._color_convert = null_convert;
|
||||
} else /* unsupported non-null conversion */
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
break;
|
||||
|
|
@ -879,3 +921,5 @@ jinit_color_deconverter(j_decompress_ptr cinfo)
|
|||
else
|
||||
cinfo->output_components = cinfo->out_color_components;
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015, D. R. Commander.
|
||||
* Copyright (C) 2015, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -15,13 +15,15 @@
|
|||
* machine-dependent tuning (e.g., assembly coding).
|
||||
*/
|
||||
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
/*
|
||||
* 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, JLONG 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 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
|
||||
|
|
@ -76,78 +78,89 @@ 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
|
||||
* 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 IDCT_range_limit(cinfo) \
|
||||
((_JSAMPLE *)((cinfo)->sample_range_limit) + _CENTERJSAMPLE)
|
||||
|
||||
#define RANGE_MASK (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */
|
||||
#define RANGE_MASK (_MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */
|
||||
|
||||
|
||||
/* Extern declarations for the forward and inverse DCT routines. */
|
||||
|
||||
EXTERN(void) jpeg_fdct_islow(DCTELEM *data);
|
||||
EXTERN(void) jpeg_fdct_ifast(DCTELEM *data);
|
||||
EXTERN(void) _jpeg_fdct_islow(DCTELEM *data);
|
||||
EXTERN(void) _jpeg_fdct_ifast(DCTELEM *data);
|
||||
EXTERN(void) jpeg_fdct_float(FAST_FLOAT *data);
|
||||
|
||||
EXTERN(void) jpeg_idct_islow(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_ifast(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_float(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_7x7(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_6x6(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_5x5(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_4x4(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_3x3(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_2x2(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_1x1(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_9x9(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_10x10(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_11x11(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_12x12(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_13x13(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_14x14(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_15x15(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) jpeg_idct_16x16(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_islow(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_ifast(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_float(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_7x7(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
_JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_6x6(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
_JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_5x5(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
_JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_4x4(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
_JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_3x3(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
_JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_2x2(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
_JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_1x1(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
_JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_9x9(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr, JCOEFPTR coef_block,
|
||||
_JSAMPARRAY output_buf, JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_10x10(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_11x11(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_12x12(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_13x13(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_14x14(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_15x15(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col);
|
||||
EXTERN(void) _jpeg_idct_16x16(j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
#include "jsimddct.h"
|
||||
#include "jpegcomp.h"
|
||||
#include "jpegapicomp.h"
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -100,7 +100,7 @@ start_pass(j_decompress_ptr cinfo)
|
|||
int ci, i;
|
||||
jpeg_component_info *compptr;
|
||||
int method = 0;
|
||||
inverse_DCT_method_ptr method_ptr = NULL;
|
||||
_inverse_DCT_method_ptr method_ptr = NULL;
|
||||
JQUANT_TBL *qtbl;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
|
|
@ -109,42 +109,46 @@ start_pass(j_decompress_ptr cinfo)
|
|||
switch (compptr->_DCT_scaled_size) {
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
case 1:
|
||||
method_ptr = jpeg_idct_1x1;
|
||||
method_ptr = _jpeg_idct_1x1;
|
||||
method = JDCT_ISLOW; /* jidctred uses islow-style table */
|
||||
break;
|
||||
case 2:
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_idct_2x2())
|
||||
method_ptr = jsimd_idct_2x2;
|
||||
else
|
||||
method_ptr = jpeg_idct_2x2;
|
||||
#endif
|
||||
method_ptr = _jpeg_idct_2x2;
|
||||
method = JDCT_ISLOW; /* jidctred uses islow-style table */
|
||||
break;
|
||||
case 3:
|
||||
method_ptr = jpeg_idct_3x3;
|
||||
method_ptr = _jpeg_idct_3x3;
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
case 4:
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_idct_4x4())
|
||||
method_ptr = jsimd_idct_4x4;
|
||||
else
|
||||
method_ptr = jpeg_idct_4x4;
|
||||
#endif
|
||||
method_ptr = _jpeg_idct_4x4;
|
||||
method = JDCT_ISLOW; /* jidctred uses islow-style table */
|
||||
break;
|
||||
case 5:
|
||||
method_ptr = jpeg_idct_5x5;
|
||||
method_ptr = _jpeg_idct_5x5;
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
case 6:
|
||||
#if defined(__mips__)
|
||||
#if defined(WITH_SIMD) && defined(__mips__)
|
||||
if (jsimd_can_idct_6x6())
|
||||
method_ptr = jsimd_idct_6x6;
|
||||
else
|
||||
#endif
|
||||
method_ptr = jpeg_idct_6x6;
|
||||
method_ptr = _jpeg_idct_6x6;
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
case 7:
|
||||
method_ptr = jpeg_idct_7x7;
|
||||
method_ptr = _jpeg_idct_7x7;
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
#endif
|
||||
|
|
@ -152,28 +156,34 @@ start_pass(j_decompress_ptr cinfo)
|
|||
switch (cinfo->dct_method) {
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
case JDCT_ISLOW:
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_idct_islow())
|
||||
method_ptr = jsimd_idct_islow;
|
||||
else
|
||||
method_ptr = jpeg_idct_islow;
|
||||
#endif
|
||||
method_ptr = _jpeg_idct_islow;
|
||||
method = JDCT_ISLOW;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_idct_ifast())
|
||||
method_ptr = jsimd_idct_ifast;
|
||||
else
|
||||
method_ptr = jpeg_idct_ifast;
|
||||
#endif
|
||||
method_ptr = _jpeg_idct_ifast;
|
||||
method = JDCT_IFAST;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_idct_float())
|
||||
method_ptr = jsimd_idct_float;
|
||||
else
|
||||
method_ptr = jpeg_idct_float;
|
||||
#endif
|
||||
method_ptr = _jpeg_idct_float;
|
||||
method = JDCT_FLOAT;
|
||||
break;
|
||||
#endif
|
||||
|
|
@ -184,40 +194,40 @@ start_pass(j_decompress_ptr cinfo)
|
|||
break;
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
case 9:
|
||||
method_ptr = jpeg_idct_9x9;
|
||||
method_ptr = _jpeg_idct_9x9;
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
case 10:
|
||||
method_ptr = jpeg_idct_10x10;
|
||||
method_ptr = _jpeg_idct_10x10;
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
case 11:
|
||||
method_ptr = jpeg_idct_11x11;
|
||||
method_ptr = _jpeg_idct_11x11;
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
case 12:
|
||||
#if defined(__mips__)
|
||||
#if defined(WITH_SIMD) && defined(__mips__)
|
||||
if (jsimd_can_idct_12x12())
|
||||
method_ptr = jsimd_idct_12x12;
|
||||
else
|
||||
#endif
|
||||
method_ptr = jpeg_idct_12x12;
|
||||
method_ptr = _jpeg_idct_12x12;
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
case 13:
|
||||
method_ptr = jpeg_idct_13x13;
|
||||
method_ptr = _jpeg_idct_13x13;
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
case 14:
|
||||
method_ptr = jpeg_idct_14x14;
|
||||
method_ptr = _jpeg_idct_14x14;
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
case 15:
|
||||
method_ptr = jpeg_idct_15x15;
|
||||
method_ptr = _jpeg_idct_15x15;
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
case 16:
|
||||
method_ptr = jpeg_idct_16x16;
|
||||
method_ptr = _jpeg_idct_16x16;
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
#endif
|
||||
|
|
@ -225,7 +235,7 @@ start_pass(j_decompress_ptr cinfo)
|
|||
ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->_DCT_scaled_size);
|
||||
break;
|
||||
}
|
||||
idct->pub.inverse_DCT[ci] = method_ptr;
|
||||
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
|
||||
|
|
@ -327,12 +337,15 @@ start_pass(j_decompress_ptr cinfo)
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_inverse_dct(j_decompress_ptr cinfo)
|
||||
_jinit_inverse_dct(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_idct_ptr idct;
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
idct = (my_idct_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_idct_controller));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,403 @@
|
|||
/*
|
||||
* jddiffct.c
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file contains the [un]difference buffer controller for decompression.
|
||||
* This controller is the top level of the lossless JPEG decompressor proper.
|
||||
* The difference buffer lies between the entropy decoding and
|
||||
* prediction/undifferencing steps. The undifference buffer lies between the
|
||||
* prediction/undifferencing and scaling steps.
|
||||
*
|
||||
* In buffered-image mode, this controller is the interface between
|
||||
* input-oriented processing and output-oriented processing.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jlossls.h" /* Private declarations for lossless codec */
|
||||
|
||||
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_d_coef_controller pub; /* public fields */
|
||||
|
||||
/* These variables keep track of the current location of the input side. */
|
||||
/* cinfo->input_iMCU_row is also used for this. */
|
||||
JDIMENSION MCU_ctr; /* counts MCUs processed in current row */
|
||||
unsigned int restart_rows_to_go; /* MCU rows left in this restart
|
||||
interval */
|
||||
unsigned int MCU_vert_offset; /* counts MCU rows within iMCU row */
|
||||
unsigned int MCU_rows_per_iMCU_row; /* number of such rows needed */
|
||||
|
||||
/* The output side's location is represented by cinfo->output_iMCU_row. */
|
||||
|
||||
JDIFFARRAY diff_buf[MAX_COMPONENTS]; /* iMCU row of differences */
|
||||
JDIFFARRAY undiff_buf[MAX_COMPONENTS]; /* iMCU row of undiff'd samples */
|
||||
|
||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
||||
/* In multi-pass modes, we need a virtual sample array for each component. */
|
||||
jvirt_sarray_ptr whole_image[MAX_COMPONENTS];
|
||||
#endif
|
||||
} my_diff_controller;
|
||||
|
||||
typedef my_diff_controller *my_diff_ptr;
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(int) decompress_data(j_decompress_ptr cinfo, _JSAMPIMAGE output_buf);
|
||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
||||
METHODDEF(int) output_data(j_decompress_ptr cinfo, _JSAMPIMAGE output_buf);
|
||||
#endif
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
start_iMCU_row(j_decompress_ptr cinfo)
|
||||
/* Reset within-iMCU-row counters for a new row (input side) */
|
||||
{
|
||||
my_diff_ptr diff = (my_diff_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) {
|
||||
diff->MCU_rows_per_iMCU_row = 1;
|
||||
} else {
|
||||
if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1))
|
||||
diff->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
|
||||
else
|
||||
diff->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
|
||||
}
|
||||
|
||||
diff->MCU_ctr = 0;
|
||||
diff->MCU_vert_offset = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for an input processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_input_pass(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_diff_ptr diff = (my_diff_ptr)cinfo->coef;
|
||||
|
||||
/* Because it is hitching a ride on the jpeg_inverse_dct struct,
|
||||
* start_pass_lossless() will be called at the start of the output pass.
|
||||
* This ensures that it will be called at the start of the input pass as
|
||||
* well.
|
||||
*/
|
||||
(*cinfo->idct->start_pass) (cinfo);
|
||||
|
||||
/* Check that the restart interval is an integer multiple of the number
|
||||
* of MCUs in an MCU row.
|
||||
*/
|
||||
if (cinfo->restart_interval % cinfo->MCUs_per_row != 0)
|
||||
ERREXIT2(cinfo, JERR_BAD_RESTART,
|
||||
cinfo->restart_interval, cinfo->MCUs_per_row);
|
||||
|
||||
/* Initialize restart counter */
|
||||
diff->restart_rows_to_go = cinfo->restart_interval / cinfo->MCUs_per_row;
|
||||
|
||||
cinfo->input_iMCU_row = 0;
|
||||
start_iMCU_row(cinfo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check for a restart marker & resynchronize decoder, undifferencer.
|
||||
* Returns FALSE if must suspend.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
process_restart(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_diff_ptr diff = (my_diff_ptr)cinfo->coef;
|
||||
|
||||
if (!(*cinfo->entropy->process_restart) (cinfo))
|
||||
return FALSE;
|
||||
|
||||
(*cinfo->idct->start_pass) (cinfo);
|
||||
|
||||
/* Reset restart counter */
|
||||
diff->restart_rows_to_go = cinfo->restart_interval / cinfo->MCUs_per_row;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for an output processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_output_pass(j_decompress_ptr cinfo)
|
||||
{
|
||||
cinfo->output_iMCU_row = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Decompress and return some data in the supplied buffer.
|
||||
* Always attempts to emit one fully interleaved MCU row ("iMCU" row).
|
||||
* Input and output must run in lockstep since we have only a one-MCU buffer.
|
||||
* Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
|
||||
*
|
||||
* NB: output_buf contains a plane for each component in image,
|
||||
* which we index according to the component's SOF position.
|
||||
*/
|
||||
|
||||
METHODDEF(int)
|
||||
decompress_data(j_decompress_ptr cinfo, _JSAMPIMAGE output_buf)
|
||||
{
|
||||
my_diff_ptr diff = (my_diff_ptr)cinfo->coef;
|
||||
lossless_decomp_ptr losslessd = (lossless_decomp_ptr)cinfo->idct;
|
||||
JDIMENSION MCU_col_num; /* index of current MCU within row */
|
||||
JDIMENSION MCU_count; /* number of MCUs decoded */
|
||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
||||
int ci, compi, row, prev_row;
|
||||
unsigned int yoffset;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Loop to process as much as one whole iMCU row */
|
||||
for (yoffset = diff->MCU_vert_offset; yoffset < diff->MCU_rows_per_iMCU_row;
|
||||
yoffset++) {
|
||||
|
||||
/* Process restart marker if needed; may have to suspend */
|
||||
if (cinfo->restart_interval) {
|
||||
if (diff->restart_rows_to_go == 0)
|
||||
if (!process_restart(cinfo))
|
||||
return JPEG_SUSPENDED;
|
||||
}
|
||||
|
||||
MCU_col_num = diff->MCU_ctr;
|
||||
/* Try to fetch an MCU row (or remaining portion of suspended MCU row). */
|
||||
MCU_count =
|
||||
(*cinfo->entropy->decode_mcus) (cinfo,
|
||||
diff->diff_buf, yoffset, MCU_col_num,
|
||||
cinfo->MCUs_per_row - MCU_col_num);
|
||||
if (MCU_count != cinfo->MCUs_per_row - MCU_col_num) {
|
||||
/* Suspension forced; update state counters and exit */
|
||||
diff->MCU_vert_offset = yoffset;
|
||||
diff->MCU_ctr += MCU_count;
|
||||
return JPEG_SUSPENDED;
|
||||
}
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
if (cinfo->restart_interval)
|
||||
diff->restart_rows_to_go--;
|
||||
|
||||
/* Completed an MCU row, but perhaps not an iMCU row */
|
||||
diff->MCU_ctr = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Undifference and scale each scanline of the disassembled MCU row
|
||||
* separately. We do not process dummy samples at the end of a scanline
|
||||
* or dummy rows at the end of the image.
|
||||
*/
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
compi = compptr->component_index;
|
||||
for (row = 0, prev_row = compptr->v_samp_factor - 1;
|
||||
row < (cinfo->input_iMCU_row == last_iMCU_row ?
|
||||
compptr->last_row_height : compptr->v_samp_factor);
|
||||
prev_row = row, row++) {
|
||||
(*losslessd->predict_undifference[compi])
|
||||
(cinfo, compi, diff->diff_buf[compi][row],
|
||||
diff->undiff_buf[compi][prev_row], diff->undiff_buf[compi][row],
|
||||
compptr->width_in_blocks);
|
||||
(*losslessd->scaler_scale) (cinfo, diff->undiff_buf[compi][row],
|
||||
output_buf[compi][row],
|
||||
compptr->width_in_blocks);
|
||||
}
|
||||
}
|
||||
|
||||
/* Completed the iMCU row, advance counters for next one.
|
||||
*
|
||||
* NB: output_data will increment output_iMCU_row.
|
||||
* This counter is not needed for the single-pass case
|
||||
* or the input side of the multi-pass case.
|
||||
*/
|
||||
if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
|
||||
start_iMCU_row(cinfo);
|
||||
return JPEG_ROW_COMPLETED;
|
||||
}
|
||||
/* Completed the scan */
|
||||
(*cinfo->inputctl->finish_input_pass) (cinfo);
|
||||
return JPEG_SCAN_COMPLETED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Dummy consume-input routine for single-pass operation.
|
||||
*/
|
||||
|
||||
METHODDEF(int)
|
||||
dummy_consume_data(j_decompress_ptr cinfo)
|
||||
{
|
||||
return JPEG_SUSPENDED; /* Always indicate nothing was done */
|
||||
}
|
||||
|
||||
|
||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
||||
|
||||
/*
|
||||
* Consume input data and store it in the full-image sample buffer.
|
||||
* We read as much as one fully interleaved MCU row ("iMCU" row) per call,
|
||||
* ie, v_samp_factor rows for each component in the scan.
|
||||
* Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
|
||||
*/
|
||||
|
||||
METHODDEF(int)
|
||||
consume_data(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_diff_ptr diff = (my_diff_ptr)cinfo->coef;
|
||||
int ci, compi;
|
||||
_JSAMPARRAY buffer[MAX_COMPS_IN_SCAN];
|
||||
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];
|
||||
compi = compptr->component_index;
|
||||
buffer[compi] = (_JSAMPARRAY)(*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr)cinfo, diff->whole_image[compi],
|
||||
cinfo->input_iMCU_row * compptr->v_samp_factor,
|
||||
(JDIMENSION)compptr->v_samp_factor, TRUE);
|
||||
}
|
||||
|
||||
return decompress_data(cinfo, buffer);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Output some data from the full-image sample buffer in the multi-pass case.
|
||||
* Always attempts to emit one fully interleaved MCU row ("iMCU" row).
|
||||
* Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
|
||||
*
|
||||
* NB: output_buf contains a plane for each component in image.
|
||||
*/
|
||||
|
||||
METHODDEF(int)
|
||||
output_data(j_decompress_ptr cinfo, _JSAMPIMAGE output_buf)
|
||||
{
|
||||
my_diff_ptr diff = (my_diff_ptr)cinfo->coef;
|
||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
||||
int ci, samp_rows, row;
|
||||
_JSAMPARRAY buffer;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Force some input to be done if we are getting ahead of the input. */
|
||||
while (cinfo->input_scan_number < cinfo->output_scan_number ||
|
||||
(cinfo->input_scan_number == cinfo->output_scan_number &&
|
||||
cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) {
|
||||
if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
|
||||
return JPEG_SUSPENDED;
|
||||
}
|
||||
|
||||
/* OK, output from the virtual arrays. */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Align the virtual buffer for this component. */
|
||||
buffer = (_JSAMPARRAY)(*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr)cinfo, diff->whole_image[ci],
|
||||
cinfo->output_iMCU_row * compptr->v_samp_factor,
|
||||
(JDIMENSION)compptr->v_samp_factor, FALSE);
|
||||
|
||||
if (cinfo->output_iMCU_row < last_iMCU_row)
|
||||
samp_rows = compptr->v_samp_factor;
|
||||
else {
|
||||
/* NB: can't use last_row_height here; it is input-side-dependent! */
|
||||
samp_rows = (int)(compptr->height_in_blocks % compptr->v_samp_factor);
|
||||
if (samp_rows == 0) samp_rows = compptr->v_samp_factor;
|
||||
}
|
||||
|
||||
for (row = 0; row < samp_rows; row++) {
|
||||
memcpy(output_buf[ci][row], buffer[row],
|
||||
compptr->width_in_blocks * sizeof(_JSAMPLE));
|
||||
}
|
||||
}
|
||||
|
||||
if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
|
||||
return JPEG_ROW_COMPLETED;
|
||||
return JPEG_SCAN_COMPLETED;
|
||||
}
|
||||
|
||||
#endif /* D_MULTISCAN_FILES_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize difference buffer controller.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
_jinit_d_diff_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_diff_ptr diff;
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
diff = (my_diff_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_diff_controller));
|
||||
cinfo->coef = (struct jpeg_d_coef_controller *)diff;
|
||||
diff->pub.start_input_pass = start_input_pass;
|
||||
diff->pub.start_output_pass = start_output_pass;
|
||||
|
||||
/* Create the [un]difference buffers. */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
diff->diff_buf[ci] =
|
||||
ALLOC_DARRAY(JPOOL_IMAGE,
|
||||
(JDIMENSION)jround_up((long)compptr->width_in_blocks,
|
||||
(long)compptr->h_samp_factor),
|
||||
(JDIMENSION)compptr->v_samp_factor);
|
||||
diff->undiff_buf[ci] =
|
||||
ALLOC_DARRAY(JPOOL_IMAGE,
|
||||
(JDIMENSION)jround_up((long)compptr->width_in_blocks,
|
||||
(long)compptr->h_samp_factor),
|
||||
(JDIMENSION)compptr->v_samp_factor);
|
||||
}
|
||||
|
||||
if (need_full_buffer) {
|
||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
||||
/* Allocate a full-image virtual array for each component. */
|
||||
int access_rows;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
access_rows = compptr->v_samp_factor;
|
||||
diff->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
|
||||
((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)access_rows);
|
||||
}
|
||||
diff->pub.consume_data = consume_data;
|
||||
diff->pub._decompress_data = output_data;
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else {
|
||||
diff->pub.consume_data = dummy_consume_data;
|
||||
diff->pub._decompress_data = decompress_data;
|
||||
diff->whole_image[0] = NULL; /* flag for no virtual arrays */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* D_LOSSLESS_SUPPORTED */
|
||||
|
|
@ -3,8 +3,10 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009-2011, 2016, 2018-2019, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2016, 2018-2019, 2022, D. R. Commander.
|
||||
* Copyright (C) 2018, Matthias Räncker.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
|
|
@ -24,8 +26,8 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdhuff.h" /* Declarations shared with jdphuff.c */
|
||||
#include "jpegcomp.h"
|
||||
#include "jdhuff.h" /* Declarations shared with jd*huff.c */
|
||||
#include "jpegapicomp.h"
|
||||
#include "jstdhuff.c"
|
||||
|
||||
|
||||
|
|
@ -134,7 +136,7 @@ start_pass_huff_decoder(j_decompress_ptr cinfo)
|
|||
* Compute the derived values for a Huffman table.
|
||||
* This routine also performs some validation checks on the table.
|
||||
*
|
||||
* Note this is also used by jdphuff.c.
|
||||
* Note this is also used by jdphuff.c and jdlhuff.c.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
|
|
@ -245,14 +247,14 @@ jpeg_make_d_derived_tbl(j_decompress_ptr cinfo, boolean isDC, int tblno,
|
|||
|
||||
/* Validate symbols as being reasonable.
|
||||
* For AC tables, we make no check, but accept all byte values 0..255.
|
||||
* For DC tables, we require the symbols to be in range 0..15.
|
||||
* (Tighter bounds could be applied depending on the data depth and mode,
|
||||
* but this is sufficient to ensure safe decoding.)
|
||||
* For DC tables, we require the symbols to be in range 0..15 in lossy mode
|
||||
* and 0..16 in lossless mode. (Tighter bounds could be applied depending on
|
||||
* the data depth and mode, but this is sufficient to ensure safe decoding.)
|
||||
*/
|
||||
if (isDC) {
|
||||
for (i = 0; i < numsymbols; i++) {
|
||||
int sym = htbl->huffval[i];
|
||||
if (sym < 0 || sym > 15)
|
||||
if (sym < 0 || sym > (cinfo->master->lossless ? 16 : 15))
|
||||
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
|
||||
}
|
||||
}
|
||||
|
|
@ -260,7 +262,7 @@ jpeg_make_d_derived_tbl(j_decompress_ptr cinfo, boolean isDC, int tblno,
|
|||
|
||||
|
||||
/*
|
||||
* Out-of-line code for bit fetching (shared with jdphuff.c).
|
||||
* Out-of-line code for bit fetching (shared with jdphuff.c and jdlhuff.c).
|
||||
* See jdhuff.h for info about usage.
|
||||
* Note: current values of get_buffer and bits_left are passed as parameters,
|
||||
* but are returned in the corresponding fields of the state struct.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010-2011, 2015-2016, 2021, D. R. Commander.
|
||||
* Copyright (C) 2018, Matthias Räncker.
|
||||
|
|
@ -10,8 +12,9 @@
|
|||
* 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.
|
||||
* that are shared between the sequential decoder (jdhuff.c), the progressive
|
||||
* decoder (jdphuff.c), and the lossless decoder (jdlhuff.c). No other modules
|
||||
* need to see these.
|
||||
*/
|
||||
|
||||
#include "jconfigint.h"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* jdicc.c
|
||||
*
|
||||
* Copyright (C) 1997-1998, Thomas G. Lane, Todd Newman.
|
||||
* Copyright (C) 2017, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file provides code to read International Color Consortium (ICC) device
|
||||
* profiles embedded in JFIF JPEG image files. The ICC has defined a standard
|
||||
* for including such data in JPEG "APP2" markers. The code given here does
|
||||
* not know anything about the internal structure of the ICC profile data; it
|
||||
* just knows how to get the profile data from a JPEG file while reading it.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jerror.h"
|
||||
|
||||
|
||||
#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */
|
||||
#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */
|
||||
|
||||
|
||||
/*
|
||||
* Handy subroutine to test whether a saved marker is an ICC profile marker.
|
||||
*/
|
||||
|
||||
LOCAL(boolean)
|
||||
marker_is_icc(jpeg_saved_marker_ptr marker)
|
||||
{
|
||||
return
|
||||
marker->marker == ICC_MARKER &&
|
||||
marker->data_length >= ICC_OVERHEAD_LEN &&
|
||||
/* verify the identifying string */
|
||||
marker->data[0] == 0x49 &&
|
||||
marker->data[1] == 0x43 &&
|
||||
marker->data[2] == 0x43 &&
|
||||
marker->data[3] == 0x5F &&
|
||||
marker->data[4] == 0x50 &&
|
||||
marker->data[5] == 0x52 &&
|
||||
marker->data[6] == 0x4F &&
|
||||
marker->data[7] == 0x46 &&
|
||||
marker->data[8] == 0x49 &&
|
||||
marker->data[9] == 0x4C &&
|
||||
marker->data[10] == 0x45 &&
|
||||
marker->data[11] == 0x0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* See if there was an ICC profile in the JPEG file being read; if so,
|
||||
* reassemble and return the profile data.
|
||||
*
|
||||
* TRUE is returned if an ICC profile was found, FALSE if not. If TRUE is
|
||||
* returned, *icc_data_ptr is set to point to the returned data, and
|
||||
* *icc_data_len is set to its length.
|
||||
*
|
||||
* IMPORTANT: the data at *icc_data_ptr is allocated with malloc() and must be
|
||||
* freed by the caller with free() when the caller no longer needs it.
|
||||
* (Alternatively, we could write this routine to use the IJG library's memory
|
||||
* allocator, so that the data would be freed implicitly when
|
||||
* jpeg_finish_decompress() is called. But it seems likely that many
|
||||
* applications will prefer to have the data stick around after decompression
|
||||
* finishes.)
|
||||
*/
|
||||
|
||||
GLOBAL(boolean)
|
||||
jpeg_read_icc_profile(j_decompress_ptr cinfo, JOCTET **icc_data_ptr,
|
||||
unsigned int *icc_data_len)
|
||||
{
|
||||
jpeg_saved_marker_ptr marker;
|
||||
int num_markers = 0;
|
||||
int seq_no;
|
||||
JOCTET *icc_data;
|
||||
unsigned int total_length;
|
||||
#define MAX_SEQ_NO 255 /* sufficient since marker numbers are bytes */
|
||||
char marker_present[MAX_SEQ_NO + 1]; /* 1 if marker found */
|
||||
unsigned int data_length[MAX_SEQ_NO + 1]; /* size of profile data in marker */
|
||||
unsigned int data_offset[MAX_SEQ_NO + 1]; /* offset for data in marker */
|
||||
|
||||
if (icc_data_ptr == NULL || icc_data_len == NULL)
|
||||
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
||||
if (cinfo->global_state < DSTATE_READY)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
*icc_data_ptr = NULL; /* avoid confusion if FALSE return */
|
||||
*icc_data_len = 0;
|
||||
|
||||
/* This first pass over the saved markers discovers whether there are
|
||||
* any ICC markers and verifies the consistency of the marker numbering.
|
||||
*/
|
||||
|
||||
for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++)
|
||||
marker_present[seq_no] = 0;
|
||||
|
||||
for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
|
||||
if (marker_is_icc(marker)) {
|
||||
if (num_markers == 0)
|
||||
num_markers = marker->data[13];
|
||||
else if (num_markers != marker->data[13]) {
|
||||
WARNMS(cinfo, JWRN_BOGUS_ICC); /* inconsistent num_markers fields */
|
||||
return FALSE;
|
||||
}
|
||||
seq_no = marker->data[12];
|
||||
if (seq_no <= 0 || seq_no > num_markers) {
|
||||
WARNMS(cinfo, JWRN_BOGUS_ICC); /* bogus sequence number */
|
||||
return FALSE;
|
||||
}
|
||||
if (marker_present[seq_no]) {
|
||||
WARNMS(cinfo, JWRN_BOGUS_ICC); /* duplicate sequence numbers */
|
||||
return FALSE;
|
||||
}
|
||||
marker_present[seq_no] = 1;
|
||||
data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_markers == 0)
|
||||
return FALSE;
|
||||
|
||||
/* Check for missing markers, count total space needed,
|
||||
* compute offset of each marker's part of the data.
|
||||
*/
|
||||
|
||||
total_length = 0;
|
||||
for (seq_no = 1; seq_no <= num_markers; seq_no++) {
|
||||
if (marker_present[seq_no] == 0) {
|
||||
WARNMS(cinfo, JWRN_BOGUS_ICC); /* missing sequence number */
|
||||
return FALSE;
|
||||
}
|
||||
data_offset[seq_no] = total_length;
|
||||
total_length += data_length[seq_no];
|
||||
}
|
||||
|
||||
if (total_length == 0) {
|
||||
WARNMS(cinfo, JWRN_BOGUS_ICC); /* found only empty markers? */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Allocate space for assembled data */
|
||||
icc_data = (JOCTET *)malloc(total_length * sizeof(JOCTET));
|
||||
if (icc_data == NULL)
|
||||
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 11); /* oops, out of memory */
|
||||
|
||||
/* and fill it in */
|
||||
for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
|
||||
if (marker_is_icc(marker)) {
|
||||
JOCTET FAR *src_ptr;
|
||||
JOCTET *dst_ptr;
|
||||
unsigned int length;
|
||||
seq_no = marker->data[12];
|
||||
dst_ptr = icc_data + data_offset[seq_no];
|
||||
src_ptr = marker->data + ICC_OVERHEAD_LEN;
|
||||
length = data_length[seq_no];
|
||||
while (length--) {
|
||||
*dst_ptr++ = *src_ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*icc_data_ptr = icc_data;
|
||||
*icc_data_len = total_length;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2016, 2018, 2022, D. R. Commander.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
|
|
@ -11,14 +13,15 @@
|
|||
*
|
||||
* 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.
|
||||
* processing (marker reading and coefficient/difference decoding).
|
||||
* The actual input reading is done in jdmarker.c, jdhuff.c, jdphuff.c,
|
||||
* and jdlhuff.c.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jpegcomp.h"
|
||||
#include "jpegapicomp.h"
|
||||
|
||||
|
||||
/* Private state */
|
||||
|
|
@ -46,6 +49,7 @@ initial_setup(j_decompress_ptr cinfo)
|
|||
{
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
|
||||
/* Make sure image isn't bigger than I can handle */
|
||||
if ((long)cinfo->image_height > (long)JPEG_MAX_DIMENSION ||
|
||||
|
|
@ -53,7 +57,12 @@ initial_setup(j_decompress_ptr cinfo)
|
|||
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)
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
if (cinfo->data_precision != 8 && cinfo->data_precision != 12 &&
|
||||
cinfo->data_precision != 16)
|
||||
#else
|
||||
if (cinfo->data_precision != 8 && cinfo->data_precision != 12)
|
||||
#endif
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
/* Check that number of components won't exceed internal array sizes */
|
||||
|
|
@ -78,36 +87,36 @@ initial_setup(j_decompress_ptr cinfo)
|
|||
}
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80
|
||||
cinfo->block_size = DCTSIZE;
|
||||
cinfo->block_size = data_unit;
|
||||
cinfo->natural_order = jpeg_natural_order;
|
||||
cinfo->lim_Se = DCTSIZE2 - 1;
|
||||
#endif
|
||||
|
||||
/* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE.
|
||||
* In the full decompressor, this will be overridden by jdmaster.c;
|
||||
/* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE in lossy
|
||||
* mode. 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.
|
||||
*/
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
cinfo->min_DCT_h_scaled_size = cinfo->min_DCT_v_scaled_size = DCTSIZE;
|
||||
cinfo->min_DCT_h_scaled_size = cinfo->min_DCT_v_scaled_size = data_unit;
|
||||
#else
|
||||
cinfo->min_DCT_scaled_size = DCTSIZE;
|
||||
cinfo->min_DCT_scaled_size = data_unit;
|
||||
#endif
|
||||
|
||||
/* Compute dimensions of components */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = DCTSIZE;
|
||||
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = data_unit;
|
||||
#else
|
||||
compptr->DCT_scaled_size = DCTSIZE;
|
||||
compptr->DCT_scaled_size = data_unit;
|
||||
#endif
|
||||
/* Size in DCT blocks */
|
||||
/* Size in data units */
|
||||
compptr->width_in_blocks = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * (long)compptr->h_samp_factor,
|
||||
(long)(cinfo->max_h_samp_factor * DCTSIZE));
|
||||
(long)(cinfo->max_h_samp_factor * data_unit));
|
||||
compptr->height_in_blocks = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * (long)compptr->v_samp_factor,
|
||||
(long)(cinfo->max_v_samp_factor * DCTSIZE));
|
||||
(long)(cinfo->max_v_samp_factor * data_unit));
|
||||
/* Set the first and last MCU columns to decompress from multi-scan images.
|
||||
* By default, decompress all of the MCU columns.
|
||||
*/
|
||||
|
|
@ -133,7 +142,7 @@ initial_setup(j_decompress_ptr cinfo)
|
|||
/* 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));
|
||||
(long)(cinfo->max_v_samp_factor * data_unit));
|
||||
|
||||
/* Decide whether file contains multiple scans */
|
||||
if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode)
|
||||
|
|
@ -150,6 +159,7 @@ per_scan_setup(j_decompress_ptr cinfo)
|
|||
{
|
||||
int ci, mcublks, tmp;
|
||||
jpeg_component_info *compptr;
|
||||
int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
|
||||
|
||||
if (cinfo->comps_in_scan == 1) {
|
||||
|
||||
|
|
@ -160,14 +170,14 @@ per_scan_setup(j_decompress_ptr cinfo)
|
|||
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 */
|
||||
/* For noninterleaved scan, always one data unit 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.
|
||||
* as the number of data unit 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;
|
||||
|
|
@ -187,22 +197,22 @@ per_scan_setup(j_decompress_ptr cinfo)
|
|||
/* Overall image size in MCUs */
|
||||
cinfo->MCUs_per_row = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width,
|
||||
(long)(cinfo->max_h_samp_factor * DCTSIZE));
|
||||
(long)(cinfo->max_h_samp_factor * data_unit));
|
||||
cinfo->MCU_rows_in_scan = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height,
|
||||
(long)(cinfo->max_v_samp_factor * DCTSIZE));
|
||||
(long)(cinfo->max_v_samp_factor * data_unit));
|
||||
|
||||
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 */
|
||||
/* Sampling factors give # of data units 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 */
|
||||
/* Figure number of non-dummy data units 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;
|
||||
|
|
@ -281,7 +291,8 @@ METHODDEF(void)
|
|||
start_input_pass(j_decompress_ptr cinfo)
|
||||
{
|
||||
per_scan_setup(cinfo);
|
||||
latch_quant_tables(cinfo);
|
||||
if (!cinfo->master->lossless)
|
||||
latch_quant_tables(cinfo);
|
||||
(*cinfo->entropy->start_pass) (cinfo);
|
||||
(*cinfo->coef->start_input_pass) (cinfo);
|
||||
cinfo->inputctl->consume_input = cinfo->coef->consume_data;
|
||||
|
|
@ -290,8 +301,8 @@ start_input_pass(j_decompress_ptr cinfo)
|
|||
|
||||
/*
|
||||
* 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.
|
||||
* This is called by the coefficient or difference controller after it's read
|
||||
* all the expected data of the scan.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
|
|
@ -307,8 +318,8 @@ finish_input_pass(j_decompress_ptr cinfo)
|
|||
* 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.
|
||||
* coefficient or difference controller's consume_data routine, depending on
|
||||
* whether we are reading a compressed data segment or inter-segment markers.
|
||||
*/
|
||||
|
||||
METHODDEF(int)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
* jdlhuff.c
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file contains Huffman entropy decoding routines for lossless JPEG.
|
||||
*
|
||||
* Much of the complexity here has to do with supporting input suspension.
|
||||
* If the data source module demands suspension, we want to be able to back
|
||||
* up to the start of the current MCU. To do this, we copy state variables
|
||||
* into local working storage, and update them back to the permanent
|
||||
* storage only upon successful completion of an MCU.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jlossls.h" /* Private declarations for lossless codec */
|
||||
#include "jdhuff.h" /* Declarations shared with jd*huff.c */
|
||||
|
||||
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
|
||||
typedef struct {
|
||||
int ci, yoffset, MCU_width;
|
||||
} lhd_output_ptr_info;
|
||||
|
||||
/*
|
||||
* Expanded entropy decoder object for Huffman decoding in lossless mode.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_entropy_decoder pub; /* public fields */
|
||||
|
||||
/* These fields are loaded into local variables at start of each MCU.
|
||||
* In case of suspension, we exit WITHOUT updating them.
|
||||
*/
|
||||
bitread_perm_state bitstate; /* Bit buffer at start of MCU */
|
||||
|
||||
/* Pointers to derived tables (these workspaces have image lifespan) */
|
||||
d_derived_tbl *derived_tbls[NUM_HUFF_TBLS];
|
||||
|
||||
/* Precalculated info set up by start_pass for use in decode_mcus: */
|
||||
|
||||
/* Pointers to derived tables to be used for each data unit within an MCU */
|
||||
d_derived_tbl *cur_tbls[D_MAX_BLOCKS_IN_MCU];
|
||||
|
||||
/* Pointers to the proper output difference row for each group of data units
|
||||
* within an MCU. For each component, there are Vi groups of Hi data units.
|
||||
*/
|
||||
JDIFFROW output_ptr[D_MAX_BLOCKS_IN_MCU];
|
||||
|
||||
/* Number of output pointers in use for the current MCU. This is the sum
|
||||
* of all Vi in the MCU.
|
||||
*/
|
||||
int num_output_ptrs;
|
||||
|
||||
/* Information used for positioning the output pointers within the output
|
||||
* difference rows.
|
||||
*/
|
||||
lhd_output_ptr_info output_ptr_info[D_MAX_BLOCKS_IN_MCU];
|
||||
|
||||
/* Index of the proper output pointer for each data unit within an MCU */
|
||||
int output_ptr_index[D_MAX_BLOCKS_IN_MCU];
|
||||
|
||||
} lhuff_entropy_decoder;
|
||||
|
||||
typedef lhuff_entropy_decoder *lhuff_entropy_ptr;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a Huffman-compressed scan.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_lhuff_decoder(j_decompress_ptr cinfo)
|
||||
{
|
||||
lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
|
||||
int ci, dctbl, sampn, ptrn, yoffset, xoffset;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
dctbl = compptr->dc_tbl_no;
|
||||
/* Make sure requested tables are present */
|
||||
if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS ||
|
||||
cinfo->dc_huff_tbl_ptrs[dctbl] == NULL)
|
||||
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
|
||||
/* Compute derived values for Huffman tables */
|
||||
/* We may do this more than once for a table, but it's not expensive */
|
||||
jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl,
|
||||
&entropy->derived_tbls[dctbl]);
|
||||
}
|
||||
|
||||
/* Precalculate decoding info for each sample in an MCU of this scan */
|
||||
for (sampn = 0, ptrn = 0; sampn < cinfo->blocks_in_MCU;) {
|
||||
compptr = cinfo->cur_comp_info[cinfo->MCU_membership[sampn]];
|
||||
ci = compptr->component_index;
|
||||
for (yoffset = 0; yoffset < compptr->MCU_height; yoffset++, ptrn++) {
|
||||
/* Precalculate the setup info for each output pointer */
|
||||
entropy->output_ptr_info[ptrn].ci = ci;
|
||||
entropy->output_ptr_info[ptrn].yoffset = yoffset;
|
||||
entropy->output_ptr_info[ptrn].MCU_width = compptr->MCU_width;
|
||||
for (xoffset = 0; xoffset < compptr->MCU_width; xoffset++, sampn++) {
|
||||
/* Precalculate the output pointer index for each sample */
|
||||
entropy->output_ptr_index[sampn] = ptrn;
|
||||
/* Precalculate which table to use for each sample */
|
||||
entropy->cur_tbls[sampn] = entropy->derived_tbls[compptr->dc_tbl_no];
|
||||
}
|
||||
}
|
||||
}
|
||||
entropy->num_output_ptrs = ptrn;
|
||||
|
||||
/* Initialize bitread state variables */
|
||||
entropy->bitstate.bits_left = 0;
|
||||
entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
|
||||
entropy->pub.insufficient_data = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Figure F.12: extend sign bit.
|
||||
* On some machines, a shift and add will be faster than a table lookup.
|
||||
*/
|
||||
|
||||
#define AVOID_TABLES
|
||||
#ifdef AVOID_TABLES
|
||||
|
||||
#define NEG_1 ((unsigned int)-1)
|
||||
#define HUFF_EXTEND(x, s) \
|
||||
((x) + ((((x) - (1 << ((s) - 1))) >> 31) & (((NEG_1) << (s)) + 1)))
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
static const int extend_offset[16] = { /* entry n is (-1 << n) + 1 */
|
||||
0, ((-1) << 1) + 1, ((-1) << 2) + 1, ((-1) << 3) + 1, ((-1) << 4) + 1,
|
||||
((-1) << 5) + 1, ((-1) << 6) + 1, ((-1) << 7) + 1, ((-1) << 8) + 1,
|
||||
((-1) << 9) + 1, ((-1) << 10) + 1, ((-1) << 11) + 1, ((-1) << 12) + 1,
|
||||
((-1) << 13) + 1, ((-1) << 14) + 1, ((-1) << 15) + 1
|
||||
};
|
||||
|
||||
#endif /* AVOID_TABLES */
|
||||
|
||||
|
||||
/*
|
||||
* Check for a restart marker & resynchronize decoder.
|
||||
* Returns FALSE if must suspend.
|
||||
*/
|
||||
|
||||
LOCAL(boolean)
|
||||
process_restart(j_decompress_ptr cinfo)
|
||||
{
|
||||
lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
|
||||
|
||||
/* Throw away any unused bits remaining in bit buffer; */
|
||||
/* include any full bytes in next_marker's count of discarded bytes */
|
||||
cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
|
||||
entropy->bitstate.bits_left = 0;
|
||||
|
||||
/* Advance past the RSTn marker */
|
||||
if (!(*cinfo->marker->read_restart_marker) (cinfo))
|
||||
return FALSE;
|
||||
|
||||
/* Reset out-of-data flag, unless read_restart_marker left us smack up
|
||||
* against a marker. In that case we will end up treating the next data
|
||||
* segment as empty, and we can avoid producing bogus output pixels by
|
||||
* leaving the flag set.
|
||||
*/
|
||||
if (cinfo->unread_marker == 0)
|
||||
entropy->pub.insufficient_data = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Decode and return nMCU MCUs' worth of Huffman-compressed differences.
|
||||
* Each MCU is also disassembled and placed accordingly in diff_buf.
|
||||
*
|
||||
* MCU_col_num specifies the column of the first MCU being requested within
|
||||
* the MCU row. This tells us where to position the output row pointers in
|
||||
* diff_buf.
|
||||
*
|
||||
* Returns the number of MCUs decoded. This may be less than nMCU MCUs if
|
||||
* data source requested suspension. In that case no changes have been made
|
||||
* to permanent state. (Exception: some output differences may already have
|
||||
* been assigned. This is harmless for this module, since we'll just
|
||||
* re-assign them on the next call.)
|
||||
*/
|
||||
|
||||
METHODDEF(JDIMENSION)
|
||||
decode_mcus(j_decompress_ptr cinfo, JDIFFIMAGE diff_buf,
|
||||
JDIMENSION MCU_row_num, JDIMENSION MCU_col_num, JDIMENSION nMCU)
|
||||
{
|
||||
lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
|
||||
int sampn, ci, yoffset, MCU_width, ptrn;
|
||||
JDIMENSION mcu_num;
|
||||
BITREAD_STATE_VARS;
|
||||
|
||||
/* Set output pointer locations based on MCU_col_num */
|
||||
for (ptrn = 0; ptrn < entropy->num_output_ptrs; ptrn++) {
|
||||
ci = entropy->output_ptr_info[ptrn].ci;
|
||||
yoffset = entropy->output_ptr_info[ptrn].yoffset;
|
||||
MCU_width = entropy->output_ptr_info[ptrn].MCU_width;
|
||||
entropy->output_ptr[ptrn] =
|
||||
diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we've run out of data, zero out the buffers and return.
|
||||
* By resetting the undifferencer, the output samples will be CENTERJSAMPLE.
|
||||
*
|
||||
* NB: We should find a way to do this without interacting with the
|
||||
* undifferencer module directly.
|
||||
*/
|
||||
if (entropy->pub.insufficient_data) {
|
||||
for (ptrn = 0; ptrn < entropy->num_output_ptrs; ptrn++)
|
||||
jzero_far((void FAR *)entropy->output_ptr[ptrn],
|
||||
nMCU * entropy->output_ptr_info[ptrn].MCU_width *
|
||||
sizeof(JDIFF));
|
||||
|
||||
(*cinfo->idct->start_pass) (cinfo);
|
||||
|
||||
} else {
|
||||
|
||||
/* Load up working state */
|
||||
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
|
||||
|
||||
/* Outer loop handles the number of MCUs requested */
|
||||
|
||||
for (mcu_num = 0; mcu_num < nMCU; mcu_num++) {
|
||||
|
||||
/* Inner loop handles the samples in the MCU */
|
||||
for (sampn = 0; sampn < cinfo->blocks_in_MCU; sampn++) {
|
||||
d_derived_tbl *dctbl = entropy->cur_tbls[sampn];
|
||||
register int s, r;
|
||||
|
||||
/* Section H.2.2: decode the sample difference */
|
||||
HUFF_DECODE(s, br_state, dctbl, return mcu_num, label1);
|
||||
if (s) {
|
||||
if (s == 16) /* special case: always output 32768 */
|
||||
s = 32768;
|
||||
else { /* normal case: fetch subsequent bits */
|
||||
CHECK_BIT_BUFFER(br_state, s, return mcu_num);
|
||||
r = GET_BITS(s);
|
||||
s = HUFF_EXTEND(r, s);
|
||||
}
|
||||
}
|
||||
|
||||
/* Output the sample difference */
|
||||
*entropy->output_ptr[entropy->output_ptr_index[sampn]]++ = (JDIFF)s;
|
||||
}
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
|
||||
}
|
||||
}
|
||||
|
||||
return nMCU;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for lossless mode Huffman entropy decoding.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_lhuff_decoder(j_decompress_ptr cinfo)
|
||||
{
|
||||
lhuff_entropy_ptr entropy;
|
||||
int i;
|
||||
|
||||
entropy = (lhuff_entropy_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(lhuff_entropy_decoder));
|
||||
cinfo->entropy = (struct jpeg_entropy_decoder *)entropy;
|
||||
entropy->pub.start_pass = start_pass_lhuff_decoder;
|
||||
entropy->pub.decode_mcus = decode_mcus;
|
||||
entropy->pub.process_restart = process_restart;
|
||||
|
||||
/* Mark tables unallocated */
|
||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
||||
entropy->derived_tbls[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* D_LOSSLESS_SUPPORTED */
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
* jdlossls.c
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1998, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This file contains prediction, sample undifferencing, point transform, and
|
||||
* sample scaling routines for the lossless JPEG decompressor.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jlossls.h"
|
||||
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
|
||||
|
||||
/**************** Sample undifferencing (reconstruction) *****************/
|
||||
|
||||
/*
|
||||
* In order to avoid a performance penalty for checking which predictor is
|
||||
* being used and which row is being processed for each call of the
|
||||
* undifferencer, and to promote optimization, we have separate undifferencing
|
||||
* functions for each predictor selection value.
|
||||
*
|
||||
* We are able to avoid duplicating source code by implementing the predictors
|
||||
* and undifferencers as macros. Each of the undifferencing functions is
|
||||
* simply a wrapper around an UNDIFFERENCE macro with the appropriate PREDICTOR
|
||||
* macro passed as an argument.
|
||||
*/
|
||||
|
||||
/* Predictor for the first column of the first row: 2^(P-Pt-1) */
|
||||
#define INITIAL_PREDICTORx (1 << (cinfo->data_precision - cinfo->Al - 1))
|
||||
|
||||
/* Predictor for the first column of the remaining rows: Rb */
|
||||
#define INITIAL_PREDICTOR2 prev_row[0]
|
||||
|
||||
|
||||
/*
|
||||
* 1-Dimensional undifferencer routine.
|
||||
*
|
||||
* This macro implements the 1-D horizontal predictor (1). INITIAL_PREDICTOR
|
||||
* is used as the special case predictor for the first column, which must be
|
||||
* either INITIAL_PREDICTOR2 or INITIAL_PREDICTORx. The remaining samples
|
||||
* use PREDICTOR1.
|
||||
*
|
||||
* The reconstructed sample is supposed to be calculated modulo 2^16, so we
|
||||
* logically AND the result with 0xFFFF.
|
||||
*/
|
||||
|
||||
#define UNDIFFERENCE_1D(INITIAL_PREDICTOR) \
|
||||
int Ra; \
|
||||
\
|
||||
Ra = (*diff_buf++ + INITIAL_PREDICTOR) & 0xFFFF; \
|
||||
*undiff_buf++ = Ra; \
|
||||
\
|
||||
while (--width) { \
|
||||
Ra = (*diff_buf++ + PREDICTOR1) & 0xFFFF; \
|
||||
*undiff_buf++ = Ra; \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 2-Dimensional undifferencer routine.
|
||||
*
|
||||
* This macro implements the 2-D horizontal predictors (#2-7). PREDICTOR2 is
|
||||
* used as the special case predictor for the first column. The remaining
|
||||
* samples use PREDICTOR, which is a function of Ra, Rb, and Rc.
|
||||
*
|
||||
* Because prev_row and output_buf may point to the same storage area (in an
|
||||
* interleaved image with Vi=1, for example), we must take care to buffer Rb/Rc
|
||||
* before writing the current reconstructed sample value into output_buf.
|
||||
*
|
||||
* The reconstructed sample is supposed to be calculated modulo 2^16, so we
|
||||
* logically AND the result with 0xFFFF.
|
||||
*/
|
||||
|
||||
#define UNDIFFERENCE_2D(PREDICTOR) \
|
||||
int Ra, Rb, Rc; \
|
||||
\
|
||||
Rb = *prev_row++; \
|
||||
Ra = (*diff_buf++ + PREDICTOR2) & 0xFFFF; \
|
||||
*undiff_buf++ = Ra; \
|
||||
\
|
||||
while (--width) { \
|
||||
Rc = Rb; \
|
||||
Rb = *prev_row++; \
|
||||
Ra = (*diff_buf++ + PREDICTOR) & 0xFFFF; \
|
||||
*undiff_buf++ = Ra; \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Undifferencers for the second and subsequent rows in a scan or restart
|
||||
* interval. The first sample in the row is undifferenced using the vertical
|
||||
* predictor (2). The rest of the samples are undifferenced using the
|
||||
* predictor specified in the scan header.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_undifference1(j_decompress_ptr cinfo, int comp_index,
|
||||
JDIFFROW diff_buf, JDIFFROW prev_row,
|
||||
JDIFFROW undiff_buf, JDIMENSION width)
|
||||
{
|
||||
UNDIFFERENCE_1D(INITIAL_PREDICTOR2);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_undifference2(j_decompress_ptr cinfo, int comp_index,
|
||||
JDIFFROW diff_buf, JDIFFROW prev_row,
|
||||
JDIFFROW undiff_buf, JDIMENSION width)
|
||||
{
|
||||
UNDIFFERENCE_2D(PREDICTOR2);
|
||||
(void)(Rc);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_undifference3(j_decompress_ptr cinfo, int comp_index,
|
||||
JDIFFROW diff_buf, JDIFFROW prev_row,
|
||||
JDIFFROW undiff_buf, JDIMENSION width)
|
||||
{
|
||||
UNDIFFERENCE_2D(PREDICTOR3);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_undifference4(j_decompress_ptr cinfo, int comp_index,
|
||||
JDIFFROW diff_buf, JDIFFROW prev_row,
|
||||
JDIFFROW undiff_buf, JDIMENSION width)
|
||||
{
|
||||
UNDIFFERENCE_2D(PREDICTOR4);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_undifference5(j_decompress_ptr cinfo, int comp_index,
|
||||
JDIFFROW diff_buf, JDIFFROW prev_row,
|
||||
JDIFFROW undiff_buf, JDIMENSION width)
|
||||
{
|
||||
UNDIFFERENCE_2D(PREDICTOR5);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_undifference6(j_decompress_ptr cinfo, int comp_index,
|
||||
JDIFFROW diff_buf, JDIFFROW prev_row,
|
||||
JDIFFROW undiff_buf, JDIMENSION width)
|
||||
{
|
||||
UNDIFFERENCE_2D(PREDICTOR6);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_undifference7(j_decompress_ptr cinfo, int comp_index,
|
||||
JDIFFROW diff_buf, JDIFFROW prev_row,
|
||||
JDIFFROW undiff_buf, JDIMENSION width)
|
||||
{
|
||||
UNDIFFERENCE_2D(PREDICTOR7);
|
||||
(void)(Rc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Undifferencer for the first row in a scan or restart interval. The first
|
||||
* sample in the row is undifferenced using the special predictor constant
|
||||
* x=2^(P-Pt-1). The rest of the samples are undifferenced using the
|
||||
* 1-D horizontal predictor (1).
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
jpeg_undifference_first_row(j_decompress_ptr cinfo, int comp_index,
|
||||
JDIFFROW diff_buf, JDIFFROW prev_row,
|
||||
JDIFFROW undiff_buf, JDIMENSION width)
|
||||
{
|
||||
lossless_decomp_ptr losslessd = (lossless_decomp_ptr)cinfo->idct;
|
||||
|
||||
UNDIFFERENCE_1D(INITIAL_PREDICTORx);
|
||||
|
||||
/*
|
||||
* Now that we have undifferenced the first row, we want to use the
|
||||
* undifferencer that corresponds to the predictor specified in the
|
||||
* scan header.
|
||||
*/
|
||||
switch (cinfo->Ss) {
|
||||
case 1:
|
||||
losslessd->predict_undifference[comp_index] = jpeg_undifference1;
|
||||
break;
|
||||
case 2:
|
||||
losslessd->predict_undifference[comp_index] = jpeg_undifference2;
|
||||
break;
|
||||
case 3:
|
||||
losslessd->predict_undifference[comp_index] = jpeg_undifference3;
|
||||
break;
|
||||
case 4:
|
||||
losslessd->predict_undifference[comp_index] = jpeg_undifference4;
|
||||
break;
|
||||
case 5:
|
||||
losslessd->predict_undifference[comp_index] = jpeg_undifference5;
|
||||
break;
|
||||
case 6:
|
||||
losslessd->predict_undifference[comp_index] = jpeg_undifference6;
|
||||
break;
|
||||
case 7:
|
||||
losslessd->predict_undifference[comp_index] = jpeg_undifference7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************** Sample upscaling by 2^Pt ************************/
|
||||
|
||||
METHODDEF(void)
|
||||
simple_upscale(j_decompress_ptr cinfo,
|
||||
JDIFFROW diff_buf, _JSAMPROW output_buf, JDIMENSION width)
|
||||
{
|
||||
do {
|
||||
*output_buf++ = (_JSAMPLE)(*diff_buf++ << cinfo->Al);
|
||||
} while (--width);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
noscale(j_decompress_ptr cinfo,
|
||||
JDIFFROW diff_buf, _JSAMPROW output_buf, JDIMENSION width)
|
||||
{
|
||||
do {
|
||||
*output_buf++ = (_JSAMPLE)(*diff_buf++);
|
||||
} while (--width);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for an input processing pass.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_lossless(j_decompress_ptr cinfo)
|
||||
{
|
||||
lossless_decomp_ptr losslessd = (lossless_decomp_ptr)cinfo->idct;
|
||||
int ci;
|
||||
|
||||
/* Check that the scan parameters Ss, Se, Ah, Al are OK for lossless JPEG.
|
||||
*
|
||||
* Ss is the predictor selection value (psv). Legal values for sequential
|
||||
* lossless JPEG are: 1 <= psv <= 7.
|
||||
*
|
||||
* Se and Ah are not used and should be zero.
|
||||
*
|
||||
* Al specifies the point transform (Pt).
|
||||
* Legal values are: 0 <= Pt <= (data precision - 1).
|
||||
*/
|
||||
if (cinfo->Ss < 1 || cinfo->Ss > 7 ||
|
||||
cinfo->Se != 0 || cinfo->Ah != 0 ||
|
||||
cinfo->Al < 0 || cinfo->Al >= cinfo->data_precision)
|
||||
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
|
||||
cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
|
||||
|
||||
/* Set undifference functions to first row function */
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
losslessd->predict_undifference[ci] = jpeg_undifference_first_row;
|
||||
|
||||
/* Set scaler function based on Pt */
|
||||
if (cinfo->Al)
|
||||
losslessd->scaler_scale = simple_upscale;
|
||||
else
|
||||
losslessd->scaler_scale = noscale;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the lossless decompressor.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
_jinit_lossless_decompressor(j_decompress_ptr cinfo)
|
||||
{
|
||||
lossless_decomp_ptr losslessd;
|
||||
|
||||
/* Create subobject in permanent pool */
|
||||
losslessd = (lossless_decomp_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,
|
||||
sizeof(jpeg_lossless_decompressor));
|
||||
cinfo->idct = (struct jpeg_inverse_dct *)losslessd;
|
||||
losslessd->pub.start_pass = start_pass_lossless;
|
||||
}
|
||||
|
||||
#endif /* D_LOSSLESS_SUPPORTED */
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2016, D. R. Commander.
|
||||
* Copyright (C) 2010, 2016, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -20,12 +20,15 @@
|
|||
#include "jdmainct.h"
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
|
||||
|
||||
/*
|
||||
* In the current system design, the main buffer need never be a full-image
|
||||
* buffer; any full-height buffers will be found inside the coefficient or
|
||||
* postprocessing controllers. Nonetheless, the main controller is not
|
||||
* trivial. Its responsibility is to provide context rows for upsampling/
|
||||
* rescaling, and doing this in an efficient fashion is a bit tricky.
|
||||
* buffer; any full-height buffers will be found inside the coefficient,
|
||||
* difference, or postprocessing controllers. Nonetheless, the main controller
|
||||
* is not trivial. Its responsibility is to provide context rows for
|
||||
* upsampling/rescaling, and doing this in an efficient fashion is a bit
|
||||
* tricky.
|
||||
*
|
||||
* Postprocessor input data is counted in "row groups". A row group
|
||||
* is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
|
||||
|
|
@ -37,20 +40,20 @@
|
|||
* row group (times any additional scale factor that the upsampler is
|
||||
* applying).
|
||||
*
|
||||
* The coefficient controller will deliver data to us one iMCU row at a time;
|
||||
* each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or
|
||||
* exactly min_DCT_scaled_size row groups. (This amount of data corresponds
|
||||
* to one row of MCUs when the image is fully interleaved.) Note that the
|
||||
* number of sample rows varies across components, but the number of row
|
||||
* groups does not. Some garbage sample rows may be included in the last iMCU
|
||||
* row at the bottom of the image.
|
||||
* The coefficient or difference controller will deliver data to us one iMCU
|
||||
* row at a time; each iMCU row contains v_samp_factor * DCT_scaled_size sample
|
||||
* rows, or exactly min_DCT_scaled_size row groups. (This amount of data
|
||||
* corresponds to one row of MCUs when the image is fully interleaved.) Note
|
||||
* that the number of sample rows varies across components, but the number of
|
||||
* row groups does not. Some garbage sample rows may be included in the last
|
||||
* iMCU row at the bottom of the image.
|
||||
*
|
||||
* Depending on the vertical scaling algorithm used, the upsampler may need
|
||||
* access to the sample row(s) above and below its current input row group.
|
||||
* The upsampler is required to set need_context_rows TRUE at global selection
|
||||
* time if so. When need_context_rows is FALSE, this controller can simply
|
||||
* obtain one iMCU row at a time from the coefficient controller and dole it
|
||||
* out as row groups to the postprocessor.
|
||||
* obtain one iMCU row at a time from the coefficient or difference controller
|
||||
* and dole it out as row groups to the postprocessor.
|
||||
*
|
||||
* When need_context_rows is TRUE, this controller guarantees that the buffer
|
||||
* passed to postprocessing contains at least one row group's worth of samples
|
||||
|
|
@ -113,16 +116,16 @@
|
|||
|
||||
/* Forward declarations */
|
||||
METHODDEF(void) process_data_simple_main(j_decompress_ptr cinfo,
|
||||
JSAMPARRAY output_buf,
|
||||
_JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail);
|
||||
METHODDEF(void) process_data_context_main(j_decompress_ptr cinfo,
|
||||
JSAMPARRAY output_buf,
|
||||
_JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail);
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
METHODDEF(void) process_data_crank_post(j_decompress_ptr cinfo,
|
||||
JSAMPARRAY output_buf,
|
||||
_JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail);
|
||||
#endif
|
||||
|
|
@ -138,14 +141,15 @@ alloc_funny_pointers(j_decompress_ptr cinfo)
|
|||
int ci, rgroup;
|
||||
int M = cinfo->_min_DCT_scaled_size;
|
||||
jpeg_component_info *compptr;
|
||||
JSAMPARRAY xbuf;
|
||||
_JSAMPARRAY xbuf;
|
||||
|
||||
/* Get top-level space for component array pointers.
|
||||
* We alloc both arrays with one call to save a few cycles.
|
||||
*/
|
||||
main_ptr->xbuffer[0] = (JSAMPIMAGE)
|
||||
main_ptr->xbuffer[0] = (_JSAMPIMAGE)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
cinfo->num_components * 2 * sizeof(JSAMPARRAY));
|
||||
cinfo->num_components * 2 *
|
||||
sizeof(_JSAMPARRAY));
|
||||
main_ptr->xbuffer[1] = main_ptr->xbuffer[0] + cinfo->num_components;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
|
|
@ -155,9 +159,9 @@ alloc_funny_pointers(j_decompress_ptr cinfo)
|
|||
/* Get space for pointer lists --- M+4 row groups in each list.
|
||||
* We alloc both pointer lists with one call to save a few cycles.
|
||||
*/
|
||||
xbuf = (JSAMPARRAY)
|
||||
xbuf = (_JSAMPARRAY)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
2 * (rgroup * (M + 4)) * sizeof(JSAMPROW));
|
||||
2 * (rgroup * (M + 4)) * sizeof(_JSAMPROW));
|
||||
xbuf += rgroup; /* want one row group at negative offsets */
|
||||
main_ptr->xbuffer[0][ci] = xbuf;
|
||||
xbuf += rgroup * (M + 4);
|
||||
|
|
@ -179,7 +183,7 @@ make_funny_pointers(j_decompress_ptr cinfo)
|
|||
int ci, i, rgroup;
|
||||
int M = cinfo->_min_DCT_scaled_size;
|
||||
jpeg_component_info *compptr;
|
||||
JSAMPARRAY buf, xbuf0, xbuf1;
|
||||
_JSAMPARRAY buf, xbuf0, xbuf1;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
|
|
@ -219,7 +223,7 @@ set_bottom_pointers(j_decompress_ptr cinfo)
|
|||
my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
|
||||
int ci, i, rgroup, iMCUheight, rows_left;
|
||||
jpeg_component_info *compptr;
|
||||
JSAMPARRAY xbuf;
|
||||
_JSAMPARRAY xbuf;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
|
|
@ -258,14 +262,14 @@ start_pass_main(j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
|
|||
switch (pass_mode) {
|
||||
case JBUF_PASS_THRU:
|
||||
if (cinfo->upsample->need_context_rows) {
|
||||
main_ptr->pub.process_data = process_data_context_main;
|
||||
main_ptr->pub._process_data = process_data_context_main;
|
||||
make_funny_pointers(cinfo); /* Create the xbuffer[] lists */
|
||||
main_ptr->whichptr = 0; /* Read first iMCU row into xbuffer[0] */
|
||||
main_ptr->context_state = CTX_PREPARE_FOR_IMCU;
|
||||
main_ptr->iMCU_row_ctr = 0;
|
||||
} else {
|
||||
/* Simple case with no context needed */
|
||||
main_ptr->pub.process_data = process_data_simple_main;
|
||||
main_ptr->pub._process_data = process_data_simple_main;
|
||||
}
|
||||
main_ptr->buffer_full = FALSE; /* Mark buffer empty */
|
||||
main_ptr->rowgroup_ctr = 0;
|
||||
|
|
@ -273,7 +277,7 @@ start_pass_main(j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
|
|||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
case JBUF_CRANK_DEST:
|
||||
/* For last pass of 2-pass quantization, just crank the postprocessor */
|
||||
main_ptr->pub.process_data = process_data_crank_post;
|
||||
main_ptr->pub._process_data = process_data_crank_post;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
|
@ -289,7 +293,7 @@ start_pass_main(j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
process_data_simple_main(j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
||||
process_data_simple_main(j_decompress_ptr cinfo, _JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
|
||||
{
|
||||
my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
|
||||
|
|
@ -297,7 +301,7 @@ process_data_simple_main(j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
|||
|
||||
/* Read input data if we haven't filled the main buffer yet */
|
||||
if (!main_ptr->buffer_full) {
|
||||
if (!(*cinfo->coef->decompress_data) (cinfo, main_ptr->buffer))
|
||||
if (!(*cinfo->coef->_decompress_data) (cinfo, main_ptr->buffer))
|
||||
return; /* suspension forced, can do nothing more */
|
||||
main_ptr->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
|
||||
}
|
||||
|
|
@ -310,9 +314,9 @@ process_data_simple_main(j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
|||
*/
|
||||
|
||||
/* Feed the postprocessor */
|
||||
(*cinfo->post->post_process_data) (cinfo, main_ptr->buffer,
|
||||
&main_ptr->rowgroup_ctr, rowgroups_avail,
|
||||
output_buf, out_row_ctr, out_rows_avail);
|
||||
(*cinfo->post->_post_process_data) (cinfo, main_ptr->buffer,
|
||||
&main_ptr->rowgroup_ctr, rowgroups_avail,
|
||||
output_buf, out_row_ctr, out_rows_avail);
|
||||
|
||||
/* Has postprocessor consumed all the data yet? If so, mark buffer empty */
|
||||
if (main_ptr->rowgroup_ctr >= rowgroups_avail) {
|
||||
|
|
@ -328,15 +332,15 @@ process_data_simple_main(j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
process_data_context_main(j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
||||
process_data_context_main(j_decompress_ptr cinfo, _JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
|
||||
{
|
||||
my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
|
||||
|
||||
/* Read input data if we haven't filled the main buffer yet */
|
||||
if (!main_ptr->buffer_full) {
|
||||
if (!(*cinfo->coef->decompress_data) (cinfo,
|
||||
main_ptr->xbuffer[main_ptr->whichptr]))
|
||||
if (!(*cinfo->coef->_decompress_data) (cinfo,
|
||||
main_ptr->xbuffer[main_ptr->whichptr]))
|
||||
return; /* suspension forced, can do nothing more */
|
||||
main_ptr->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
|
||||
main_ptr->iMCU_row_ctr++; /* count rows received */
|
||||
|
|
@ -350,11 +354,11 @@ process_data_context_main(j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
|||
switch (main_ptr->context_state) {
|
||||
case CTX_POSTPONED_ROW:
|
||||
/* Call postprocessor using previously set pointers for postponed row */
|
||||
(*cinfo->post->post_process_data) (cinfo,
|
||||
main_ptr->xbuffer[main_ptr->whichptr],
|
||||
&main_ptr->rowgroup_ctr,
|
||||
main_ptr->rowgroups_avail, output_buf,
|
||||
out_row_ctr, out_rows_avail);
|
||||
(*cinfo->post->_post_process_data) (cinfo,
|
||||
main_ptr->xbuffer[main_ptr->whichptr],
|
||||
&main_ptr->rowgroup_ctr,
|
||||
main_ptr->rowgroups_avail, output_buf,
|
||||
out_row_ctr, out_rows_avail);
|
||||
if (main_ptr->rowgroup_ctr < main_ptr->rowgroups_avail)
|
||||
return; /* Need to suspend */
|
||||
main_ptr->context_state = CTX_PREPARE_FOR_IMCU;
|
||||
|
|
@ -374,11 +378,11 @@ process_data_context_main(j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
|||
FALLTHROUGH /*FALLTHROUGH*/
|
||||
case CTX_PROCESS_IMCU:
|
||||
/* Call postprocessor using previously set pointers */
|
||||
(*cinfo->post->post_process_data) (cinfo,
|
||||
main_ptr->xbuffer[main_ptr->whichptr],
|
||||
&main_ptr->rowgroup_ctr,
|
||||
main_ptr->rowgroups_avail, output_buf,
|
||||
out_row_ctr, out_rows_avail);
|
||||
(*cinfo->post->_post_process_data) (cinfo,
|
||||
main_ptr->xbuffer[main_ptr->whichptr],
|
||||
&main_ptr->rowgroup_ctr,
|
||||
main_ptr->rowgroups_avail, output_buf,
|
||||
out_row_ctr, out_rows_avail);
|
||||
if (main_ptr->rowgroup_ctr < main_ptr->rowgroups_avail)
|
||||
return; /* Need to suspend */
|
||||
/* After the first iMCU, change wraparound pointers to normal state */
|
||||
|
|
@ -405,12 +409,12 @@ process_data_context_main(j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
|||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
|
||||
METHODDEF(void)
|
||||
process_data_crank_post(j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
||||
process_data_crank_post(j_decompress_ptr cinfo, _JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
|
||||
{
|
||||
(*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE)NULL,
|
||||
(JDIMENSION *)NULL, (JDIMENSION)0,
|
||||
output_buf, out_row_ctr, out_rows_avail);
|
||||
(*cinfo->post->_post_process_data) (cinfo, (_JSAMPIMAGE)NULL,
|
||||
(JDIMENSION *)NULL, (JDIMENSION)0,
|
||||
output_buf, out_row_ctr, out_rows_avail);
|
||||
}
|
||||
|
||||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
|
|
@ -421,12 +425,15 @@ process_data_crank_post(j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_d_main_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
||||
_jinit_d_main_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_main_ptr main_ptr;
|
||||
int ci, rgroup, ngroups;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
main_ptr = (my_main_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_main_controller));
|
||||
|
|
@ -452,9 +459,11 @@ jinit_d_main_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
|||
ci++, compptr++) {
|
||||
rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
|
||||
cinfo->_min_DCT_scaled_size; /* height of a row group of component */
|
||||
main_ptr->buffer[ci] = (*cinfo->mem->alloc_sarray)
|
||||
main_ptr->buffer[ci] = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
compptr->width_in_blocks * compptr->_DCT_scaled_size,
|
||||
(JDIMENSION)(rgroup * ngroups));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */
|
||||
|
|
|
|||
|
|
@ -3,22 +3,27 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jpeglib.h"
|
||||
#include "jpegcomp.h"
|
||||
#include "jpegapicomp.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_d_main_controller pub; /* public fields */
|
||||
|
||||
/* Pointer to allocated workspace (M or M+2 row groups). */
|
||||
JSAMPARRAY buffer[MAX_COMPONENTS];
|
||||
_JSAMPARRAY buffer[MAX_COMPONENTS];
|
||||
|
||||
boolean buffer_full; /* Have we gotten an iMCU row from decoder? */
|
||||
JDIMENSION rowgroup_ctr; /* counts row groups output to postprocessor */
|
||||
|
|
@ -26,7 +31,7 @@ typedef struct {
|
|||
/* Remaining fields are only used in the context case. */
|
||||
|
||||
/* These are the master pointers to the funny-order pointer lists. */
|
||||
JSAMPIMAGE xbuffer[2]; /* pointers to weird pointer lists */
|
||||
_JSAMPIMAGE xbuffer[2]; /* pointers to weird pointer lists */
|
||||
|
||||
int whichptr; /* indicates which pointer set is now in use */
|
||||
int context_state; /* process_data state machine status */
|
||||
|
|
@ -53,7 +58,7 @@ set_wraparound_pointers(j_decompress_ptr cinfo)
|
|||
int ci, i, rgroup;
|
||||
int M = cinfo->_min_DCT_scaled_size;
|
||||
jpeg_component_info *compptr;
|
||||
JSAMPARRAY xbuf0, xbuf1;
|
||||
_JSAMPARRAY xbuf0, xbuf1;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
|
|
@ -69,3 +74,5 @@ set_wraparound_pointers(j_decompress_ptr cinfo)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2012, 2015, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
|
|
@ -237,7 +239,8 @@ get_soi(j_decompress_ptr cinfo)
|
|||
|
||||
|
||||
LOCAL(boolean)
|
||||
get_sof(j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
|
||||
get_sof(j_decompress_ptr cinfo, boolean is_prog, boolean is_lossless,
|
||||
boolean is_arith)
|
||||
/* Process a SOFn marker */
|
||||
{
|
||||
JLONG length;
|
||||
|
|
@ -246,6 +249,7 @@ get_sof(j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
|
|||
INPUT_VARS(cinfo);
|
||||
|
||||
cinfo->progressive_mode = is_prog;
|
||||
cinfo->master->lossless = is_lossless;
|
||||
cinfo->arith_code = is_arith;
|
||||
|
||||
INPUT_2BYTES(cinfo, length, return FALSE);
|
||||
|
|
@ -990,32 +994,40 @@ read_markers(j_decompress_ptr cinfo)
|
|||
|
||||
case M_SOF0: /* Baseline */
|
||||
case M_SOF1: /* Extended sequential, Huffman */
|
||||
if (!get_sof(cinfo, FALSE, FALSE))
|
||||
if (!get_sof(cinfo, FALSE, FALSE, FALSE))
|
||||
return JPEG_SUSPENDED;
|
||||
break;
|
||||
|
||||
case M_SOF2: /* Progressive, Huffman */
|
||||
if (!get_sof(cinfo, TRUE, FALSE))
|
||||
if (!get_sof(cinfo, TRUE, FALSE, FALSE))
|
||||
return JPEG_SUSPENDED;
|
||||
break;
|
||||
|
||||
case M_SOF3: /* Lossless, Huffman */
|
||||
if (!get_sof(cinfo, FALSE, TRUE, FALSE))
|
||||
return JPEG_SUSPENDED;
|
||||
break;
|
||||
|
||||
case M_SOF9: /* Extended sequential, arithmetic */
|
||||
if (!get_sof(cinfo, FALSE, TRUE))
|
||||
if (!get_sof(cinfo, FALSE, FALSE, TRUE))
|
||||
return JPEG_SUSPENDED;
|
||||
break;
|
||||
|
||||
case M_SOF10: /* Progressive, arithmetic */
|
||||
if (!get_sof(cinfo, TRUE, TRUE))
|
||||
if (!get_sof(cinfo, TRUE, FALSE, TRUE))
|
||||
return JPEG_SUSPENDED;
|
||||
break;
|
||||
|
||||
case M_SOF11: /* Lossless, arithmetic */
|
||||
if (!get_sof(cinfo, FALSE, TRUE, TRUE))
|
||||
return JPEG_SUSPENDED;
|
||||
break;
|
||||
|
||||
/* Currently unsupported SOFn types */
|
||||
case M_SOF3: /* Lossless, Huffman */
|
||||
case M_SOF5: /* Differential sequential, Huffman */
|
||||
case M_SOF6: /* Differential progressive, Huffman */
|
||||
case M_SOF7: /* Differential lossless, Huffman */
|
||||
case M_JPG: /* Reserved for JPEG extensions */
|
||||
case M_SOF11: /* Lossless, arithmetic */
|
||||
case M_SOF13: /* Differential sequential, arithmetic */
|
||||
case M_SOF14: /* Differential progressive, arithmetic */
|
||||
case M_SOF15: /* Differential lossless, arithmetic */
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2002-2009 by Guido Vollbeding.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009-2011, 2016, 2019, 2022, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2016, 2019, 2022-2023, D. R. Commander.
|
||||
* Copyright (C) 2013, Linaro Limited.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
|
|
@ -20,7 +22,7 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jpegcomp.h"
|
||||
#include "jpegapicomp.h"
|
||||
#include "jdmaster.h"
|
||||
|
||||
|
||||
|
|
@ -33,6 +35,9 @@ LOCAL(boolean)
|
|||
use_merged_upsample(j_decompress_ptr cinfo)
|
||||
{
|
||||
#ifdef UPSAMPLE_MERGING_SUPPORTED
|
||||
/* Colorspace conversion is not supported with lossless JPEG images */
|
||||
if (cinfo->master->lossless)
|
||||
return FALSE;
|
||||
/* Merging is the equivalent of plain box-filter upsampling */
|
||||
if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling)
|
||||
return FALSE;
|
||||
|
|
@ -97,154 +102,154 @@ jpeg_core_output_dimensions(j_decompress_ptr cinfo)
|
|||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Compute actual output image dimensions and DCT scaling choices. */
|
||||
if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom) {
|
||||
/* Provide 1/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 1;
|
||||
cinfo->_min_DCT_v_scaled_size = 1;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 2) {
|
||||
/* Provide 2/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 2L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 2L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 2;
|
||||
cinfo->_min_DCT_v_scaled_size = 2;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 3) {
|
||||
/* Provide 3/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 3L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 3L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 3;
|
||||
cinfo->_min_DCT_v_scaled_size = 3;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 4) {
|
||||
/* Provide 4/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 4L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 4L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 4;
|
||||
cinfo->_min_DCT_v_scaled_size = 4;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 5) {
|
||||
/* Provide 5/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 5L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 5L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 5;
|
||||
cinfo->_min_DCT_v_scaled_size = 5;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 6) {
|
||||
/* Provide 6/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 6L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 6L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 6;
|
||||
cinfo->_min_DCT_v_scaled_size = 6;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 7) {
|
||||
/* Provide 7/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 7L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 7L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 7;
|
||||
cinfo->_min_DCT_v_scaled_size = 7;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 8) {
|
||||
/* Provide 8/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 8L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 8L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 8;
|
||||
cinfo->_min_DCT_v_scaled_size = 8;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 9) {
|
||||
/* Provide 9/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 9L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 9L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 9;
|
||||
cinfo->_min_DCT_v_scaled_size = 9;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 10) {
|
||||
/* Provide 10/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 10L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 10L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 10;
|
||||
cinfo->_min_DCT_v_scaled_size = 10;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 11) {
|
||||
/* Provide 11/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 11L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 11L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 11;
|
||||
cinfo->_min_DCT_v_scaled_size = 11;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 12) {
|
||||
/* Provide 12/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 12L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 12L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 12;
|
||||
cinfo->_min_DCT_v_scaled_size = 12;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 13) {
|
||||
/* Provide 13/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 13L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 13L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 13;
|
||||
cinfo->_min_DCT_v_scaled_size = 13;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 14) {
|
||||
/* Provide 14/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 14L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 14L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 14;
|
||||
cinfo->_min_DCT_v_scaled_size = 14;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 15) {
|
||||
/* Provide 15/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 15L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 15L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 15;
|
||||
cinfo->_min_DCT_v_scaled_size = 15;
|
||||
} else {
|
||||
/* Provide 16/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 16L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 16L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 16;
|
||||
cinfo->_min_DCT_v_scaled_size = 16;
|
||||
if (!cinfo->master->lossless) {
|
||||
/* Compute actual output image dimensions and DCT scaling choices. */
|
||||
if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom) {
|
||||
/* Provide 1/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 1;
|
||||
cinfo->_min_DCT_v_scaled_size = 1;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 2) {
|
||||
/* Provide 2/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 2L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 2L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 2;
|
||||
cinfo->_min_DCT_v_scaled_size = 2;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 3) {
|
||||
/* Provide 3/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 3L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 3L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 3;
|
||||
cinfo->_min_DCT_v_scaled_size = 3;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 4) {
|
||||
/* Provide 4/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 4L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 4L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 4;
|
||||
cinfo->_min_DCT_v_scaled_size = 4;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 5) {
|
||||
/* Provide 5/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 5L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 5L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 5;
|
||||
cinfo->_min_DCT_v_scaled_size = 5;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 6) {
|
||||
/* Provide 6/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 6L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 6L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 6;
|
||||
cinfo->_min_DCT_v_scaled_size = 6;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 7) {
|
||||
/* Provide 7/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 7L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 7L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 7;
|
||||
cinfo->_min_DCT_v_scaled_size = 7;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 8) {
|
||||
/* Provide 8/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 8L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 8L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 8;
|
||||
cinfo->_min_DCT_v_scaled_size = 8;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 9) {
|
||||
/* Provide 9/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 9L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 9L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 9;
|
||||
cinfo->_min_DCT_v_scaled_size = 9;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 10) {
|
||||
/* Provide 10/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 10L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 10L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 10;
|
||||
cinfo->_min_DCT_v_scaled_size = 10;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 11) {
|
||||
/* Provide 11/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 11L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 11L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 11;
|
||||
cinfo->_min_DCT_v_scaled_size = 11;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 12) {
|
||||
/* Provide 12/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 12L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 12L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 12;
|
||||
cinfo->_min_DCT_v_scaled_size = 12;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 13) {
|
||||
/* Provide 13/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 13L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 13L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 13;
|
||||
cinfo->_min_DCT_v_scaled_size = 13;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 14) {
|
||||
/* Provide 14/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 14L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 14L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 14;
|
||||
cinfo->_min_DCT_v_scaled_size = 14;
|
||||
} else if (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * 15) {
|
||||
/* Provide 15/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 15L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 15L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 15;
|
||||
cinfo->_min_DCT_v_scaled_size = 15;
|
||||
} else {
|
||||
/* Provide 16/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width * 16L, (long)DCTSIZE);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height * 16L, (long)DCTSIZE);
|
||||
cinfo->_min_DCT_h_scaled_size = 16;
|
||||
cinfo->_min_DCT_v_scaled_size = 16;
|
||||
}
|
||||
|
||||
/* Recompute dimensions of components */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
compptr->_DCT_h_scaled_size = cinfo->_min_DCT_h_scaled_size;
|
||||
compptr->_DCT_v_scaled_size = cinfo->_min_DCT_v_scaled_size;
|
||||
}
|
||||
} else
|
||||
#endif /* !IDCT_SCALING_SUPPORTED */
|
||||
{
|
||||
/* Hardwire it to "no scaling" */
|
||||
cinfo->output_width = cinfo->image_width;
|
||||
cinfo->output_height = cinfo->image_height;
|
||||
/* jdinput.c has already initialized DCT_scaled_size,
|
||||
* and has computed unscaled downsampled_width and downsampled_height.
|
||||
*/
|
||||
}
|
||||
|
||||
/* Recompute dimensions of components */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
compptr->_DCT_h_scaled_size = cinfo->_min_DCT_h_scaled_size;
|
||||
compptr->_DCT_v_scaled_size = cinfo->_min_DCT_v_scaled_size;
|
||||
}
|
||||
|
||||
#else /* !IDCT_SCALING_SUPPORTED */
|
||||
|
||||
/* Hardwire it to "no scaling" */
|
||||
cinfo->output_width = cinfo->image_width;
|
||||
cinfo->output_height = cinfo->image_height;
|
||||
/* jdinput.c has already initialized DCT_scaled_size,
|
||||
* and has computed unscaled downsampled_width and downsampled_height.
|
||||
*/
|
||||
|
||||
#endif /* IDCT_SCALING_SUPPORTED */
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -273,54 +278,56 @@ jpeg_calc_output_dimensions(j_decompress_ptr cinfo)
|
|||
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
|
||||
/* In selecting the actual DCT scaling for each component, we try to
|
||||
* scale up the chroma components via IDCT scaling rather than upsampling.
|
||||
* This saves time if the upsampler gets to use 1:1 scaling.
|
||||
* Note this code adapts subsampling ratios which are powers of 2.
|
||||
*/
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
int ssize = cinfo->_min_DCT_scaled_size;
|
||||
while (ssize < DCTSIZE &&
|
||||
((cinfo->max_h_samp_factor * cinfo->_min_DCT_scaled_size) %
|
||||
(compptr->h_samp_factor * ssize * 2) == 0) &&
|
||||
((cinfo->max_v_samp_factor * cinfo->_min_DCT_scaled_size) %
|
||||
(compptr->v_samp_factor * ssize * 2) == 0)) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
if (!cinfo->master->lossless) {
|
||||
/* In selecting the actual DCT scaling for each component, we try to
|
||||
* scale up the chroma components via IDCT scaling rather than upsampling.
|
||||
* This saves time if the upsampler gets to use 1:1 scaling.
|
||||
* Note this code adapts subsampling ratios which are powers of 2.
|
||||
*/
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
int ssize = cinfo->_min_DCT_scaled_size;
|
||||
while (ssize < DCTSIZE &&
|
||||
((cinfo->max_h_samp_factor * cinfo->_min_DCT_scaled_size) %
|
||||
(compptr->h_samp_factor * ssize * 2) == 0) &&
|
||||
((cinfo->max_v_samp_factor * cinfo->_min_DCT_scaled_size) %
|
||||
(compptr->v_samp_factor * ssize * 2) == 0)) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = ssize;
|
||||
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = ssize;
|
||||
#else
|
||||
compptr->DCT_scaled_size = ssize;
|
||||
compptr->DCT_scaled_size = ssize;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Recompute downsampled dimensions of components;
|
||||
* application needs to know these if using raw downsampled data.
|
||||
*/
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Size in samples, after IDCT scaling */
|
||||
compptr->downsampled_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width *
|
||||
(long)(compptr->h_samp_factor * compptr->_DCT_scaled_size),
|
||||
(long)(cinfo->max_h_samp_factor * DCTSIZE));
|
||||
compptr->downsampled_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height *
|
||||
(long)(compptr->v_samp_factor * compptr->_DCT_scaled_size),
|
||||
(long)(cinfo->max_v_samp_factor * DCTSIZE));
|
||||
}
|
||||
|
||||
#else /* !IDCT_SCALING_SUPPORTED */
|
||||
|
||||
/* Hardwire it to "no scaling" */
|
||||
cinfo->output_width = cinfo->image_width;
|
||||
cinfo->output_height = cinfo->image_height;
|
||||
/* jdinput.c has already initialized DCT_scaled_size to DCTSIZE,
|
||||
* and has computed unscaled downsampled_width and downsampled_height.
|
||||
*/
|
||||
}
|
||||
|
||||
/* Recompute downsampled dimensions of components;
|
||||
* application needs to know these if using raw downsampled data.
|
||||
*/
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Size in samples, after IDCT scaling */
|
||||
compptr->downsampled_width = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_width *
|
||||
(long)(compptr->h_samp_factor *
|
||||
compptr->_DCT_scaled_size),
|
||||
(long)(cinfo->max_h_samp_factor * DCTSIZE));
|
||||
compptr->downsampled_height = (JDIMENSION)
|
||||
jdiv_round_up((long)cinfo->image_height *
|
||||
(long)(compptr->v_samp_factor *
|
||||
compptr->_DCT_scaled_size),
|
||||
(long)(cinfo->max_v_samp_factor * DCTSIZE));
|
||||
}
|
||||
} else
|
||||
#endif /* IDCT_SCALING_SUPPORTED */
|
||||
{
|
||||
/* Hardwire it to "no scaling" */
|
||||
cinfo->output_width = cinfo->image_width;
|
||||
cinfo->output_height = cinfo->image_height;
|
||||
/* jdinput.c has already initialized DCT_scaled_size to DCTSIZE,
|
||||
* and has computed unscaled downsampled_width and downsampled_height.
|
||||
*/
|
||||
}
|
||||
|
||||
/* Report number of components in selected colorspace. */
|
||||
/* Probably this should be in the color conversion module... */
|
||||
|
|
@ -409,27 +416,83 @@ prepare_range_limit_table(j_decompress_ptr cinfo)
|
|||
/* Allocate and fill in the sample_range_limit table */
|
||||
{
|
||||
JSAMPLE *table;
|
||||
J12SAMPLE *table12;
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
J16SAMPLE *table16;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
table = (JSAMPLE *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(5 * (MAXJSAMPLE + 1) + CENTERJSAMPLE) * sizeof(JSAMPLE));
|
||||
table += (MAXJSAMPLE + 1); /* allow negative subscripts of simple table */
|
||||
cinfo->sample_range_limit = table;
|
||||
/* First segment of "simple" table: limit[x] = 0 for x < 0 */
|
||||
memset(table - (MAXJSAMPLE + 1), 0, (MAXJSAMPLE + 1) * sizeof(JSAMPLE));
|
||||
/* Main part of "simple" table: limit[x] = x */
|
||||
for (i = 0; i <= MAXJSAMPLE; i++)
|
||||
table[i] = (JSAMPLE)i;
|
||||
table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */
|
||||
/* End of simple table, rest of first half of post-IDCT table */
|
||||
for (i = CENTERJSAMPLE; i < 2 * (MAXJSAMPLE + 1); i++)
|
||||
table[i] = MAXJSAMPLE;
|
||||
/* Second half of post-IDCT table */
|
||||
memset(table + (2 * (MAXJSAMPLE + 1)), 0,
|
||||
(2 * (MAXJSAMPLE + 1) - CENTERJSAMPLE) * sizeof(JSAMPLE));
|
||||
memcpy(table + (4 * (MAXJSAMPLE + 1) - CENTERJSAMPLE),
|
||||
cinfo->sample_range_limit, CENTERJSAMPLE * sizeof(JSAMPLE));
|
||||
if (cinfo->data_precision == 16) {
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
table16 = (J16SAMPLE *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(5 * (MAXJ16SAMPLE + 1) + CENTERJ16SAMPLE) *
|
||||
sizeof(J16SAMPLE));
|
||||
table16 += (MAXJ16SAMPLE + 1); /* allow negative subscripts of simple
|
||||
table */
|
||||
cinfo->sample_range_limit = (JSAMPLE *)table16;
|
||||
/* First segment of "simple" table: limit[x] = 0 for x < 0 */
|
||||
memset(table16 - (MAXJ16SAMPLE + 1), 0,
|
||||
(MAXJ16SAMPLE + 1) * sizeof(J16SAMPLE));
|
||||
/* Main part of "simple" table: limit[x] = x */
|
||||
for (i = 0; i <= MAXJ16SAMPLE; i++)
|
||||
table16[i] = (J16SAMPLE)i;
|
||||
table16 += CENTERJ16SAMPLE; /* Point to where post-IDCT table starts */
|
||||
/* End of simple table, rest of first half of post-IDCT table */
|
||||
for (i = CENTERJ16SAMPLE; i < 2 * (MAXJ16SAMPLE + 1); i++)
|
||||
table16[i] = MAXJ16SAMPLE;
|
||||
/* Second half of post-IDCT table */
|
||||
memset(table16 + (2 * (MAXJ16SAMPLE + 1)), 0,
|
||||
(2 * (MAXJ16SAMPLE + 1) - CENTERJ16SAMPLE) * sizeof(J16SAMPLE));
|
||||
memcpy(table16 + (4 * (MAXJ16SAMPLE + 1) - CENTERJ16SAMPLE),
|
||||
cinfo->sample_range_limit, CENTERJ16SAMPLE * sizeof(J16SAMPLE));
|
||||
#else
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
#endif
|
||||
} else if (cinfo->data_precision == 12) {
|
||||
table12 = (J12SAMPLE *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(5 * (MAXJ12SAMPLE + 1) + CENTERJ12SAMPLE) *
|
||||
sizeof(J12SAMPLE));
|
||||
table12 += (MAXJ12SAMPLE + 1); /* allow negative subscripts of simple
|
||||
table */
|
||||
cinfo->sample_range_limit = (JSAMPLE *)table12;
|
||||
/* First segment of "simple" table: limit[x] = 0 for x < 0 */
|
||||
memset(table12 - (MAXJ12SAMPLE + 1), 0,
|
||||
(MAXJ12SAMPLE + 1) * sizeof(J12SAMPLE));
|
||||
/* Main part of "simple" table: limit[x] = x */
|
||||
for (i = 0; i <= MAXJ12SAMPLE; i++)
|
||||
table12[i] = (J12SAMPLE)i;
|
||||
table12 += CENTERJ12SAMPLE; /* Point to where post-IDCT table starts */
|
||||
/* End of simple table, rest of first half of post-IDCT table */
|
||||
for (i = CENTERJ12SAMPLE; i < 2 * (MAXJ12SAMPLE + 1); i++)
|
||||
table12[i] = MAXJ12SAMPLE;
|
||||
/* Second half of post-IDCT table */
|
||||
memset(table12 + (2 * (MAXJ12SAMPLE + 1)), 0,
|
||||
(2 * (MAXJ12SAMPLE + 1) - CENTERJ12SAMPLE) * sizeof(J12SAMPLE));
|
||||
memcpy(table12 + (4 * (MAXJ12SAMPLE + 1) - CENTERJ12SAMPLE),
|
||||
cinfo->sample_range_limit, CENTERJ12SAMPLE * sizeof(J12SAMPLE));
|
||||
} else {
|
||||
table = (JSAMPLE *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(5 * (MAXJSAMPLE + 1) + CENTERJSAMPLE) * sizeof(JSAMPLE));
|
||||
table += (MAXJSAMPLE + 1); /* allow negative subscripts of simple table */
|
||||
cinfo->sample_range_limit = table;
|
||||
/* First segment of "simple" table: limit[x] = 0 for x < 0 */
|
||||
memset(table - (MAXJSAMPLE + 1), 0, (MAXJSAMPLE + 1) * sizeof(JSAMPLE));
|
||||
/* Main part of "simple" table: limit[x] = x */
|
||||
for (i = 0; i <= MAXJSAMPLE; i++)
|
||||
table[i] = (JSAMPLE)i;
|
||||
table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */
|
||||
/* End of simple table, rest of first half of post-IDCT table */
|
||||
for (i = CENTERJSAMPLE; i < 2 * (MAXJSAMPLE + 1); i++)
|
||||
table[i] = MAXJSAMPLE;
|
||||
/* Second half of post-IDCT table */
|
||||
memset(table + (2 * (MAXJSAMPLE + 1)), 0,
|
||||
(2 * (MAXJSAMPLE + 1) - CENTERJSAMPLE) * sizeof(JSAMPLE));
|
||||
memcpy(table + (4 * (MAXJSAMPLE + 1) - CENTERJSAMPLE),
|
||||
cinfo->sample_range_limit, CENTERJSAMPLE * sizeof(JSAMPLE));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -452,6 +515,17 @@ master_selection(j_decompress_ptr cinfo)
|
|||
long samplesperrow;
|
||||
JDIMENSION jd_samplesperrow;
|
||||
|
||||
/* Disable IDCT scaling and raw (downsampled) data output in lossless mode.
|
||||
* IDCT scaling is not useful in lossless mode, and it must be disabled in
|
||||
* order to properly calculate the output dimensions. Raw data output isn't
|
||||
* particularly useful without subsampling and has not been tested in
|
||||
* lossless mode.
|
||||
*/
|
||||
if (cinfo->master->lossless) {
|
||||
cinfo->raw_data_out = FALSE;
|
||||
cinfo->scale_num = cinfo->scale_denom = 1;
|
||||
}
|
||||
|
||||
/* Initialize dimensions and other stuff */
|
||||
jpeg_calc_output_dimensions(cinfo);
|
||||
prepare_range_limit_table(cinfo);
|
||||
|
|
@ -480,7 +554,8 @@ master_selection(j_decompress_ptr cinfo)
|
|||
if (cinfo->raw_data_out)
|
||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
||||
/* 2-pass quantizer only works in 3-component color space. */
|
||||
if (cinfo->out_color_components != 3) {
|
||||
if (cinfo->out_color_components != 3 ||
|
||||
cinfo->out_color_space == JCS_RGB565) {
|
||||
cinfo->enable_1pass_quant = TRUE;
|
||||
cinfo->enable_external_quant = FALSE;
|
||||
cinfo->enable_2pass_quant = FALSE;
|
||||
|
|
@ -495,7 +570,12 @@ master_selection(j_decompress_ptr cinfo)
|
|||
|
||||
if (cinfo->enable_1pass_quant) {
|
||||
#ifdef QUANT_1PASS_SUPPORTED
|
||||
jinit_1pass_quantizer(cinfo);
|
||||
if (cinfo->data_precision == 16)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
else if (cinfo->data_precision == 12)
|
||||
j12init_1pass_quantizer(cinfo);
|
||||
else
|
||||
jinit_1pass_quantizer(cinfo);
|
||||
master->quantizer_1pass = cinfo->cquantize;
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
|
|
@ -505,7 +585,12 @@ master_selection(j_decompress_ptr cinfo)
|
|||
/* We use the 2-pass code to map to external colormaps. */
|
||||
if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) {
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
jinit_2pass_quantizer(cinfo);
|
||||
if (cinfo->data_precision == 16)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
else if (cinfo->data_precision == 12)
|
||||
j12init_2pass_quantizer(cinfo);
|
||||
else
|
||||
jinit_2pass_quantizer(cinfo);
|
||||
master->quantizer_2pass = cinfo->cquantize;
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
|
|
@ -520,42 +605,122 @@ master_selection(j_decompress_ptr cinfo)
|
|||
if (!cinfo->raw_data_out) {
|
||||
if (master->using_merged_upsample) {
|
||||
#ifdef UPSAMPLE_MERGING_SUPPORTED
|
||||
jinit_merged_upsampler(cinfo); /* does color conversion too */
|
||||
if (cinfo->data_precision == 16)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
else if (cinfo->data_precision == 12)
|
||||
j12init_merged_upsampler(cinfo); /* does color conversion too */
|
||||
else
|
||||
jinit_merged_upsampler(cinfo); /* does color conversion too */
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else {
|
||||
jinit_color_deconverter(cinfo);
|
||||
jinit_upsampler(cinfo);
|
||||
}
|
||||
jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant);
|
||||
}
|
||||
/* Inverse DCT */
|
||||
jinit_inverse_dct(cinfo);
|
||||
/* Entropy decoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
#ifdef D_ARITH_CODING_SUPPORTED
|
||||
jinit_arith_decoder(cinfo);
|
||||
if (cinfo->data_precision == 16) {
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
j16init_color_deconverter(cinfo);
|
||||
j16init_upsampler(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
#endif
|
||||
} else if (cinfo->data_precision == 12) {
|
||||
j12init_color_deconverter(cinfo);
|
||||
j12init_upsampler(cinfo);
|
||||
} else {
|
||||
jinit_color_deconverter(cinfo);
|
||||
jinit_upsampler(cinfo);
|
||||
}
|
||||
}
|
||||
if (cinfo->data_precision == 16)
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
j16init_d_post_controller(cinfo, cinfo->enable_2pass_quant);
|
||||
#else
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
#endif
|
||||
else if (cinfo->data_precision == 12)
|
||||
j12init_d_post_controller(cinfo, cinfo->enable_2pass_quant);
|
||||
else
|
||||
jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant);
|
||||
}
|
||||
|
||||
if (cinfo->master->lossless) {
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
/* Prediction, sample undifferencing, point transform, and sample size
|
||||
* scaling
|
||||
*/
|
||||
if (cinfo->data_precision == 16)
|
||||
j16init_lossless_decompressor(cinfo);
|
||||
else if (cinfo->data_precision == 12)
|
||||
j12init_lossless_decompressor(cinfo);
|
||||
else
|
||||
jinit_lossless_decompressor(cinfo);
|
||||
/* Entropy decoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
} else {
|
||||
jinit_lhuff_decoder(cinfo);
|
||||
}
|
||||
|
||||
/* Initialize principal buffer controllers. */
|
||||
use_c_buffer = cinfo->inputctl->has_multiple_scans ||
|
||||
cinfo->buffered_image;
|
||||
if (cinfo->data_precision == 16)
|
||||
j16init_d_diff_controller(cinfo, use_c_buffer);
|
||||
else if (cinfo->data_precision == 12)
|
||||
j12init_d_diff_controller(cinfo, use_c_buffer);
|
||||
else
|
||||
jinit_d_diff_controller(cinfo, use_c_buffer);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else {
|
||||
if (cinfo->progressive_mode) {
|
||||
#ifdef D_PROGRESSIVE_SUPPORTED
|
||||
jinit_phuff_decoder(cinfo);
|
||||
if (cinfo->data_precision == 16)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
/* Inverse DCT */
|
||||
if (cinfo->data_precision == 12)
|
||||
j12init_inverse_dct(cinfo);
|
||||
else
|
||||
jinit_inverse_dct(cinfo);
|
||||
/* Entropy decoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
#ifdef D_ARITH_CODING_SUPPORTED
|
||||
jinit_arith_decoder(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
#endif
|
||||
} else
|
||||
jinit_huff_decoder(cinfo);
|
||||
} 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);
|
||||
}
|
||||
|
||||
/* Initialize principal buffer controllers. */
|
||||
use_c_buffer = cinfo->inputctl->has_multiple_scans ||
|
||||
cinfo->buffered_image;
|
||||
if (cinfo->data_precision == 12)
|
||||
j12init_d_coef_controller(cinfo, use_c_buffer);
|
||||
else
|
||||
jinit_d_coef_controller(cinfo, use_c_buffer);
|
||||
}
|
||||
|
||||
/* Initialize principal buffer controllers. */
|
||||
use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image;
|
||||
jinit_d_coef_controller(cinfo, use_c_buffer);
|
||||
|
||||
if (!cinfo->raw_data_out)
|
||||
jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */);
|
||||
if (!cinfo->raw_data_out) {
|
||||
if (cinfo->data_precision == 16)
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
j16init_d_main_controller(cinfo,
|
||||
FALSE /* never need full buffer here */);
|
||||
#else
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
#endif
|
||||
else if (cinfo->data_precision == 12)
|
||||
j12init_d_main_controller(cinfo,
|
||||
FALSE /* never need full buffer here */);
|
||||
else
|
||||
jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */);
|
||||
}
|
||||
|
||||
/* We can now tell the memory manager to allocate virtual arrays. */
|
||||
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2009, 2011, 2014-2015, 2020, D. R. Commander.
|
||||
* Copyright (C) 2009, 2011, 2014-2015, 2020, 2022, D. R. Commander.
|
||||
* Copyright (C) 2013, Linaro Limited.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
|
|
@ -167,20 +167,20 @@ build_ycc_rgb_table(j_decompress_ptr cinfo)
|
|||
|
||||
upsample->Cr_r_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE + 1) * sizeof(int));
|
||||
(_MAXJSAMPLE + 1) * sizeof(int));
|
||||
upsample->Cb_b_tab = (int *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE + 1) * sizeof(int));
|
||||
(_MAXJSAMPLE + 1) * sizeof(int));
|
||||
upsample->Cr_g_tab = (JLONG *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE + 1) * sizeof(JLONG));
|
||||
(_MAXJSAMPLE + 1) * sizeof(JLONG));
|
||||
upsample->Cb_g_tab = (JLONG *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(MAXJSAMPLE + 1) * sizeof(JLONG));
|
||||
(_MAXJSAMPLE + 1) * sizeof(JLONG));
|
||||
|
||||
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 */
|
||||
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);
|
||||
|
|
@ -219,14 +219,14 @@ start_pass_merged_upsample(j_decompress_ptr cinfo)
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
merged_2v_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
merged_2v_upsample(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
|
||||
JDIMENSION in_row_groups_avail, _JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
|
||||
/* 2:1 vertical sampling case: may need a spare row. */
|
||||
{
|
||||
my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
|
||||
JSAMPROW work_ptrs[2];
|
||||
_JSAMPROW work_ptrs[2];
|
||||
JDIMENSION num_rows; /* number of rows returned to caller */
|
||||
|
||||
if (upsample->spare_full) {
|
||||
|
|
@ -234,8 +234,8 @@ merged_2v_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
JDIMENSION size = upsample->out_row_width;
|
||||
if (cinfo->out_color_space == JCS_RGB565)
|
||||
size = cinfo->output_width * 2;
|
||||
jcopy_sample_rows(&upsample->spare_row, 0, output_buf + *out_row_ctr, 0, 1,
|
||||
size);
|
||||
_jcopy_sample_rows(&upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
|
||||
1, size);
|
||||
num_rows = 1;
|
||||
upsample->spare_full = FALSE;
|
||||
} else {
|
||||
|
|
@ -270,9 +270,9 @@ merged_2v_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
|
||||
METHODDEF(void)
|
||||
merged_1v_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
merged_1v_upsample(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
|
||||
JDIMENSION in_row_groups_avail, _JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
|
||||
/* 1:1 vertical sampling case: much easier, never need a spare row. */
|
||||
{
|
||||
|
|
@ -302,8 +302,8 @@ merged_1v_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
|
||||
h2v1_merged_upsample(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf)
|
||||
{
|
||||
switch (cinfo->out_color_space) {
|
||||
case JCS_EXT_RGB:
|
||||
|
|
@ -347,8 +347,8 @@ h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
|
||||
h2v2_merged_upsample(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf)
|
||||
{
|
||||
switch (cinfo->out_color_space) {
|
||||
case JCS_EXT_RGB:
|
||||
|
|
@ -474,8 +474,8 @@ static INLINE boolean is_big_endian(void)
|
|||
|
||||
|
||||
METHODDEF(void)
|
||||
h2v1_merged_upsample_565(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
|
||||
h2v1_merged_upsample_565(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf)
|
||||
{
|
||||
if (is_big_endian())
|
||||
h2v1_merged_upsample_565_be(cinfo, input_buf, in_row_group_ctr,
|
||||
|
|
@ -487,8 +487,8 @@ h2v1_merged_upsample_565(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
|
||||
METHODDEF(void)
|
||||
h2v1_merged_upsample_565D(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
|
||||
h2v1_merged_upsample_565D(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf)
|
||||
{
|
||||
if (is_big_endian())
|
||||
h2v1_merged_upsample_565D_be(cinfo, input_buf, in_row_group_ctr,
|
||||
|
|
@ -500,8 +500,8 @@ h2v1_merged_upsample_565D(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
|
||||
METHODDEF(void)
|
||||
h2v2_merged_upsample_565(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
|
||||
h2v2_merged_upsample_565(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf)
|
||||
{
|
||||
if (is_big_endian())
|
||||
h2v2_merged_upsample_565_be(cinfo, input_buf, in_row_group_ctr,
|
||||
|
|
@ -513,8 +513,8 @@ h2v2_merged_upsample_565(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
|
||||
METHODDEF(void)
|
||||
h2v2_merged_upsample_565D(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
|
||||
h2v2_merged_upsample_565D(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf)
|
||||
{
|
||||
if (is_big_endian())
|
||||
h2v2_merged_upsample_565D_be(cinfo, input_buf, in_row_group_ctr,
|
||||
|
|
@ -534,10 +534,13 @@ h2v2_merged_upsample_565D(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_merged_upsampler(j_decompress_ptr cinfo)
|
||||
_jinit_merged_upsampler(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_merged_upsample_ptr upsample;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
upsample = (my_merged_upsample_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_merged_upsampler));
|
||||
|
|
@ -548,10 +551,12 @@ jinit_merged_upsampler(j_decompress_ptr cinfo)
|
|||
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->pub._upsample = merged_2v_upsample;
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_h2v2_merged_upsample())
|
||||
upsample->upmethod = jsimd_h2v2_merged_upsample;
|
||||
else
|
||||
#endif
|
||||
upsample->upmethod = h2v2_merged_upsample;
|
||||
if (cinfo->out_color_space == JCS_RGB565) {
|
||||
if (cinfo->dither_mode != JDITHER_NONE) {
|
||||
|
|
@ -561,14 +566,16 @@ jinit_merged_upsampler(j_decompress_ptr cinfo)
|
|||
}
|
||||
}
|
||||
/* Allocate a spare row buffer */
|
||||
upsample->spare_row = (JSAMPROW)
|
||||
upsample->spare_row = (_JSAMPROW)
|
||||
(*cinfo->mem->alloc_large) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(size_t)(upsample->out_row_width * sizeof(JSAMPLE)));
|
||||
(size_t)(upsample->out_row_width * sizeof(_JSAMPLE)));
|
||||
} else {
|
||||
upsample->pub.upsample = merged_1v_upsample;
|
||||
upsample->pub._upsample = merged_1v_upsample;
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_h2v1_merged_upsample())
|
||||
upsample->upmethod = jsimd_h2v1_merged_upsample;
|
||||
else
|
||||
#endif
|
||||
upsample->upmethod = h2v1_merged_upsample;
|
||||
if (cinfo->out_color_space == JCS_RGB565) {
|
||||
if (cinfo->dither_mode != JDITHER_NONE) {
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2020, D. R. Commander.
|
||||
* Copyright (C) 2020, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jpeglib.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
#ifdef UPSAMPLE_MERGING_SUPPORTED
|
||||
|
||||
|
|
@ -21,8 +22,8 @@ typedef struct {
|
|||
struct jpeg_upsampler pub; /* public fields */
|
||||
|
||||
/* Pointer to routine to do actual upsampling/conversion of one row group */
|
||||
void (*upmethod) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf);
|
||||
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 */
|
||||
|
|
@ -35,7 +36,7 @@ typedef struct {
|
|||
* 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;
|
||||
_JSAMPROW spare_row;
|
||||
boolean spare_full; /* T if spare buffer is occupied */
|
||||
|
||||
JDIMENSION out_row_width; /* samples per output row */
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2013, Linaro Limited.
|
||||
* Copyright (C) 2014-2015, 2018, 2020, D. R. Commander.
|
||||
* Copyright (C) 2014-2015, 2018, 2020, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -15,18 +15,19 @@
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
h2v1_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
h2v1_merged_upsample_565_internal(j_decompress_ptr cinfo,
|
||||
_JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf)
|
||||
_JSAMPARRAY output_buf)
|
||||
{
|
||||
my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
|
||||
register int y, cred, cgreen, cblue;
|
||||
int cb, cr;
|
||||
register JSAMPROW outptr;
|
||||
JSAMPROW inptr0, inptr1, inptr2;
|
||||
register _JSAMPROW outptr;
|
||||
_JSAMPROW inptr0, inptr1, inptr2;
|
||||
JDIMENSION col;
|
||||
/* copy these pointers into registers if possible */
|
||||
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
int *Crrtab = upsample->Cr_r_tab;
|
||||
int *Cbbtab = upsample->Cb_b_tab;
|
||||
JLONG *Crgtab = upsample->Cr_g_tab;
|
||||
|
|
@ -86,18 +87,18 @@ h2v1_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
INLINE
|
||||
LOCAL(void)
|
||||
h2v1_merged_upsample_565D_internal(j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf,
|
||||
_JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf)
|
||||
_JSAMPARRAY output_buf)
|
||||
{
|
||||
my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
|
||||
register int y, cred, cgreen, cblue;
|
||||
int cb, cr;
|
||||
register JSAMPROW outptr;
|
||||
JSAMPROW inptr0, inptr1, inptr2;
|
||||
register _JSAMPROW outptr;
|
||||
_JSAMPROW inptr0, inptr1, inptr2;
|
||||
JDIMENSION col;
|
||||
/* copy these pointers into registers if possible */
|
||||
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
int *Crrtab = upsample->Cr_r_tab;
|
||||
int *Cbbtab = upsample->Cb_b_tab;
|
||||
JLONG *Crgtab = upsample->Cr_g_tab;
|
||||
|
|
@ -159,18 +160,18 @@ h2v1_merged_upsample_565D_internal(j_decompress_ptr cinfo,
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf)
|
||||
_JSAMPARRAY output_buf)
|
||||
{
|
||||
my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
|
||||
register int y, cred, cgreen, cblue;
|
||||
int cb, cr;
|
||||
register JSAMPROW outptr0, outptr1;
|
||||
JSAMPROW inptr00, inptr01, inptr1, inptr2;
|
||||
register _JSAMPROW outptr0, outptr1;
|
||||
_JSAMPROW inptr00, inptr01, inptr1, inptr2;
|
||||
JDIMENSION col;
|
||||
/* copy these pointers into registers if possible */
|
||||
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
int *Crrtab = upsample->Cr_r_tab;
|
||||
int *Cbbtab = upsample->Cb_b_tab;
|
||||
JLONG *Crgtab = upsample->Cr_g_tab;
|
||||
|
|
@ -255,18 +256,18 @@ h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
INLINE
|
||||
LOCAL(void)
|
||||
h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf,
|
||||
_JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf)
|
||||
_JSAMPARRAY output_buf)
|
||||
{
|
||||
my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
|
||||
register int y, cred, cgreen, cblue;
|
||||
int cb, cr;
|
||||
register JSAMPROW outptr0, outptr1;
|
||||
JSAMPROW inptr00, inptr01, inptr1, inptr2;
|
||||
register _JSAMPROW outptr0, outptr1;
|
||||
_JSAMPROW inptr00, inptr01, inptr1, inptr2;
|
||||
JDIMENSION col;
|
||||
/* copy these pointers into registers if possible */
|
||||
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
int *Crrtab = upsample->Cr_r_tab;
|
||||
int *Cbbtab = upsample->Cb_b_tab;
|
||||
JLONG *Crgtab = upsample->Cr_g_tab;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2011, 2015, 2020, 2023, D. R. Commander.
|
||||
* Copyright (C) 2011, 2015, 2020, 2022-2023, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -21,18 +21,18 @@
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
h2v1_merged_upsample_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf)
|
||||
_JSAMPARRAY output_buf)
|
||||
{
|
||||
my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
|
||||
register int y, cred, cgreen, cblue;
|
||||
int cb, cr;
|
||||
register JSAMPROW outptr;
|
||||
JSAMPROW inptr0, inptr1, inptr2;
|
||||
register _JSAMPROW outptr;
|
||||
_JSAMPROW inptr0, inptr1, inptr2;
|
||||
JDIMENSION col;
|
||||
/* copy these pointers into registers if possible */
|
||||
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
int *Crrtab = upsample->Cr_r_tab;
|
||||
int *Cbbtab = upsample->Cb_b_tab;
|
||||
JLONG *Crgtab = upsample->Cr_g_tab;
|
||||
|
|
@ -57,7 +57,7 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
||||
#ifdef RGB_ALPHA
|
||||
outptr[RGB_ALPHA] = MAXJSAMPLE;
|
||||
outptr[RGB_ALPHA] = _MAXJSAMPLE;
|
||||
#endif
|
||||
outptr += RGB_PIXELSIZE;
|
||||
y = *inptr0++;
|
||||
|
|
@ -65,7 +65,7 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
||||
#ifdef RGB_ALPHA
|
||||
outptr[RGB_ALPHA] = MAXJSAMPLE;
|
||||
outptr[RGB_ALPHA] = _MAXJSAMPLE;
|
||||
#endif
|
||||
outptr += RGB_PIXELSIZE;
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
||||
#ifdef RGB_ALPHA
|
||||
outptr[RGB_ALPHA] = MAXJSAMPLE;
|
||||
outptr[RGB_ALPHA] = _MAXJSAMPLE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -93,18 +93,18 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
INLINE
|
||||
LOCAL(void)
|
||||
h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
h2v2_merged_upsample_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr,
|
||||
JSAMPARRAY output_buf)
|
||||
_JSAMPARRAY output_buf)
|
||||
{
|
||||
my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
|
||||
register int y, cred, cgreen, cblue;
|
||||
int cb, cr;
|
||||
register JSAMPROW outptr0, outptr1;
|
||||
JSAMPROW inptr00, inptr01, inptr1, inptr2;
|
||||
register _JSAMPROW outptr0, outptr1;
|
||||
_JSAMPROW inptr00, inptr01, inptr1, inptr2;
|
||||
JDIMENSION col;
|
||||
/* copy these pointers into registers if possible */
|
||||
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
int *Crrtab = upsample->Cr_r_tab;
|
||||
int *Cbbtab = upsample->Cb_b_tab;
|
||||
JLONG *Crgtab = upsample->Cr_g_tab;
|
||||
|
|
@ -131,7 +131,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
||||
#ifdef RGB_ALPHA
|
||||
outptr0[RGB_ALPHA] = MAXJSAMPLE;
|
||||
outptr0[RGB_ALPHA] = _MAXJSAMPLE;
|
||||
#endif
|
||||
outptr0 += RGB_PIXELSIZE;
|
||||
y = *inptr00++;
|
||||
|
|
@ -139,7 +139,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
||||
#ifdef RGB_ALPHA
|
||||
outptr0[RGB_ALPHA] = MAXJSAMPLE;
|
||||
outptr0[RGB_ALPHA] = _MAXJSAMPLE;
|
||||
#endif
|
||||
outptr0 += RGB_PIXELSIZE;
|
||||
y = *inptr01++;
|
||||
|
|
@ -147,7 +147,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
||||
#ifdef RGB_ALPHA
|
||||
outptr1[RGB_ALPHA] = MAXJSAMPLE;
|
||||
outptr1[RGB_ALPHA] = _MAXJSAMPLE;
|
||||
#endif
|
||||
outptr1 += RGB_PIXELSIZE;
|
||||
y = *inptr01++;
|
||||
|
|
@ -155,7 +155,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
||||
#ifdef RGB_ALPHA
|
||||
outptr1[RGB_ALPHA] = MAXJSAMPLE;
|
||||
outptr1[RGB_ALPHA] = _MAXJSAMPLE;
|
||||
#endif
|
||||
outptr1 += RGB_PIXELSIZE;
|
||||
}
|
||||
|
|
@ -171,14 +171,14 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
||||
#ifdef RGB_ALPHA
|
||||
outptr0[RGB_ALPHA] = MAXJSAMPLE;
|
||||
outptr0[RGB_ALPHA] = _MAXJSAMPLE;
|
||||
#endif
|
||||
y = *inptr01;
|
||||
outptr1[RGB_RED] = range_limit[y + cred];
|
||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
||||
#ifdef RGB_ALPHA
|
||||
outptr1[RGB_ALPHA] = MAXJSAMPLE;
|
||||
outptr1[RGB_ALPHA] = _MAXJSAMPLE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1995-1997, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015-2016, 2018-2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
|
|
@ -23,7 +25,7 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdhuff.h" /* Declarations shared with jdhuff.c */
|
||||
#include "jdhuff.h" /* Declarations shared with jd*huff.c */
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* It was modified by The libjpeg-turbo Project to include only code relevant
|
||||
* to libjpeg-turbo.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022-2023, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -22,8 +22,11 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
|
||||
|
||||
/* Private buffer controller object */
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -35,7 +38,7 @@ typedef struct {
|
|||
* 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 */
|
||||
_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 */
|
||||
|
|
@ -46,26 +49,28 @@ typedef my_post_controller *my_post_ptr;
|
|||
|
||||
|
||||
/* Forward declarations */
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
METHODDEF(void) post_process_1pass(j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf,
|
||||
_JSAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf,
|
||||
_JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail);
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
#endif
|
||||
#if defined(QUANT_2PASS_SUPPORTED) && BITS_IN_JSAMPLE != 16
|
||||
METHODDEF(void) post_process_prepass(j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf,
|
||||
_JSAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf,
|
||||
_JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail);
|
||||
METHODDEF(void) post_process_2pass(j_decompress_ptr cinfo,
|
||||
JSAMPIMAGE input_buf,
|
||||
_JSAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf,
|
||||
_JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail);
|
||||
#endif
|
||||
|
|
@ -82,39 +87,42 @@ start_pass_dpost(j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
|
|||
|
||||
switch (pass_mode) {
|
||||
case JBUF_PASS_THRU:
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
if (cinfo->quantize_colors) {
|
||||
/* Single-pass processing with color quantization. */
|
||||
post->pub.post_process_data = post_process_1pass;
|
||||
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)
|
||||
post->buffer = (_JSAMPARRAY)(*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr)cinfo, post->whole_image,
|
||||
(JDIMENSION)0, post->strip_height, TRUE);
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* 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;
|
||||
post->pub._post_process_data = cinfo->upsample->_upsample;
|
||||
}
|
||||
break;
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
#if defined(QUANT_2PASS_SUPPORTED) && BITS_IN_JSAMPLE != 16
|
||||
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;
|
||||
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;
|
||||
post->pub._post_process_data = post_process_2pass;
|
||||
break;
|
||||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
#endif /* defined(QUANT_2PASS_SUPPORTED) && BITS_IN_JSAMPLE != 16 */
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
break;
|
||||
|
|
@ -128,10 +136,12 @@ start_pass_dpost(j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
|
|||
* This is used for color precision reduction as well as one-pass quantization.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
|
||||
METHODDEF(void)
|
||||
post_process_1pass(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
post_process_1pass(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
|
||||
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;
|
||||
|
|
@ -143,27 +153,29 @@ post_process_1pass(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
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);
|
||||
(*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);
|
||||
(*cinfo->cquantize->_color_quantize) (cinfo, post->buffer,
|
||||
output_buf + *out_row_ctr,
|
||||
(int)num_rows);
|
||||
*out_row_ctr += num_rows;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
|
||||
#if defined(QUANT_2PASS_SUPPORTED) && BITS_IN_JSAMPLE != 16
|
||||
|
||||
/*
|
||||
* Process some data in the first pass of 2-pass quantization.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
post_process_prepass(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
post_process_prepass(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
|
||||
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;
|
||||
|
|
@ -171,23 +183,23 @@ post_process_prepass(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
/* Reposition virtual buffer if at start of strip. */
|
||||
if (post->next_row == 0) {
|
||||
post->buffer = (*cinfo->mem->access_virt_sarray)
|
||||
post->buffer = (_JSAMPARRAY)(*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);
|
||||
(*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);
|
||||
(*cinfo->cquantize->_color_quantize) (cinfo, post->buffer + old_next_row,
|
||||
(_JSAMPARRAY)NULL, (int)num_rows);
|
||||
*out_row_ctr += num_rows;
|
||||
}
|
||||
|
||||
|
|
@ -204,9 +216,9 @@ post_process_prepass(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
post_process_2pass(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
post_process_2pass(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
|
||||
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;
|
||||
|
|
@ -214,7 +226,7 @@ post_process_2pass(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
/* Reposition virtual buffer if at start of strip. */
|
||||
if (post->next_row == 0) {
|
||||
post->buffer = (*cinfo->mem->access_virt_sarray)
|
||||
post->buffer = (_JSAMPARRAY)(*cinfo->mem->access_virt_sarray)
|
||||
((j_common_ptr)cinfo, post->whole_image,
|
||||
post->starting_row, post->strip_height, FALSE);
|
||||
}
|
||||
|
|
@ -230,9 +242,9 @@ post_process_2pass(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
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);
|
||||
(*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. */
|
||||
|
|
@ -243,7 +255,7 @@ post_process_2pass(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
#endif /* defined(QUANT_2PASS_SUPPORTED) && BITS_IN_JSAMPLE != 16 */
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -251,10 +263,13 @@ post_process_2pass(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_d_post_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
||||
_jinit_d_post_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
||||
{
|
||||
my_post_ptr post;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
post = (my_post_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_post_controller));
|
||||
|
|
@ -265,6 +280,7 @@ jinit_d_post_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
|||
|
||||
/* Create the quantization buffer, if needed */
|
||||
if (cinfo->quantize_colors) {
|
||||
#if BITS_IN_JSAMPLE != 16
|
||||
/* 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?)
|
||||
|
|
@ -285,10 +301,15 @@ jinit_d_post_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
|||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
} else {
|
||||
/* One-pass color quantization: just make a strip buffer. */
|
||||
post->buffer = (*cinfo->mem->alloc_sarray)
|
||||
post->buffer = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
cinfo->output_width * cinfo->out_color_components,
|
||||
post->strip_height);
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2010, 2015-2016, D. R. Commander.
|
||||
* Copyright (C) 2010, 2015-2016, 2022, D. R. Commander.
|
||||
* Copyright (C) 2014, MIPS Technologies, Inc., California.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* Copyright (C) 2019-2020, Arm Limited.
|
||||
|
|
@ -28,10 +28,12 @@
|
|||
#include "jinclude.h"
|
||||
#include "jdsample.h"
|
||||
#include "jsimd.h"
|
||||
#include "jpegcomp.h"
|
||||
#include "jpegapicomp.h"
|
||||
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
|
||||
|
||||
/*
|
||||
* Initialize for an upsampling pass.
|
||||
*/
|
||||
|
|
@ -57,9 +59,9 @@ start_pass_upsample(j_decompress_ptr cinfo)
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
sep_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
sep_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,
|
||||
_JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail)
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
|
||||
|
|
@ -95,9 +97,10 @@ sep_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
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);
|
||||
(*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;
|
||||
|
|
@ -124,7 +127,7 @@ sep_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|||
|
||||
METHODDEF(void)
|
||||
fullsize_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
*output_data_ptr = input_data;
|
||||
}
|
||||
|
|
@ -137,7 +140,7 @@ fullsize_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
|
||||
METHODDEF(void)
|
||||
noop_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
*output_data_ptr = NULL; /* safety check */
|
||||
}
|
||||
|
|
@ -156,14 +159,14 @@ noop_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
|
||||
METHODDEF(void)
|
||||
int_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
register JSAMPROW inptr, outptr;
|
||||
register JSAMPLE invalue;
|
||||
_JSAMPARRAY output_data = *output_data_ptr;
|
||||
register _JSAMPROW inptr, outptr;
|
||||
register _JSAMPLE invalue;
|
||||
register int h;
|
||||
JSAMPROW outend;
|
||||
_JSAMPROW outend;
|
||||
int h_expand, v_expand;
|
||||
int inrow, outrow;
|
||||
|
||||
|
|
@ -184,8 +187,8 @@ int_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
}
|
||||
/* 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);
|
||||
_jcopy_sample_rows(output_data, outrow, output_data, outrow + 1,
|
||||
v_expand - 1, cinfo->output_width);
|
||||
}
|
||||
inrow++;
|
||||
outrow += v_expand;
|
||||
|
|
@ -200,12 +203,12 @@ int_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
|
||||
METHODDEF(void)
|
||||
h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
register JSAMPROW inptr, outptr;
|
||||
register JSAMPLE invalue;
|
||||
JSAMPROW outend;
|
||||
_JSAMPARRAY output_data = *output_data_ptr;
|
||||
register _JSAMPROW inptr, outptr;
|
||||
register _JSAMPLE invalue;
|
||||
_JSAMPROW outend;
|
||||
int inrow;
|
||||
|
||||
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
|
||||
|
|
@ -228,12 +231,12 @@ h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
|
||||
METHODDEF(void)
|
||||
h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
register JSAMPROW inptr, outptr;
|
||||
register JSAMPLE invalue;
|
||||
JSAMPROW outend;
|
||||
_JSAMPARRAY output_data = *output_data_ptr;
|
||||
register _JSAMPROW inptr, outptr;
|
||||
register _JSAMPLE invalue;
|
||||
_JSAMPROW outend;
|
||||
int inrow, outrow;
|
||||
|
||||
inrow = outrow = 0;
|
||||
|
|
@ -246,8 +249,8 @@ h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*outptr++ = invalue;
|
||||
*outptr++ = invalue;
|
||||
}
|
||||
jcopy_sample_rows(output_data, outrow, output_data, outrow + 1, 1,
|
||||
cinfo->output_width);
|
||||
_jcopy_sample_rows(output_data, outrow, output_data, outrow + 1, 1,
|
||||
cinfo->output_width);
|
||||
inrow++;
|
||||
outrow += 2;
|
||||
}
|
||||
|
|
@ -271,10 +274,10 @@ h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
|
||||
METHODDEF(void)
|
||||
h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
register JSAMPROW inptr, outptr;
|
||||
_JSAMPARRAY output_data = *output_data_ptr;
|
||||
register _JSAMPROW inptr, outptr;
|
||||
register int invalue;
|
||||
register JDIMENSION colctr;
|
||||
int inrow;
|
||||
|
|
@ -284,20 +287,20 @@ h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
outptr = output_data[inrow];
|
||||
/* Special case for first column */
|
||||
invalue = *inptr++;
|
||||
*outptr++ = (JSAMPLE)invalue;
|
||||
*outptr++ = (JSAMPLE)((invalue * 3 + inptr[0] + 2) >> 2);
|
||||
*outptr++ = (_JSAMPLE)invalue;
|
||||
*outptr++ = (_JSAMPLE)((invalue * 3 + inptr[0] + 2) >> 2);
|
||||
|
||||
for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
|
||||
/* General case: 3/4 * nearer pixel + 1/4 * further pixel */
|
||||
invalue = (*inptr++) * 3;
|
||||
*outptr++ = (JSAMPLE)((invalue + inptr[-2] + 1) >> 2);
|
||||
*outptr++ = (JSAMPLE)((invalue + inptr[0] + 2) >> 2);
|
||||
*outptr++ = (_JSAMPLE)((invalue + inptr[-2] + 1) >> 2);
|
||||
*outptr++ = (_JSAMPLE)((invalue + inptr[0] + 2) >> 2);
|
||||
}
|
||||
|
||||
/* Special case for last column */
|
||||
invalue = *inptr;
|
||||
*outptr++ = (JSAMPLE)((invalue * 3 + inptr[-1] + 1) >> 2);
|
||||
*outptr++ = (JSAMPLE)invalue;
|
||||
*outptr++ = (_JSAMPLE)((invalue * 3 + inptr[-1] + 1) >> 2);
|
||||
*outptr++ = (_JSAMPLE)invalue;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -311,10 +314,10 @@ h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
|
||||
METHODDEF(void)
|
||||
h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
JSAMPROW inptr0, inptr1, outptr;
|
||||
_JSAMPARRAY output_data = *output_data_ptr;
|
||||
_JSAMPROW inptr0, inptr1, outptr;
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
int thiscolsum, bias;
|
||||
#else
|
||||
|
|
@ -339,7 +342,7 @@ h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
|
||||
for (colctr = 0; colctr < compptr->downsampled_width; colctr++) {
|
||||
thiscolsum = (*inptr0++) * 3 + (*inptr1++);
|
||||
*outptr++ = (JSAMPLE)((thiscolsum + bias) >> 2);
|
||||
*outptr++ = (_JSAMPLE)((thiscolsum + bias) >> 2);
|
||||
}
|
||||
}
|
||||
inrow++;
|
||||
|
|
@ -357,10 +360,10 @@ h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
|
||||
METHODDEF(void)
|
||||
h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
_JSAMPARRAY input_data, _JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
register JSAMPROW inptr0, inptr1, outptr;
|
||||
_JSAMPARRAY output_data = *output_data_ptr;
|
||||
register _JSAMPROW inptr0, inptr1, outptr;
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
register int thiscolsum, lastcolsum, nextcolsum;
|
||||
#else
|
||||
|
|
@ -383,22 +386,22 @@ h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
/* Special case for first column */
|
||||
thiscolsum = (*inptr0++) * 3 + (*inptr1++);
|
||||
nextcolsum = (*inptr0++) * 3 + (*inptr1++);
|
||||
*outptr++ = (JSAMPLE)((thiscolsum * 4 + 8) >> 4);
|
||||
*outptr++ = (JSAMPLE)((thiscolsum * 3 + nextcolsum + 7) >> 4);
|
||||
*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 = (*inptr0++) * 3 + (*inptr1++);
|
||||
*outptr++ = (JSAMPLE)((thiscolsum * 3 + lastcolsum + 8) >> 4);
|
||||
*outptr++ = (JSAMPLE)((thiscolsum * 3 + nextcolsum + 7) >> 4);
|
||||
*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);
|
||||
*outptr++ = (_JSAMPLE)((thiscolsum * 3 + lastcolsum + 8) >> 4);
|
||||
*outptr++ = (_JSAMPLE)((thiscolsum * 4 + 7) >> 4);
|
||||
}
|
||||
inrow++;
|
||||
}
|
||||
|
|
@ -410,7 +413,7 @@ h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_upsampler(j_decompress_ptr cinfo)
|
||||
_jinit_upsampler(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_upsample_ptr upsample;
|
||||
int ci;
|
||||
|
|
@ -418,13 +421,16 @@ jinit_upsampler(j_decompress_ptr cinfo)
|
|||
boolean need_buffer, do_fancy;
|
||||
int h_in_group, v_in_group, h_out_group, v_out_group;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
if (!cinfo->master->jinit_upsampler_no_alloc) {
|
||||
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_upsample;
|
||||
upsample->pub.upsample = sep_upsample;
|
||||
upsample->pub._upsample = sep_upsample;
|
||||
upsample->pub.need_context_rows = FALSE; /* until we find out differently */
|
||||
} else
|
||||
upsample = (my_upsample_ptr)cinfo->upsample;
|
||||
|
|
@ -464,21 +470,25 @@ jinit_upsampler(j_decompress_ptr cinfo)
|
|||
} 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) {
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_h2v1_fancy_upsample())
|
||||
upsample->methods[ci] = jsimd_h2v1_fancy_upsample;
|
||||
else
|
||||
#endif
|
||||
upsample->methods[ci] = h2v1_fancy_upsample;
|
||||
} else {
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_h2v1_upsample())
|
||||
upsample->methods[ci] = jsimd_h2v1_upsample;
|
||||
else
|
||||
#endif
|
||||
upsample->methods[ci] = h2v1_upsample;
|
||||
}
|
||||
} else if (h_in_group == h_out_group &&
|
||||
v_in_group * 2 == v_out_group && do_fancy) {
|
||||
/* Non-fancy upsampling is handled by the generic method */
|
||||
#if defined(__arm__) || defined(__aarch64__) || \
|
||||
defined(_M_ARM) || defined(_M_ARM64)
|
||||
#if defined(WITH_SIMD) && (defined(__arm__) || defined(__aarch64__) || \
|
||||
defined(_M_ARM) || defined(_M_ARM64))
|
||||
if (jsimd_can_h1v2_fancy_upsample())
|
||||
upsample->methods[ci] = jsimd_h1v2_fancy_upsample;
|
||||
else
|
||||
|
|
@ -489,21 +499,25 @@ jinit_upsampler(j_decompress_ptr cinfo)
|
|||
v_in_group * 2 == v_out_group) {
|
||||
/* Special cases for 2h2v upsampling */
|
||||
if (do_fancy && compptr->downsampled_width > 2) {
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_h2v2_fancy_upsample())
|
||||
upsample->methods[ci] = jsimd_h2v2_fancy_upsample;
|
||||
else
|
||||
#endif
|
||||
upsample->methods[ci] = h2v2_fancy_upsample;
|
||||
upsample->pub.need_context_rows = TRUE;
|
||||
} else {
|
||||
#ifdef WITH_SIMD
|
||||
if (jsimd_can_h2v2_upsample())
|
||||
upsample->methods[ci] = jsimd_h2v2_upsample;
|
||||
else
|
||||
#endif
|
||||
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 */
|
||||
#if defined(__mips__)
|
||||
#if defined(WITH_SIMD) && defined(__mips__)
|
||||
if (jsimd_can_int_upsample())
|
||||
upsample->methods[ci] = jsimd_int_upsample;
|
||||
else
|
||||
|
|
@ -514,7 +528,7 @@ jinit_upsampler(j_decompress_ptr cinfo)
|
|||
} else
|
||||
ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
|
||||
if (need_buffer && !cinfo->master->jinit_upsampler_no_alloc) {
|
||||
upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
|
||||
upsample->color_buf[ci] = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION)jround_up((long)cinfo->output_width,
|
||||
(long)cinfo->max_h_samp_factor),
|
||||
|
|
@ -522,3 +536,5 @@ jinit_upsampler(j_decompress_ptr cinfo)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */
|
||||
|
|
|
|||
|
|
@ -3,19 +3,22 @@
|
|||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jpeglib.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
/* Pointer to routine to upsample a single component */
|
||||
typedef void (*upsample1_ptr) (j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data,
|
||||
JSAMPARRAY *output_data_ptr);
|
||||
_JSAMPARRAY input_data,
|
||||
_JSAMPARRAY *output_data_ptr);
|
||||
|
||||
/* Private subobject */
|
||||
|
||||
|
|
@ -29,7 +32,7 @@ typedef struct {
|
|||
* 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];
|
||||
_JSAMPARRAY color_buf[MAX_COMPONENTS];
|
||||
|
||||
/* Per-component upsampling method pointers */
|
||||
upsample1_ptr methods[MAX_COMPONENTS];
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1995-1997, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2020, D. R. Commander.
|
||||
* Copyright (C) 2020, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jpegcomp.h"
|
||||
#include "jpegapicomp.h"
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
|
|
@ -48,6 +48,9 @@ LOCAL(void) transdecode_master_selection(j_decompress_ptr cinfo);
|
|||
GLOBAL(jvirt_barray_ptr *)
|
||||
jpeg_read_coefficients(j_decompress_ptr cinfo)
|
||||
{
|
||||
if (cinfo->master->lossless)
|
||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
||||
|
||||
if (cinfo->global_state == DSTATE_READY) {
|
||||
/* First call: initialize active modules */
|
||||
transdecode_master_selection(cinfo);
|
||||
|
|
@ -127,7 +130,10 @@ transdecode_master_selection(j_decompress_ptr cinfo)
|
|||
}
|
||||
|
||||
/* Always get a full-image coefficient buffer. */
|
||||
jinit_d_coef_controller(cinfo, TRUE);
|
||||
if (cinfo->data_precision == 12)
|
||||
j12init_d_coef_controller(cinfo, TRUE);
|
||||
else
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||
* Modified 1997-2009 by Guido Vollbeding.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2014, 2017, 2021-2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
|
|
@ -53,7 +55,8 @@ JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
|
|||
#if JPEG_LIB_VERSION >= 70
|
||||
JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request")
|
||||
#endif
|
||||
JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
|
||||
JMESSAGE(JERR_BAD_DCT_COEF,
|
||||
"DCT coefficient (lossy) or spatial difference (lossless) out of range")
|
||||
JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
JMESSAGE(JERR_BAD_DROP_SAMPLING,
|
||||
|
|
@ -69,9 +72,9 @@ 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")
|
||||
"Invalid progressive/lossless parameters Ss=%d Se=%d Ah=%d Al=%d")
|
||||
JMESSAGE(JERR_BAD_PROG_SCRIPT,
|
||||
"Invalid progressive parameters at scan script entry %d")
|
||||
"Invalid progressive/lossless 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")
|
||||
|
|
@ -180,7 +183,7 @@ JMESSAGE(JTRC_THUMB_PALETTE,
|
|||
JMESSAGE(JTRC_THUMB_RGB,
|
||||
"JFIF extension marker: RGB thumbnail image, length %u")
|
||||
JMESSAGE(JTRC_UNKNOWN_IDS,
|
||||
"Unrecognized component IDs %d %d %d, assuming YCbCr")
|
||||
"Unrecognized component IDs %d %d %d, assuming YCbCr (lossy) or RGB (lossless)")
|
||||
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")
|
||||
|
|
@ -211,6 +214,8 @@ JMESSAGE(JWRN_BOGUS_ICC, "Corrupt JPEG data: bad ICC marker")
|
|||
JMESSAGE(JERR_BAD_DROP_SAMPLING,
|
||||
"Component index %d: mismatching sampling ratio %d:%d, %d:%d, %c")
|
||||
#endif
|
||||
JMESSAGE(JERR_BAD_RESTART,
|
||||
"Invalid restart interval %d; must be an integer multiple of the number of MCUs in an MCU row (%d)")
|
||||
|
||||
#ifdef JMAKE_ENUM_LIST
|
||||
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_fdct_ifast(DCTELEM *data)
|
||||
_jpeg_fdct_ifast(DCTELEM *data)
|
||||
{
|
||||
DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
DCTELEM tmp10, tmp11, tmp12, tmp13;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015, 2020, D. R. Commander.
|
||||
* Copyright (C) 2015, 2020, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -140,7 +140,7 @@
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_fdct_islow(DCTELEM *data)
|
||||
_jpeg_fdct_islow(DCTELEM *data)
|
||||
{
|
||||
JLONG tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
JLONG tmp10, tmp11, tmp12, tmp13;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
||||
* Modified 2010 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2014, D. R. Commander.
|
||||
* Copyright (C) 2014, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -69,9 +69,9 @@
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_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;
|
||||
|
|
@ -79,8 +79,8 @@ jpeg_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
JCOEFPTR inptr;
|
||||
FLOAT_MULT_TYPE *quantptr;
|
||||
FAST_FLOAT *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
int ctr;
|
||||
FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
|
||||
#define _0_125 ((FLOAT_MULT_TYPE)0.125)
|
||||
|
|
@ -192,7 +192,7 @@ jpeg_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
/* Even part */
|
||||
|
||||
/* Apply signed->unsigned and prepare float->int conversion */
|
||||
z5 = wsptr[0] + ((FAST_FLOAT)CENTERJSAMPLE + (FAST_FLOAT)0.5);
|
||||
z5 = wsptr[0] + ((FAST_FLOAT)_CENTERJSAMPLE + (FAST_FLOAT)0.5);
|
||||
tmp10 = z5 + wsptr[4];
|
||||
tmp11 = z5 - wsptr[4];
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015, D. R. Commander.
|
||||
* Copyright (C) 2015, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -64,10 +64,10 @@
|
|||
* 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
|
||||
* For 8-bit samples, 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,
|
||||
* For 12-bit samples, 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
|
||||
|
|
@ -168,9 +168,9 @@
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_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;
|
||||
|
|
@ -178,8 +178,8 @@ jpeg_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
JCOEFPTR inptr;
|
||||
IFAST_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE2]; /* buffers data between passes */
|
||||
SHIFT_TEMPS /* for DESCALE */
|
||||
|
|
@ -296,7 +296,7 @@ jpeg_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
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 =
|
||||
_JSAMPLE dcval =
|
||||
range_limit[IDESCALE(wsptr[0], PASS1_BITS + 3) & RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modification developed 2002-2018 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015, 2020, D. R. Commander.
|
||||
* Copyright (C) 2015, 2020, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -170,9 +170,9 @@
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp0, tmp1, tmp2, tmp3;
|
||||
JLONG tmp10, tmp11, tmp12, tmp13;
|
||||
|
|
@ -180,8 +180,8 @@ jpeg_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE2]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -314,8 +314,8 @@ jpeg_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
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((JLONG)wsptr[0],
|
||||
PASS1_BITS + 3) & RANGE_MASK];
|
||||
_JSAMPLE dcval = range_limit[(int)DESCALE((JLONG)wsptr[0],
|
||||
PASS1_BITS + 3) & RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
outptr[1] = dcval;
|
||||
|
|
@ -424,17 +424,17 @@ jpeg_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_7x7(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_7x7(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp0, tmp1, tmp2, tmp10, tmp11, tmp12, tmp13;
|
||||
JLONG z1, z2, z3;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[7 * 7]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -573,17 +573,17 @@ jpeg_idct_7x7(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_6x6(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_6x6(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp0, tmp1, tmp2, tmp10, tmp11, tmp12;
|
||||
JLONG z1, z2, z3;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[6 * 6]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -694,17 +694,17 @@ jpeg_idct_6x6(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_5x5(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_5x5(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp0, tmp1, tmp10, tmp11, tmp12;
|
||||
JLONG z1, z2, z3;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[5 * 5]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -809,16 +809,16 @@ jpeg_idct_5x5(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_3x3(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_3x3(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp0, tmp2, tmp10, tmp12;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[3 * 3]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -899,17 +899,17 @@ jpeg_idct_3x3(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_9x9(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_9x9(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp0, tmp1, tmp2, tmp3, tmp10, tmp11, tmp12, tmp13, tmp14;
|
||||
JLONG z1, z2, z3, z4;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[8 * 9]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -1070,9 +1070,9 @@ jpeg_idct_9x9(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_10x10(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_10x10(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp10, tmp11, tmp12, tmp13, tmp14;
|
||||
JLONG tmp20, tmp21, tmp22, tmp23, tmp24;
|
||||
|
|
@ -1080,8 +1080,8 @@ jpeg_idct_10x10(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[8 * 10]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -1265,9 +1265,9 @@ jpeg_idct_10x10(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_11x11(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_11x11(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp10, tmp11, tmp12, tmp13, tmp14;
|
||||
JLONG tmp20, tmp21, tmp22, tmp23, tmp24, tmp25;
|
||||
|
|
@ -1275,8 +1275,8 @@ jpeg_idct_11x11(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[8 * 11]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -1459,9 +1459,9 @@ jpeg_idct_11x11(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_12x12(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_12x12(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp10, tmp11, tmp12, tmp13, tmp14, tmp15;
|
||||
JLONG tmp20, tmp21, tmp22, tmp23, tmp24, tmp25;
|
||||
|
|
@ -1469,8 +1469,8 @@ jpeg_idct_12x12(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[8 * 12]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -1675,9 +1675,9 @@ jpeg_idct_12x12(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_13x13(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_13x13(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp10, tmp11, tmp12, tmp13, tmp14, tmp15;
|
||||
JLONG tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26;
|
||||
|
|
@ -1685,8 +1685,8 @@ jpeg_idct_13x13(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[8 * 13]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -1903,9 +1903,9 @@ jpeg_idct_13x13(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_14x14(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_14x14(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16;
|
||||
JLONG tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26;
|
||||
|
|
@ -1913,8 +1913,8 @@ jpeg_idct_14x14(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[8 * 14]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -2129,9 +2129,9 @@ jpeg_idct_14x14(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_15x15(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_15x15(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16;
|
||||
JLONG tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27;
|
||||
|
|
@ -2139,8 +2139,8 @@ jpeg_idct_15x15(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[8 * 15]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -2371,9 +2371,9 @@ jpeg_idct_15x15(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_16x16(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_16x16(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp0, tmp1, tmp2, tmp3, tmp10, tmp11, tmp12, tmp13;
|
||||
JLONG tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27;
|
||||
|
|
@ -2381,8 +2381,8 @@ jpeg_idct_16x16(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[8 * 16]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015, D. R. Commander.
|
||||
* Copyright (C) 2015, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -118,17 +118,17 @@
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp0, tmp2, tmp10, tmp12;
|
||||
JLONG z1, z2, z3, z4;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE * 4]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -210,8 +210,8 @@ jpeg_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
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((JLONG)wsptr[0],
|
||||
PASS1_BITS + 3) & RANGE_MASK];
|
||||
_JSAMPLE dcval = range_limit[(int)DESCALE((JLONG)wsptr[0],
|
||||
PASS1_BITS + 3) & RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
outptr[1] = dcval;
|
||||
|
|
@ -276,16 +276,16 @@ jpeg_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_jpeg_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, _JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
JLONG tmp0, tmp10, z1;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE *quantptr;
|
||||
int *wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
_JSAMPROW outptr;
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE * 2]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
|
@ -345,8 +345,8 @@ jpeg_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
#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((JLONG)wsptr[0],
|
||||
PASS1_BITS + 3) & RANGE_MASK];
|
||||
_JSAMPLE dcval = range_limit[(int)DESCALE((JLONG)wsptr[0],
|
||||
PASS1_BITS + 3) & RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
outptr[1] = dcval;
|
||||
|
|
@ -387,13 +387,13 @@ jpeg_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_1x1(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
_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);
|
||||
_JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* We hardly need an inverse DCT routine for this: just take the
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1994, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* Copyright (C) 2022-2023, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -123,6 +123,8 @@ static INLINE int GETENV_S(char *buffer, size_t buffer_size, const char *name)
|
|||
|
||||
#else
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* This provides a similar interface to the Microsoft _putenv_s() function, but
|
||||
* other than parameter validation, it has no advantages over setenv().
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* jlossls.h
|
||||
*
|
||||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1998, Thomas G. Lane.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
* This include file contains common declarations for the lossless JPEG
|
||||
* codec modules.
|
||||
*/
|
||||
|
||||
#ifndef JLOSSLS_H
|
||||
#define JLOSSLS_H
|
||||
|
||||
#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jpeglib.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
#define ALLOC_DARRAY(pool_id, diffsperrow, numrows) \
|
||||
(JDIFFARRAY)(*cinfo->mem->alloc_sarray) \
|
||||
((j_common_ptr)cinfo, pool_id, \
|
||||
(diffsperrow) * sizeof(JDIFF) / sizeof(_JSAMPLE), numrows)
|
||||
|
||||
|
||||
/*
|
||||
* Table H.1: Predictors for lossless coding.
|
||||
*/
|
||||
|
||||
#define PREDICTOR1 Ra
|
||||
#define PREDICTOR2 Rb
|
||||
#define PREDICTOR3 Rc
|
||||
#define PREDICTOR4 (int)((JLONG)Ra + (JLONG)Rb - (JLONG)Rc)
|
||||
#define PREDICTOR5 (int)((JLONG)Ra + RIGHT_SHIFT((JLONG)Rb - (JLONG)Rc, 1))
|
||||
#define PREDICTOR6 (int)((JLONG)Rb + RIGHT_SHIFT((JLONG)Ra - (JLONG)Rc, 1))
|
||||
#define PREDICTOR7 (int)RIGHT_SHIFT((JLONG)Ra + (JLONG)Rb, 1)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
|
||||
typedef void (*predict_difference_method_ptr) (j_compress_ptr cinfo, int ci,
|
||||
_JSAMPROW input_buf,
|
||||
_JSAMPROW prev_row,
|
||||
JDIFFROW diff_buf,
|
||||
JDIMENSION width);
|
||||
|
||||
/* Lossless compressor */
|
||||
typedef struct {
|
||||
struct jpeg_forward_dct pub; /* public fields */
|
||||
|
||||
/* It is useful to allow each component to have a separate diff method. */
|
||||
predict_difference_method_ptr predict_difference[MAX_COMPONENTS];
|
||||
|
||||
/* MCU rows left in the restart interval for each component */
|
||||
unsigned int restart_rows_to_go[MAX_COMPONENTS];
|
||||
|
||||
/* Sample scaling */
|
||||
void (*scaler_scale) (j_compress_ptr cinfo, _JSAMPROW input_buf,
|
||||
_JSAMPROW output_buf, JDIMENSION width);
|
||||
} jpeg_lossless_compressor;
|
||||
|
||||
typedef jpeg_lossless_compressor *lossless_comp_ptr;
|
||||
|
||||
#endif /* C_LOSSLESS_SUPPORTED */
|
||||
|
||||
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
|
||||
typedef void (*predict_undifference_method_ptr) (j_decompress_ptr cinfo,
|
||||
int comp_index,
|
||||
JDIFFROW diff_buf,
|
||||
JDIFFROW prev_row,
|
||||
JDIFFROW undiff_buf,
|
||||
JDIMENSION width);
|
||||
|
||||
/* Lossless decompressor */
|
||||
typedef struct {
|
||||
struct jpeg_inverse_dct pub; /* public fields */
|
||||
|
||||
/* It is useful to allow each component to have a separate undiff method. */
|
||||
predict_undifference_method_ptr predict_undifference[MAX_COMPONENTS];
|
||||
|
||||
/* Sample scaling */
|
||||
void (*scaler_scale) (j_decompress_ptr cinfo, JDIFFROW diff_buf,
|
||||
_JSAMPROW output_buf, JDIMENSION width);
|
||||
} jpeg_lossless_decompressor;
|
||||
|
||||
typedef jpeg_lossless_decompressor *lossless_decomp_ptr;
|
||||
|
||||
#endif /* D_LOSSLESS_SUPPORTED */
|
||||
|
||||
#endif /* JLOSSLS_H */
|
||||
|
|
@ -155,7 +155,9 @@ typedef my_memory_mgr *my_mem_ptr;
|
|||
*/
|
||||
|
||||
struct jvirt_sarray_control {
|
||||
JSAMPARRAY mem_buffer; /* => the in-memory buffer */
|
||||
JSAMPARRAY mem_buffer; /* => the in-memory buffer (if
|
||||
cinfo->data_precision is 12, then this is
|
||||
actually a J12SAMPARRAY) */
|
||||
JDIMENSION rows_in_array; /* total virtual array height */
|
||||
JDIMENSION samplesperrow; /* width of array (and of memory buffer) */
|
||||
JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */
|
||||
|
|
@ -351,9 +353,10 @@ alloc_small(j_common_ptr cinfo, int pool_id, size_t sizeofobject)
|
|||
* request is large enough that it may as well be passed directly to
|
||||
* jpeg_get_large; the pool management just links everything together
|
||||
* so that we can free it all on demand.
|
||||
* Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY
|
||||
* structures. The routines that create these structures (see below)
|
||||
* deliberately bunch rows together to ensure a large request size.
|
||||
* Note: the major use of "large" objects is in
|
||||
* JSAMPARRAY/J12SAMPARRAY/J16SAMPARRAY and JBLOCKARRAY structures. The
|
||||
* routines that create these structures (see below) deliberately bunch rows
|
||||
* together to ensure a large request size.
|
||||
*/
|
||||
|
||||
METHODDEF(void *)
|
||||
|
|
@ -437,9 +440,22 @@ alloc_sarray(j_common_ptr cinfo, int pool_id, JDIMENSION samplesperrow,
|
|||
JSAMPROW workspace;
|
||||
JDIMENSION rowsperchunk, currow, i;
|
||||
long ltemp;
|
||||
J12SAMPARRAY result12;
|
||||
J12SAMPROW workspace12;
|
||||
#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
|
||||
J16SAMPARRAY result16;
|
||||
J16SAMPROW workspace16;
|
||||
#endif
|
||||
int data_precision = cinfo->is_decompressor ?
|
||||
((j_decompress_ptr)cinfo)->data_precision :
|
||||
((j_compress_ptr)cinfo)->data_precision;
|
||||
size_t sample_size = data_precision == 16 ?
|
||||
sizeof(J16SAMPLE) : (data_precision == 12 ?
|
||||
sizeof(J12SAMPLE) :
|
||||
sizeof(JSAMPLE));
|
||||
|
||||
/* Make sure each row is properly aligned */
|
||||
if ((ALIGN_SIZE % sizeof(JSAMPLE)) != 0)
|
||||
if ((ALIGN_SIZE % sample_size) != 0)
|
||||
out_of_memory(cinfo, 5); /* safety check */
|
||||
|
||||
if (samplesperrow > MAX_ALLOC_CHUNK) {
|
||||
|
|
@ -448,11 +464,11 @@ alloc_sarray(j_common_ptr cinfo, int pool_id, JDIMENSION samplesperrow,
|
|||
out_of_memory(cinfo, 9);
|
||||
}
|
||||
samplesperrow = (JDIMENSION)round_up_pow2(samplesperrow, (2 * ALIGN_SIZE) /
|
||||
sizeof(JSAMPLE));
|
||||
sample_size);
|
||||
|
||||
/* Calculate max # of rows allowed in one allocation chunk */
|
||||
ltemp = (MAX_ALLOC_CHUNK - sizeof(large_pool_hdr)) /
|
||||
((long)samplesperrow * sizeof(JSAMPLE));
|
||||
((long)samplesperrow * (long)sample_size);
|
||||
if (ltemp <= 0)
|
||||
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
|
||||
if (ltemp < (long)numrows)
|
||||
|
|
@ -461,24 +477,68 @@ alloc_sarray(j_common_ptr cinfo, int pool_id, JDIMENSION samplesperrow,
|
|||
rowsperchunk = numrows;
|
||||
mem->last_rowsperchunk = rowsperchunk;
|
||||
|
||||
/* Get space for row pointers (small object) */
|
||||
result = (JSAMPARRAY)alloc_small(cinfo, pool_id,
|
||||
(size_t)(numrows * sizeof(JSAMPROW)));
|
||||
if (data_precision == 16) {
|
||||
#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
|
||||
/* Get space for row pointers (small object) */
|
||||
result16 = (J16SAMPARRAY)alloc_small(cinfo, pool_id,
|
||||
(size_t)(numrows *
|
||||
sizeof(J16SAMPROW)));
|
||||
|
||||
/* Get the rows themselves (large objects) */
|
||||
currow = 0;
|
||||
while (currow < numrows) {
|
||||
rowsperchunk = MIN(rowsperchunk, numrows - currow);
|
||||
workspace = (JSAMPROW)alloc_large(cinfo, pool_id,
|
||||
(size_t)((size_t)rowsperchunk * (size_t)samplesperrow *
|
||||
sizeof(JSAMPLE)));
|
||||
for (i = rowsperchunk; i > 0; i--) {
|
||||
result[currow++] = workspace;
|
||||
workspace += samplesperrow;
|
||||
/* Get the rows themselves (large objects) */
|
||||
currow = 0;
|
||||
while (currow < numrows) {
|
||||
rowsperchunk = MIN(rowsperchunk, numrows - currow);
|
||||
workspace16 = (J16SAMPROW)alloc_large(cinfo, pool_id,
|
||||
(size_t)((size_t)rowsperchunk * (size_t)samplesperrow * sample_size));
|
||||
for (i = rowsperchunk; i > 0; i--) {
|
||||
result16[currow++] = workspace16;
|
||||
workspace16 += samplesperrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return (JSAMPARRAY)result16;
|
||||
#else
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, data_precision);
|
||||
return NULL;
|
||||
#endif
|
||||
} else if (data_precision == 12) {
|
||||
/* Get space for row pointers (small object) */
|
||||
result12 = (J12SAMPARRAY)alloc_small(cinfo, pool_id,
|
||||
(size_t)(numrows *
|
||||
sizeof(J12SAMPROW)));
|
||||
|
||||
/* Get the rows themselves (large objects) */
|
||||
currow = 0;
|
||||
while (currow < numrows) {
|
||||
rowsperchunk = MIN(rowsperchunk, numrows - currow);
|
||||
workspace12 = (J12SAMPROW)alloc_large(cinfo, pool_id,
|
||||
(size_t)((size_t)rowsperchunk * (size_t)samplesperrow * sample_size));
|
||||
for (i = rowsperchunk; i > 0; i--) {
|
||||
result12[currow++] = workspace12;
|
||||
workspace12 += samplesperrow;
|
||||
}
|
||||
}
|
||||
|
||||
return (JSAMPARRAY)result12;
|
||||
} else {
|
||||
/* Get space for row pointers (small object) */
|
||||
result = (JSAMPARRAY)alloc_small(cinfo, pool_id,
|
||||
(size_t)(numrows * sizeof(JSAMPROW)));
|
||||
|
||||
/* Get the rows themselves (large objects) */
|
||||
currow = 0;
|
||||
while (currow < numrows) {
|
||||
rowsperchunk = MIN(rowsperchunk, numrows - currow);
|
||||
workspace = (JSAMPROW)alloc_large(cinfo, pool_id,
|
||||
(size_t)((size_t)rowsperchunk * (size_t)samplesperrow * sample_size));
|
||||
for (i = rowsperchunk; i > 0; i--) {
|
||||
result[currow++] = workspace;
|
||||
workspace += samplesperrow;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -640,6 +700,13 @@ realize_virt_arrays(j_common_ptr cinfo)
|
|||
size_t minheights, max_minheights;
|
||||
jvirt_sarray_ptr sptr;
|
||||
jvirt_barray_ptr bptr;
|
||||
int data_precision = cinfo->is_decompressor ?
|
||||
((j_decompress_ptr)cinfo)->data_precision :
|
||||
((j_compress_ptr)cinfo)->data_precision;
|
||||
size_t sample_size = data_precision == 16 ?
|
||||
sizeof(J16SAMPLE) : (data_precision == 12 ?
|
||||
sizeof(J12SAMPLE) :
|
||||
sizeof(JSAMPLE));
|
||||
|
||||
/* Compute the minimum space needed (maxaccess rows in each buffer)
|
||||
* and the maximum space needed (full image height in each buffer).
|
||||
|
|
@ -650,10 +717,10 @@ realize_virt_arrays(j_common_ptr cinfo)
|
|||
for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
|
||||
if (sptr->mem_buffer == NULL) { /* if not realized yet */
|
||||
size_t new_space = (long)sptr->rows_in_array *
|
||||
(long)sptr->samplesperrow * sizeof(JSAMPLE);
|
||||
(long)sptr->samplesperrow * sample_size;
|
||||
|
||||
space_per_minheight += (long)sptr->maxaccess *
|
||||
(long)sptr->samplesperrow * sizeof(JSAMPLE);
|
||||
(long)sptr->samplesperrow * sample_size;
|
||||
if (SIZE_MAX - maximum_space < new_space)
|
||||
out_of_memory(cinfo, 10);
|
||||
maximum_space += new_space;
|
||||
|
|
@ -708,7 +775,7 @@ realize_virt_arrays(j_common_ptr cinfo)
|
|||
jpeg_open_backing_store(cinfo, &sptr->b_s_info,
|
||||
(long)sptr->rows_in_array *
|
||||
(long)sptr->samplesperrow *
|
||||
(long)sizeof(JSAMPLE));
|
||||
(long)sample_size);
|
||||
sptr->b_s_open = TRUE;
|
||||
}
|
||||
sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE,
|
||||
|
|
@ -751,8 +818,15 @@ do_sarray_io(j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
|
|||
/* Do backing store read or write of a virtual sample array */
|
||||
{
|
||||
long bytesperrow, file_offset, byte_count, rows, thisrow, i;
|
||||
int data_precision = cinfo->is_decompressor ?
|
||||
((j_decompress_ptr)cinfo)->data_precision :
|
||||
((j_compress_ptr)cinfo)->data_precision;
|
||||
size_t sample_size = data_precision == 16 ?
|
||||
sizeof(J16SAMPLE) : (data_precision == 12 ?
|
||||
sizeof(J12SAMPLE) :
|
||||
sizeof(JSAMPLE));
|
||||
|
||||
bytesperrow = (long)ptr->samplesperrow * sizeof(JSAMPLE);
|
||||
bytesperrow = (long)ptr->samplesperrow * (long)sample_size;
|
||||
file_offset = ptr->cur_start_row * bytesperrow;
|
||||
/* Loop to read or write each allocation chunk in mem_buffer */
|
||||
for (i = 0; i < (long)ptr->rows_in_mem; i += ptr->rowsperchunk) {
|
||||
|
|
@ -766,14 +840,42 @@ do_sarray_io(j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
|
|||
if (rows <= 0) /* this chunk might be past end of file! */
|
||||
break;
|
||||
byte_count = rows * bytesperrow;
|
||||
if (writing)
|
||||
(*ptr->b_s_info.write_backing_store) (cinfo, &ptr->b_s_info,
|
||||
(void *)ptr->mem_buffer[i],
|
||||
file_offset, byte_count);
|
||||
else
|
||||
(*ptr->b_s_info.read_backing_store) (cinfo, &ptr->b_s_info,
|
||||
(void *)ptr->mem_buffer[i],
|
||||
file_offset, byte_count);
|
||||
if (data_precision == 16) {
|
||||
#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
|
||||
J16SAMPARRAY mem_buffer16 = (J16SAMPARRAY)ptr->mem_buffer;
|
||||
|
||||
if (writing)
|
||||
(*ptr->b_s_info.write_backing_store) (cinfo, &ptr->b_s_info,
|
||||
(void *)mem_buffer16[i],
|
||||
file_offset, byte_count);
|
||||
else
|
||||
(*ptr->b_s_info.read_backing_store) (cinfo, &ptr->b_s_info,
|
||||
(void *)mem_buffer16[i],
|
||||
file_offset, byte_count);
|
||||
#else
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, data_precision);
|
||||
#endif
|
||||
} else if (data_precision == 12) {
|
||||
J12SAMPARRAY mem_buffer12 = (J12SAMPARRAY)ptr->mem_buffer;
|
||||
|
||||
if (writing)
|
||||
(*ptr->b_s_info.write_backing_store) (cinfo, &ptr->b_s_info,
|
||||
(void *)mem_buffer12[i],
|
||||
file_offset, byte_count);
|
||||
else
|
||||
(*ptr->b_s_info.read_backing_store) (cinfo, &ptr->b_s_info,
|
||||
(void *)mem_buffer12[i],
|
||||
file_offset, byte_count);
|
||||
} else {
|
||||
if (writing)
|
||||
(*ptr->b_s_info.write_backing_store) (cinfo, &ptr->b_s_info,
|
||||
(void *)ptr->mem_buffer[i],
|
||||
file_offset, byte_count);
|
||||
else
|
||||
(*ptr->b_s_info.read_backing_store) (cinfo, &ptr->b_s_info,
|
||||
(void *)ptr->mem_buffer[i],
|
||||
file_offset, byte_count);
|
||||
}
|
||||
file_offset += byte_count;
|
||||
}
|
||||
}
|
||||
|
|
@ -821,6 +923,13 @@ access_virt_sarray(j_common_ptr cinfo, jvirt_sarray_ptr ptr,
|
|||
{
|
||||
JDIMENSION end_row = start_row + num_rows;
|
||||
JDIMENSION undef_row;
|
||||
int data_precision = cinfo->is_decompressor ?
|
||||
((j_decompress_ptr)cinfo)->data_precision :
|
||||
((j_compress_ptr)cinfo)->data_precision;
|
||||
size_t sample_size = data_precision == 16 ?
|
||||
sizeof(J16SAMPLE) : (data_precision == 12 ?
|
||||
sizeof(J12SAMPLE) :
|
||||
sizeof(JSAMPLE));
|
||||
|
||||
/* debugging check */
|
||||
if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
|
||||
|
|
@ -876,7 +985,7 @@ access_virt_sarray(j_common_ptr cinfo, jvirt_sarray_ptr ptr,
|
|||
if (writable)
|
||||
ptr->first_undef_row = end_row;
|
||||
if (ptr->pre_zero) {
|
||||
size_t bytesperrow = (size_t)ptr->samplesperrow * sizeof(JSAMPLE);
|
||||
size_t bytesperrow = (size_t)ptr->samplesperrow * sample_size;
|
||||
undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
|
||||
end_row -= ptr->cur_start_row;
|
||||
while (undef_row < end_row) {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 1997-2009 by Guido Vollbeding.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009, 2011, 2014-2015, 2018, 2020, D. R. Commander.
|
||||
* Copyright (C) 2009, 2011, 2014-2015, 2018, 2020, 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -41,31 +43,29 @@
|
|||
* 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.
|
||||
*/
|
||||
/* JSAMPLE should be the smallest type that will hold the values 0..255. */
|
||||
|
||||
typedef unsigned char JSAMPLE;
|
||||
#define GETJSAMPLE(value) ((int)(value))
|
||||
|
||||
#define MAXJSAMPLE 255
|
||||
#define CENTERJSAMPLE 128
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 8 */
|
||||
#define MAXJSAMPLE 255
|
||||
#define CENTERJSAMPLE 128
|
||||
|
||||
|
||||
#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.
|
||||
*/
|
||||
/* J12SAMPLE should be the smallest type that will hold the values 0..4095. */
|
||||
|
||||
typedef short JSAMPLE;
|
||||
#define GETJSAMPLE(value) ((int)(value))
|
||||
typedef short J12SAMPLE;
|
||||
|
||||
#define MAXJSAMPLE 4095
|
||||
#define CENTERJSAMPLE 2048
|
||||
#define MAXJ12SAMPLE 4095
|
||||
#define CENTERJ12SAMPLE 2048
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 12 */
|
||||
|
||||
/* J16SAMPLE should be the smallest type that will hold the values 0..65535. */
|
||||
|
||||
typedef unsigned short J16SAMPLE;
|
||||
|
||||
#define MAXJ16SAMPLE 65535
|
||||
#define CENTERJ16SAMPLE 32768
|
||||
|
||||
|
||||
/* Representation of a DCT frequency coefficient.
|
||||
|
|
@ -242,14 +242,16 @@ typedef int boolean;
|
|||
|
||||
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
||||
#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
||||
#define C_LOSSLESS_SUPPORTED /* Lossless JPEG? */
|
||||
#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.)
|
||||
* The exact same statements apply for progressive and lossless JPEG:
|
||||
* the default tables don't work for progressive mode or lossless mode.
|
||||
* (This may get fixed, however.)
|
||||
*/
|
||||
#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */
|
||||
|
||||
|
|
@ -257,6 +259,7 @@ typedef int boolean;
|
|||
|
||||
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
||||
#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
||||
#define D_LOSSLESS_SUPPORTED /* Lossless JPEG? */
|
||||
#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
|
||||
#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
|
||||
#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* jpegcomp.h
|
||||
* jpegapicomp.h
|
||||
*
|
||||
* Copyright (C) 2010, 2020, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
|
|
@ -4,8 +4,10 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 1997-2009 by Guido Vollbeding.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2015-2016, 2019, 2021, D. R. Commander.
|
||||
* Copyright (C) 2015-2017, 2019, 2021-2022, D. R. Commander.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* Copyright (C) 2021, Alex Richardson.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
|
|
@ -17,6 +19,17 @@
|
|||
*/
|
||||
|
||||
|
||||
/* Representation of a spatial difference value.
|
||||
* This should be a signed value of at least 16 bits; int is usually OK.
|
||||
*/
|
||||
|
||||
typedef int JDIFF;
|
||||
|
||||
typedef JDIFF FAR *JDIFFROW; /* pointer to one row of difference values */
|
||||
typedef JDIFFROW *JDIFFARRAY; /* ptr to some rows (a 2-D diff array) */
|
||||
typedef JDIFFARRAY *JDIFFIMAGE; /* a 3-D diff array: top index is color */
|
||||
|
||||
|
||||
/* Declarations for both compression & decompression */
|
||||
|
||||
typedef enum { /* Operating modes for buffer controllers */
|
||||
|
|
@ -61,6 +74,9 @@ typedef __UINTPTR_TYPE__ JUINTPTR;
|
|||
typedef size_t JUINTPTR;
|
||||
#endif
|
||||
|
||||
#define IsExtRGB(cs) \
|
||||
(cs == JCS_RGB || (cs >= JCS_EXT_RGB && cs <= JCS_EXT_ARGB))
|
||||
|
||||
/*
|
||||
* Left shift macro that handles a negative operand without causing any
|
||||
* sanitizer warnings
|
||||
|
|
@ -80,6 +96,7 @@ struct jpeg_comp_master {
|
|||
/* 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 */
|
||||
boolean lossless; /* True if lossless mode is enabled */
|
||||
};
|
||||
|
||||
/* Main buffer control (downsampled-data buffer) */
|
||||
|
|
@ -87,6 +104,12 @@ struct jpeg_c_main_controller {
|
|||
void (*start_pass) (j_compress_ptr cinfo, J_BUF_MODE pass_mode);
|
||||
void (*process_data) (j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail);
|
||||
void (*process_data_12) (j_compress_ptr cinfo, J12SAMPARRAY input_buf,
|
||||
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail);
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
void (*process_data_16) (j_compress_ptr cinfo, J16SAMPARRAY input_buf,
|
||||
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail);
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Compression preprocessing (downsampling input buffer control) */
|
||||
|
|
@ -97,12 +120,32 @@ struct jpeg_c_prep_controller {
|
|||
JSAMPIMAGE output_buf,
|
||||
JDIMENSION *out_row_group_ctr,
|
||||
JDIMENSION out_row_groups_avail);
|
||||
void (*pre_process_data_12) (j_compress_ptr cinfo, J12SAMPARRAY input_buf,
|
||||
JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail,
|
||||
J12SAMPIMAGE output_buf,
|
||||
JDIMENSION *out_row_group_ctr,
|
||||
JDIMENSION out_row_groups_avail);
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
void (*pre_process_data_16) (j_compress_ptr cinfo, J16SAMPARRAY input_buf,
|
||||
JDIMENSION *in_row_ctr,
|
||||
JDIMENSION in_rows_avail,
|
||||
J16SAMPIMAGE output_buf,
|
||||
JDIMENSION *out_row_group_ctr,
|
||||
JDIMENSION out_row_groups_avail);
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Coefficient buffer control */
|
||||
/* Lossy mode: Coefficient buffer control
|
||||
* Lossless mode: Difference buffer control
|
||||
*/
|
||||
struct jpeg_c_coef_controller {
|
||||
void (*start_pass) (j_compress_ptr cinfo, J_BUF_MODE pass_mode);
|
||||
boolean (*compress_data) (j_compress_ptr cinfo, JSAMPIMAGE input_buf);
|
||||
boolean (*compress_data_12) (j_compress_ptr cinfo, J12SAMPIMAGE input_buf);
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
boolean (*compress_data_16) (j_compress_ptr cinfo, J16SAMPIMAGE input_buf);
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Colorspace conversion */
|
||||
|
|
@ -111,6 +154,14 @@ struct jpeg_color_converter {
|
|||
void (*color_convert) (j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows);
|
||||
void (*color_convert_12) (j_compress_ptr cinfo, J12SAMPARRAY input_buf,
|
||||
J12SAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows);
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
void (*color_convert_16) (j_compress_ptr cinfo, J16SAMPARRAY input_buf,
|
||||
J16SAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows);
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Downsampling */
|
||||
|
|
@ -119,24 +170,47 @@ struct jpeg_downsampler {
|
|||
void (*downsample) (j_compress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_index, JSAMPIMAGE output_buf,
|
||||
JDIMENSION out_row_group_index);
|
||||
void (*downsample_12) (j_compress_ptr cinfo, J12SAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_index, J12SAMPIMAGE output_buf,
|
||||
JDIMENSION out_row_group_index);
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
void (*downsample_16) (j_compress_ptr cinfo, J16SAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_index, J16SAMPIMAGE output_buf,
|
||||
JDIMENSION out_row_group_index);
|
||||
#endif
|
||||
|
||||
boolean need_context_rows; /* TRUE if need rows above & below */
|
||||
};
|
||||
|
||||
/* Forward DCT (also controls coefficient quantization) */
|
||||
/* Lossy mode: Forward DCT (also controls coefficient quantization)
|
||||
* Lossless mode: Prediction, sample differencing, and point transform
|
||||
*/
|
||||
struct jpeg_forward_dct {
|
||||
void (*start_pass) (j_compress_ptr cinfo);
|
||||
|
||||
/* Lossy mode */
|
||||
/* perhaps this should be an array??? */
|
||||
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);
|
||||
void (*forward_DCT_12) (j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
J12SAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks);
|
||||
};
|
||||
|
||||
/* Entropy encoding */
|
||||
struct jpeg_entropy_encoder {
|
||||
void (*start_pass) (j_compress_ptr cinfo, boolean gather_statistics);
|
||||
|
||||
/* Lossy mode */
|
||||
boolean (*encode_mcu) (j_compress_ptr cinfo, JBLOCKROW *MCU_data);
|
||||
/* Lossless mode */
|
||||
JDIMENSION (*encode_mcus) (j_compress_ptr cinfo, JDIFFIMAGE diff_buf,
|
||||
JDIMENSION MCU_row_num, JDIMENSION MCU_col_num,
|
||||
JDIMENSION nMCU);
|
||||
|
||||
void (*finish_pass) (j_compress_ptr cinfo);
|
||||
};
|
||||
|
||||
|
|
@ -164,6 +238,7 @@ struct jpeg_decomp_master {
|
|||
|
||||
/* State variables made visible to other modules */
|
||||
boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */
|
||||
boolean lossless; /* True if decompressing a lossless image */
|
||||
|
||||
/* Partial decompression variables */
|
||||
JDIMENSION first_iMCU_col;
|
||||
|
|
@ -193,14 +268,36 @@ struct jpeg_d_main_controller {
|
|||
void (*start_pass) (j_decompress_ptr cinfo, J_BUF_MODE pass_mode);
|
||||
void (*process_data) (j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail);
|
||||
void (*process_data_12) (j_decompress_ptr cinfo, J12SAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail);
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
void (*process_data_16) (j_decompress_ptr cinfo, J16SAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail);
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Coefficient buffer control */
|
||||
/* Lossy mode: Coefficient buffer control
|
||||
* Lossless mode: Difference buffer control
|
||||
*/
|
||||
struct jpeg_d_coef_controller {
|
||||
void (*start_input_pass) (j_decompress_ptr cinfo);
|
||||
int (*consume_data) (j_decompress_ptr cinfo);
|
||||
void (*start_output_pass) (j_decompress_ptr cinfo);
|
||||
int (*decompress_data) (j_decompress_ptr cinfo, JSAMPIMAGE output_buf);
|
||||
int (*decompress_data_12) (j_decompress_ptr cinfo, J12SAMPIMAGE output_buf);
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
int (*decompress_data_16) (j_decompress_ptr cinfo, J16SAMPIMAGE output_buf);
|
||||
#endif
|
||||
|
||||
/* These variables keep track of the current location of the input side. */
|
||||
/* cinfo->input_iMCU_row is also used for this. */
|
||||
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 */
|
||||
|
||||
/* The output side's location is represented by cinfo->output_iMCU_row. */
|
||||
|
||||
/* Lossy mode */
|
||||
/* Pointer to array of coefficient virtual arrays, or NULL if none */
|
||||
jvirt_barray_ptr *coef_arrays;
|
||||
};
|
||||
|
|
@ -213,6 +310,20 @@ struct jpeg_d_post_controller {
|
|||
JDIMENSION in_row_groups_avail,
|
||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail);
|
||||
void (*post_process_data_12) (j_decompress_ptr cinfo, J12SAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
J12SAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail);
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
void (*post_process_data_16) (j_decompress_ptr cinfo, J16SAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail,
|
||||
J16SAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr,
|
||||
JDIMENSION out_rows_avail);
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Marker reading & parsing */
|
||||
|
|
@ -238,24 +349,42 @@ struct jpeg_marker_reader {
|
|||
/* Entropy decoding */
|
||||
struct jpeg_entropy_decoder {
|
||||
void (*start_pass) (j_decompress_ptr cinfo);
|
||||
|
||||
/* Lossy mode */
|
||||
boolean (*decode_mcu) (j_decompress_ptr cinfo, JBLOCKROW *MCU_data);
|
||||
/* Lossless mode */
|
||||
JDIMENSION (*decode_mcus) (j_decompress_ptr cinfo, JDIFFIMAGE diff_buf,
|
||||
JDIMENSION MCU_row_num, JDIMENSION MCU_col_num,
|
||||
JDIMENSION nMCU);
|
||||
boolean (*process_restart) (j_decompress_ptr cinfo);
|
||||
|
||||
/* 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) */
|
||||
/* Lossy mode: Inverse DCT (also performs dequantization)
|
||||
* Lossless mode: Prediction, sample undifferencing, point transform, and
|
||||
* sample size scaling
|
||||
*/
|
||||
typedef void (*inverse_DCT_method_ptr) (j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col);
|
||||
typedef void (*inverse_DCT_12_method_ptr) (j_decompress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block,
|
||||
J12SAMPARRAY output_buf,
|
||||
JDIMENSION output_col);
|
||||
|
||||
struct jpeg_inverse_dct {
|
||||
void (*start_pass) (j_decompress_ptr cinfo);
|
||||
|
||||
/* Lossy mode */
|
||||
/* It is useful to allow each component to have a separate IDCT method. */
|
||||
inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS];
|
||||
inverse_DCT_12_method_ptr inverse_DCT_12[MAX_COMPONENTS];
|
||||
};
|
||||
|
||||
/* Upsampling (note that upsampler must also call color converter) */
|
||||
|
|
@ -265,6 +394,16 @@ struct jpeg_upsampler {
|
|||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail);
|
||||
void (*upsample_12) (j_decompress_ptr cinfo, J12SAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail, J12SAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail);
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
void (*upsample_16) (j_decompress_ptr cinfo, J16SAMPIMAGE input_buf,
|
||||
JDIMENSION *in_row_group_ctr,
|
||||
JDIMENSION in_row_groups_avail, J16SAMPARRAY output_buf,
|
||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail);
|
||||
#endif
|
||||
|
||||
boolean need_context_rows; /* TRUE if need rows above & below */
|
||||
};
|
||||
|
|
@ -275,6 +414,14 @@ struct jpeg_color_deconverter {
|
|||
void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
int num_rows);
|
||||
void (*color_convert_12) (j_decompress_ptr cinfo, J12SAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, J12SAMPARRAY output_buf,
|
||||
int num_rows);
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
void (*color_convert_16) (j_decompress_ptr cinfo, J16SAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, J16SAMPARRAY output_buf,
|
||||
int num_rows);
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Color quantization or color precision reduction */
|
||||
|
|
@ -282,6 +429,8 @@ struct jpeg_color_quantizer {
|
|||
void (*start_pass) (j_decompress_ptr cinfo, boolean is_pre_scan);
|
||||
void (*color_quantize) (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows);
|
||||
void (*color_quantize_12) (j_decompress_ptr cinfo, J12SAMPARRAY input_buf,
|
||||
J12SAMPARRAY output_buf, int num_rows);
|
||||
void (*finish_pass) (j_decompress_ptr cinfo);
|
||||
void (*new_color_map) (j_decompress_ptr cinfo);
|
||||
};
|
||||
|
|
@ -323,36 +472,95 @@ EXTERN(void) jinit_c_master_control(j_compress_ptr cinfo,
|
|||
boolean transcode_only);
|
||||
EXTERN(void) jinit_c_main_controller(j_compress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j12init_c_main_controller(j_compress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) jinit_c_prep_controller(j_compress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j12init_c_prep_controller(j_compress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) jinit_c_coef_controller(j_compress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j12init_c_coef_controller(j_compress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) jinit_color_converter(j_compress_ptr cinfo);
|
||||
EXTERN(void) j12init_color_converter(j_compress_ptr cinfo);
|
||||
EXTERN(void) jinit_downsampler(j_compress_ptr cinfo);
|
||||
EXTERN(void) j12init_downsampler(j_compress_ptr cinfo);
|
||||
EXTERN(void) jinit_forward_dct(j_compress_ptr cinfo);
|
||||
EXTERN(void) j12init_forward_dct(j_compress_ptr cinfo);
|
||||
EXTERN(void) jinit_huff_encoder(j_compress_ptr cinfo);
|
||||
EXTERN(void) jinit_phuff_encoder(j_compress_ptr cinfo);
|
||||
EXTERN(void) jinit_arith_encoder(j_compress_ptr cinfo);
|
||||
EXTERN(void) jinit_marker_writer(j_compress_ptr cinfo);
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
EXTERN(void) j16init_c_main_controller(j_compress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j16init_c_prep_controller(j_compress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j16init_color_converter(j_compress_ptr cinfo);
|
||||
EXTERN(void) j16init_downsampler(j_compress_ptr cinfo);
|
||||
EXTERN(void) jinit_c_diff_controller(j_compress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j12init_c_diff_controller(j_compress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j16init_c_diff_controller(j_compress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) jinit_lhuff_encoder(j_compress_ptr cinfo);
|
||||
EXTERN(void) jinit_lossless_compressor(j_compress_ptr cinfo);
|
||||
EXTERN(void) j12init_lossless_compressor(j_compress_ptr cinfo);
|
||||
EXTERN(void) j16init_lossless_compressor(j_compress_ptr cinfo);
|
||||
#endif
|
||||
|
||||
/* Decompression module initialization routines */
|
||||
EXTERN(void) jinit_master_decompress(j_decompress_ptr cinfo);
|
||||
EXTERN(void) jinit_d_main_controller(j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j12init_d_main_controller(j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) jinit_d_coef_controller(j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j12init_d_coef_controller(j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) jinit_d_post_controller(j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j12init_d_post_controller(j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) jinit_input_controller(j_decompress_ptr cinfo);
|
||||
EXTERN(void) jinit_marker_reader(j_decompress_ptr cinfo);
|
||||
EXTERN(void) jinit_huff_decoder(j_decompress_ptr cinfo);
|
||||
EXTERN(void) jinit_phuff_decoder(j_decompress_ptr cinfo);
|
||||
EXTERN(void) jinit_arith_decoder(j_decompress_ptr cinfo);
|
||||
EXTERN(void) jinit_inverse_dct(j_decompress_ptr cinfo);
|
||||
EXTERN(void) j12init_inverse_dct(j_decompress_ptr cinfo);
|
||||
EXTERN(void) jinit_upsampler(j_decompress_ptr cinfo);
|
||||
EXTERN(void) j12init_upsampler(j_decompress_ptr cinfo);
|
||||
EXTERN(void) jinit_color_deconverter(j_decompress_ptr cinfo);
|
||||
EXTERN(void) j12init_color_deconverter(j_decompress_ptr cinfo);
|
||||
EXTERN(void) jinit_1pass_quantizer(j_decompress_ptr cinfo);
|
||||
EXTERN(void) j12init_1pass_quantizer(j_decompress_ptr cinfo);
|
||||
EXTERN(void) jinit_2pass_quantizer(j_decompress_ptr cinfo);
|
||||
EXTERN(void) j12init_2pass_quantizer(j_decompress_ptr cinfo);
|
||||
EXTERN(void) jinit_merged_upsampler(j_decompress_ptr cinfo);
|
||||
EXTERN(void) j12init_merged_upsampler(j_decompress_ptr cinfo);
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
EXTERN(void) j16init_d_main_controller(j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j16init_d_post_controller(j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j16init_upsampler(j_decompress_ptr cinfo);
|
||||
EXTERN(void) j16init_color_deconverter(j_decompress_ptr cinfo);
|
||||
EXTERN(void) jinit_d_diff_controller(j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j12init_d_diff_controller(j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) j16init_d_diff_controller(j_decompress_ptr cinfo,
|
||||
boolean need_full_buffer);
|
||||
EXTERN(void) jinit_lhuff_decoder(j_decompress_ptr cinfo);
|
||||
EXTERN(void) jinit_lossless_decompressor(j_decompress_ptr cinfo);
|
||||
EXTERN(void) j12init_lossless_decompressor(j_decompress_ptr cinfo);
|
||||
EXTERN(void) j16init_lossless_decompressor(j_decompress_ptr cinfo);
|
||||
#endif
|
||||
|
||||
/* Memory manager initialization */
|
||||
EXTERN(void) jinit_memory_mgr(j_common_ptr cinfo);
|
||||
|
||||
|
|
@ -362,6 +570,14 @@ EXTERN(long) jround_up(long a, long b);
|
|||
EXTERN(void) jcopy_sample_rows(JSAMPARRAY input_array, int source_row,
|
||||
JSAMPARRAY output_array, int dest_row,
|
||||
int num_rows, JDIMENSION num_cols);
|
||||
EXTERN(void) j12copy_sample_rows(J12SAMPARRAY input_array, int source_row,
|
||||
J12SAMPARRAY output_array, int dest_row,
|
||||
int num_rows, JDIMENSION num_cols);
|
||||
#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
|
||||
EXTERN(void) j16copy_sample_rows(J16SAMPARRAY input_array, int source_row,
|
||||
J16SAMPARRAY output_array, int dest_row,
|
||||
int num_rows, JDIMENSION num_cols);
|
||||
#endif
|
||||
EXTERN(void) jcopy_block_row(JBLOCKROW input_row, JBLOCKROW output_row,
|
||||
JDIMENSION num_blocks);
|
||||
EXTERN(void) jzero_far(void *target, size_t bytestozero);
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modified 2002-2009 by Guido Vollbeding.
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009-2011, 2013-2014, 2016-2017, 2020, D. R. Commander.
|
||||
* Copyright (C) 2009-2011, 2013-2014, 2016-2017, 2020, 2022, D. R. Commander.
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
|
|
@ -43,6 +45,13 @@ extern "C" {
|
|||
* if you want to be compatible.
|
||||
*/
|
||||
|
||||
/* NOTE: In lossless mode, an MCU contains one or more samples rather than one
|
||||
* or more 8x8 DCT blocks, so the term "data unit" is used to generically
|
||||
* describe a sample in lossless mode or an 8x8 DCT block in lossy mode. To
|
||||
* preserve backward API/ABI compatibility, the field and macro names retain
|
||||
* the "block" terminology.
|
||||
*/
|
||||
|
||||
#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */
|
||||
#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */
|
||||
#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */
|
||||
|
|
@ -57,9 +66,9 @@ extern "C" {
|
|||
* we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe
|
||||
* sometimes emits noncompliant files doesn't mean you should too.
|
||||
*/
|
||||
#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */
|
||||
#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on data units/MCU */
|
||||
#ifndef D_MAX_BLOCKS_IN_MCU
|
||||
#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */
|
||||
#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on data units/MCU */
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -70,6 +79,20 @@ typedef JSAMPLE *JSAMPROW; /* ptr to one image row of pixel samples. */
|
|||
typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */
|
||||
typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */
|
||||
|
||||
typedef J12SAMPLE *J12SAMPROW; /* ptr to one image row of 12-bit pixel
|
||||
samples. */
|
||||
typedef J12SAMPROW *J12SAMPARRAY; /* ptr to some 12-bit sample rows (a 2-D
|
||||
12-bit sample array) */
|
||||
typedef J12SAMPARRAY *J12SAMPIMAGE; /* a 3-D 12-bit sample array: top index is
|
||||
color */
|
||||
|
||||
typedef J16SAMPLE *J16SAMPROW; /* ptr to one image row of 16-bit pixel
|
||||
samples. */
|
||||
typedef J16SAMPROW *J16SAMPARRAY; /* ptr to some 16-bit sample rows (a 2-D
|
||||
16-bit sample array) */
|
||||
typedef J16SAMPARRAY *J16SAMPIMAGE; /* a 3-D 16-bit sample array: top index is
|
||||
color */
|
||||
|
||||
typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */
|
||||
typedef JBLOCK *JBLOCKROW; /* pointer to one row of coefficient blocks */
|
||||
typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */
|
||||
|
|
@ -135,17 +158,20 @@ typedef struct {
|
|||
/* Remaining fields should be treated as private by applications. */
|
||||
|
||||
/* These values are computed during compression or decompression startup: */
|
||||
/* Component's size in DCT blocks.
|
||||
* Any dummy blocks added to complete an MCU are not counted; therefore
|
||||
* these values do not depend on whether a scan is interleaved or not.
|
||||
/* Component's size in data units.
|
||||
* In lossy mode, any dummy blocks added to complete an MCU are not counted;
|
||||
* therefore these values do not depend on whether a scan is interleaved or
|
||||
* not. In lossless mode, these are always equal to the image width and
|
||||
* height.
|
||||
*/
|
||||
JDIMENSION width_in_blocks;
|
||||
JDIMENSION height_in_blocks;
|
||||
/* Size of a DCT block in samples. Always DCTSIZE for compression.
|
||||
* For decompression this is the size of the output from one DCT block,
|
||||
/* Size of a data unit in samples. Always DCTSIZE for lossy compression.
|
||||
* For lossy decompression this is the size of the output from one DCT block,
|
||||
* reflecting any scaling we choose to apply during the IDCT step.
|
||||
* Values from 1 to 16 are supported.
|
||||
* Note that different components may receive different IDCT scalings.
|
||||
* Values from 1 to 16 are supported. Note that different components may
|
||||
* receive different IDCT scalings. In lossless mode, this is always equal
|
||||
* to 1.
|
||||
*/
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
int DCT_h_scaled_size;
|
||||
|
|
@ -156,8 +182,10 @@ typedef struct {
|
|||
/* The downsampled dimensions are the component's actual, unpadded number
|
||||
* of samples at the main buffer (preprocessing/compression interface), thus
|
||||
* downsampled_width = ceil(image_width * Hi/Hmax)
|
||||
* and similarly for height. For decompression, IDCT scaling is included, so
|
||||
* and similarly for height. For lossy decompression, IDCT scaling is
|
||||
* included, so
|
||||
* downsampled_width = ceil(image_width * Hi/Hmax * DCT_[h_]scaled_size/DCTSIZE)
|
||||
* In lossless mode, these are always equal to the image width and height.
|
||||
*/
|
||||
JDIMENSION downsampled_width; /* actual width in samples */
|
||||
JDIMENSION downsampled_height; /* actual height in samples */
|
||||
|
|
@ -169,12 +197,12 @@ typedef struct {
|
|||
|
||||
/* These values are computed before starting a scan of the component. */
|
||||
/* The decompressor output side may not use these variables. */
|
||||
int MCU_width; /* number of blocks per MCU, horizontally */
|
||||
int MCU_height; /* number of blocks per MCU, vertically */
|
||||
int MCU_width; /* number of data units per MCU, horizontally */
|
||||
int MCU_height; /* number of data units per MCU, vertically */
|
||||
int MCU_blocks; /* MCU_width * MCU_height */
|
||||
int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_[h_]scaled_size */
|
||||
int last_col_width; /* # of non-dummy blocks across in last MCU */
|
||||
int last_row_height; /* # of non-dummy blocks down in last MCU */
|
||||
int last_col_width; /* # of non-dummy data units across in last MCU */
|
||||
int last_row_height; /* # of non-dummy data units down in last MCU */
|
||||
|
||||
/* Saved quantization table for component; NULL if none yet saved.
|
||||
* See jdinput.c comments about the need for this information.
|
||||
|
|
@ -192,8 +220,12 @@ typedef struct {
|
|||
typedef struct {
|
||||
int comps_in_scan; /* number of components encoded in this scan */
|
||||
int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */
|
||||
int Ss, Se; /* progressive JPEG spectral selection parms */
|
||||
int Ah, Al; /* progressive JPEG successive approx. parms */
|
||||
int Ss, Se; /* progressive JPEG spectral selection parms
|
||||
(Ss is the predictor selection value in
|
||||
lossless mode) */
|
||||
int Ah, Al; /* progressive JPEG successive approx. parms
|
||||
(Al is the point transform value in lossless
|
||||
mode) */
|
||||
} jpeg_scan_info;
|
||||
|
||||
/* The decompressor can save APPn and COM markers in a list of these: */
|
||||
|
|
@ -419,11 +451,13 @@ struct jpeg_compress_struct {
|
|||
int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
|
||||
#endif
|
||||
|
||||
JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */
|
||||
/* The coefficient controller receives data in units of MCU rows as defined
|
||||
* for fully interleaved scans (whether the JPEG file is interleaved or not).
|
||||
* There are v_samp_factor * DCTSIZE sample rows of each component in an
|
||||
* "iMCU" (interleaved MCU) row.
|
||||
JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coefficient or
|
||||
difference controller */
|
||||
/* The coefficient or difference controller receives data in units of MCU
|
||||
* rows as defined for fully interleaved scans (whether the JPEG file is
|
||||
* interleaved or not). In lossy mode, there are v_samp_factor * DCTSIZE
|
||||
* sample rows of each component in an "iMCU" (interleaved MCU) row. In
|
||||
* lossless mode, total_iMCU_rows is always equal to the image height.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
@ -437,12 +471,13 @@ struct jpeg_compress_struct {
|
|||
JDIMENSION MCUs_per_row; /* # of MCUs across the image */
|
||||
JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
|
||||
|
||||
int blocks_in_MCU; /* # of DCT blocks per MCU */
|
||||
int blocks_in_MCU; /* # of data units per MCU */
|
||||
int MCU_membership[C_MAX_BLOCKS_IN_MCU];
|
||||
/* MCU_membership[i] is index in cur_comp_info of component owning */
|
||||
/* i'th block in an MCU */
|
||||
/* i'th data unit in an MCU */
|
||||
|
||||
int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
|
||||
int Ss, Se, Ah, Al; /* progressive/lossless JPEG parameters for
|
||||
scan */
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80
|
||||
int block_size; /* the basic DCT block size: 1..16 */
|
||||
|
|
@ -537,7 +572,12 @@ struct jpeg_decompress_struct {
|
|||
* The map has out_color_components rows and actual_number_of_colors columns.
|
||||
*/
|
||||
int actual_number_of_colors; /* number of entries in use */
|
||||
JSAMPARRAY colormap; /* The color map as a 2-D pixel array */
|
||||
JSAMPARRAY colormap; /* The color map as a 2-D pixel array
|
||||
If data_precision is 12 or 16, then this is
|
||||
actually a J12SAMPARRAY or a J16SAMPARRAY,
|
||||
so callers must type-cast it in order to
|
||||
read/write 12-bit or 16-bit samples from/to
|
||||
the array. */
|
||||
|
||||
/* State variables: these variables indicate the progress of decompression.
|
||||
* The application may examine these but must not modify them.
|
||||
|
|
@ -647,15 +687,21 @@ struct jpeg_decompress_struct {
|
|||
#endif
|
||||
|
||||
JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */
|
||||
/* The coefficient controller's input and output progress is measured in
|
||||
* units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows
|
||||
* in fully interleaved JPEG scans, but are used whether the scan is
|
||||
* interleaved or not. We define an iMCU row as v_samp_factor DCT block
|
||||
* rows of each component. Therefore, the IDCT output contains
|
||||
/* The coefficient or difference controller's input and output progress is
|
||||
* measured in units of "iMCU" (interleaved MCU) rows. These are the same as
|
||||
* MCU rows in fully interleaved JPEG scans, but are used whether the scan is
|
||||
* interleaved or not. In lossy mode, we define an iMCU row as v_samp_factor
|
||||
* DCT block rows of each component. Therefore, the IDCT output contains
|
||||
* v_samp_factor*DCT_[v_]scaled_size sample rows of a component per iMCU row.
|
||||
* In lossless mode, total_iMCU_rows is always equal to the image height.
|
||||
*/
|
||||
|
||||
JSAMPLE *sample_range_limit; /* table for fast range-limiting */
|
||||
JSAMPLE *sample_range_limit; /* table for fast range-limiting
|
||||
If data_precision is 12 or 16, then this is
|
||||
actually a J12SAMPLE pointer or a J16SAMPLE
|
||||
pointer, so callers must type-cast it in
|
||||
order to read 12-bit or 16-bit samples from
|
||||
the array. */
|
||||
|
||||
/*
|
||||
* These fields are valid during any one scan.
|
||||
|
|
@ -669,12 +715,13 @@ struct jpeg_decompress_struct {
|
|||
JDIMENSION MCUs_per_row; /* # of MCUs across the image */
|
||||
JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
|
||||
|
||||
int blocks_in_MCU; /* # of DCT blocks per MCU */
|
||||
int blocks_in_MCU; /* # of data units per MCU */
|
||||
int MCU_membership[D_MAX_BLOCKS_IN_MCU];
|
||||
/* MCU_membership[i] is index in cur_comp_info of component owning */
|
||||
/* i'th block in an MCU */
|
||||
/* i'th data unit in an MCU */
|
||||
|
||||
int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
|
||||
int Ss, Se, Ah, Al; /* progressive/lossless JPEG parameters for
|
||||
scan */
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80
|
||||
/* These fields are derived from Se of first SOS marker.
|
||||
|
|
@ -835,6 +882,11 @@ struct jpeg_memory_mgr {
|
|||
void *(*alloc_small) (j_common_ptr cinfo, int pool_id, size_t sizeofobject);
|
||||
void *(*alloc_large) (j_common_ptr cinfo, int pool_id,
|
||||
size_t sizeofobject);
|
||||
/* If cinfo->data_precision is 12 or 16, then this method and the
|
||||
* access_virt_sarray method actually return a J12SAMPARRAY or a
|
||||
* J16SAMPARRAY, so callers must type-cast the return value in order to
|
||||
* read/write 12-bit or 16-bit samples from/to the array.
|
||||
*/
|
||||
JSAMPARRAY (*alloc_sarray) (j_common_ptr cinfo, int pool_id,
|
||||
JDIMENSION samplesperrow, JDIMENSION numrows);
|
||||
JBLOCKARRAY (*alloc_barray) (j_common_ptr cinfo, int pool_id,
|
||||
|
|
@ -916,13 +968,11 @@ EXTERN(void) jpeg_destroy_decompress(j_decompress_ptr cinfo);
|
|||
EXTERN(void) jpeg_stdio_dest(j_compress_ptr cinfo, FILE *outfile);
|
||||
EXTERN(void) jpeg_stdio_src(j_decompress_ptr cinfo, FILE *infile);
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
|
||||
/* Data source and destination managers: memory buffers. */
|
||||
EXTERN(void) jpeg_mem_dest(j_compress_ptr cinfo, unsigned char **outbuffer,
|
||||
unsigned long *outsize);
|
||||
EXTERN(void) jpeg_mem_src(j_decompress_ptr cinfo,
|
||||
const unsigned char *inbuffer, unsigned long insize);
|
||||
#endif
|
||||
|
||||
/* Default parameter setup for compression */
|
||||
EXTERN(void) jpeg_set_defaults(j_compress_ptr cinfo);
|
||||
|
|
@ -942,6 +992,9 @@ EXTERN(void) jpeg_add_quant_table(j_compress_ptr cinfo, int which_tbl,
|
|||
const unsigned int *basic_table,
|
||||
int scale_factor, boolean force_baseline);
|
||||
EXTERN(int) jpeg_quality_scaling(int quality);
|
||||
EXTERN(void) jpeg_enable_lossless(j_compress_ptr cinfo,
|
||||
int predictor_selection_value,
|
||||
int point_transform);
|
||||
EXTERN(void) jpeg_simple_progression(j_compress_ptr cinfo);
|
||||
EXTERN(void) jpeg_suppress_tables(j_compress_ptr cinfo, boolean suppress);
|
||||
EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table(j_common_ptr cinfo);
|
||||
|
|
@ -953,6 +1006,12 @@ EXTERN(void) jpeg_start_compress(j_compress_ptr cinfo,
|
|||
EXTERN(JDIMENSION) jpeg_write_scanlines(j_compress_ptr cinfo,
|
||||
JSAMPARRAY scanlines,
|
||||
JDIMENSION num_lines);
|
||||
EXTERN(JDIMENSION) jpeg12_write_scanlines(j_compress_ptr cinfo,
|
||||
J12SAMPARRAY scanlines,
|
||||
JDIMENSION num_lines);
|
||||
EXTERN(JDIMENSION) jpeg16_write_scanlines(j_compress_ptr cinfo,
|
||||
J16SAMPARRAY scanlines,
|
||||
JDIMENSION num_lines);
|
||||
EXTERN(void) jpeg_finish_compress(j_compress_ptr cinfo);
|
||||
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
|
|
@ -963,6 +1022,9 @@ EXTERN(void) jpeg_calc_jpeg_dimensions(j_compress_ptr cinfo);
|
|||
/* Replaces jpeg_write_scanlines when writing raw downsampled data. */
|
||||
EXTERN(JDIMENSION) jpeg_write_raw_data(j_compress_ptr cinfo, JSAMPIMAGE data,
|
||||
JDIMENSION num_lines);
|
||||
EXTERN(JDIMENSION) jpeg12_write_raw_data(j_compress_ptr cinfo,
|
||||
J12SAMPIMAGE data,
|
||||
JDIMENSION num_lines);
|
||||
|
||||
/* Write a special marker. See libjpeg.txt concerning safe usage. */
|
||||
EXTERN(void) jpeg_write_marker(j_compress_ptr cinfo, int marker,
|
||||
|
|
@ -998,15 +1060,28 @@ EXTERN(boolean) jpeg_start_decompress(j_decompress_ptr cinfo);
|
|||
EXTERN(JDIMENSION) jpeg_read_scanlines(j_decompress_ptr cinfo,
|
||||
JSAMPARRAY scanlines,
|
||||
JDIMENSION max_lines);
|
||||
EXTERN(JDIMENSION) jpeg12_read_scanlines(j_decompress_ptr cinfo,
|
||||
J12SAMPARRAY scanlines,
|
||||
JDIMENSION max_lines);
|
||||
EXTERN(JDIMENSION) jpeg16_read_scanlines(j_decompress_ptr cinfo,
|
||||
J16SAMPARRAY scanlines,
|
||||
JDIMENSION max_lines);
|
||||
EXTERN(JDIMENSION) jpeg_skip_scanlines(j_decompress_ptr cinfo,
|
||||
JDIMENSION num_lines);
|
||||
EXTERN(JDIMENSION) jpeg12_skip_scanlines(j_decompress_ptr cinfo,
|
||||
JDIMENSION num_lines);
|
||||
EXTERN(void) jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
|
||||
JDIMENSION *width);
|
||||
EXTERN(void) jpeg12_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
|
||||
JDIMENSION *width);
|
||||
EXTERN(boolean) jpeg_finish_decompress(j_decompress_ptr cinfo);
|
||||
|
||||
/* Replaces jpeg_read_scanlines when reading raw downsampled data. */
|
||||
EXTERN(JDIMENSION) jpeg_read_raw_data(j_decompress_ptr cinfo, JSAMPIMAGE data,
|
||||
JDIMENSION max_lines);
|
||||
EXTERN(JDIMENSION) jpeg12_read_raw_data(j_decompress_ptr cinfo,
|
||||
J12SAMPIMAGE data,
|
||||
JDIMENSION max_lines);
|
||||
|
||||
/* Additional entry points for buffered-image mode. */
|
||||
EXTERN(boolean) jpeg_has_multiple_scans(j_decompress_ptr cinfo);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009, 2015, D. R. Commander.
|
||||
* Copyright (C) 2009, 2015, 2022-2023, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -16,8 +16,9 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
#ifdef QUANT_1PASS_SUPPORTED
|
||||
#if defined(QUANT_1PASS_SUPPORTED) && BITS_IN_JSAMPLE != 16
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -66,7 +67,7 @@
|
|||
* worse, since the dither may be too much or too little at a given point.
|
||||
*
|
||||
* The normal calculation would be to form pixel value + dither, range-limit
|
||||
* this to 0..MAXJSAMPLE, and then index into the colorindex table as usual.
|
||||
* this to 0.._MAXJSAMPLE, and then index into the colorindex table as usual.
|
||||
* We can skip the separate range-limiting step by extending the colorindex
|
||||
* table in both directions.
|
||||
*/
|
||||
|
|
@ -144,13 +145,13 @@ typedef struct {
|
|||
struct jpeg_color_quantizer pub; /* public fields */
|
||||
|
||||
/* Initially allocated colormap is saved here */
|
||||
JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */
|
||||
_JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */
|
||||
int sv_actual; /* number of entries in use */
|
||||
|
||||
JSAMPARRAY colorindex; /* Precomputed mapping for speed */
|
||||
_JSAMPARRAY colorindex; /* Precomputed mapping for speed */
|
||||
/* colorindex[i][j] = index of color closest to pixel value j in component i,
|
||||
* premultiplied as described above. Since colormap indexes must fit into
|
||||
* JSAMPLEs, the entries of this array will too.
|
||||
* _JSAMPLEs, the entries of this array will too.
|
||||
*/
|
||||
boolean is_padded; /* is the colorindex padded for odither? */
|
||||
|
||||
|
|
@ -248,24 +249,24 @@ select_ncolors(j_decompress_ptr cinfo, int Ncolors[])
|
|||
LOCAL(int)
|
||||
output_value(j_decompress_ptr cinfo, int ci, int j, int maxj)
|
||||
/* Return j'th output value, where j will range from 0 to maxj */
|
||||
/* The output values must fall in 0..MAXJSAMPLE in increasing order */
|
||||
/* The output values must fall in 0.._MAXJSAMPLE in increasing order */
|
||||
{
|
||||
/* We always provide values 0 and MAXJSAMPLE for each component;
|
||||
/* We always provide values 0 and _MAXJSAMPLE for each component;
|
||||
* any additional values are equally spaced between these limits.
|
||||
* (Forcing the upper and lower values to the limits ensures that
|
||||
* dithering can't produce a color outside the selected gamut.)
|
||||
*/
|
||||
return (int)(((JLONG)j * MAXJSAMPLE + maxj / 2) / maxj);
|
||||
return (int)(((JLONG)j * _MAXJSAMPLE + maxj / 2) / maxj);
|
||||
}
|
||||
|
||||
|
||||
LOCAL(int)
|
||||
largest_input_value(j_decompress_ptr cinfo, int ci, int j, int maxj)
|
||||
/* Return largest input value that should map to j'th output value */
|
||||
/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */
|
||||
/* Must have largest(j=0) >= 0, and largest(j=maxj) >= _MAXJSAMPLE */
|
||||
{
|
||||
/* Breakpoints are halfway between values returned by output_value */
|
||||
return (int)(((JLONG)(2 * j + 1) * MAXJSAMPLE + maxj) / (2 * maxj));
|
||||
return (int)(((JLONG)(2 * j + 1) * _MAXJSAMPLE + maxj) / (2 * maxj));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -277,7 +278,7 @@ LOCAL(void)
|
|||
create_colormap(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
JSAMPARRAY colormap; /* Created colormap */
|
||||
_JSAMPARRAY colormap; /* Created colormap */
|
||||
int total_colors; /* Number of distinct output colors */
|
||||
int i, j, k, nci, blksize, blkdist, ptr, val;
|
||||
|
||||
|
|
@ -296,7 +297,7 @@ create_colormap(j_decompress_ptr cinfo)
|
|||
/* The colors are ordered in the map in standard row-major order, */
|
||||
/* i.e. rightmost (highest-indexed) color changes most rapidly. */
|
||||
|
||||
colormap = (*cinfo->mem->alloc_sarray)
|
||||
colormap = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION)total_colors, (JDIMENSION)cinfo->out_color_components);
|
||||
|
||||
|
|
@ -315,7 +316,7 @@ create_colormap(j_decompress_ptr cinfo)
|
|||
for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
|
||||
/* fill in blksize entries beginning at ptr */
|
||||
for (k = 0; k < blksize; k++)
|
||||
colormap[i][ptr + k] = (JSAMPLE)val;
|
||||
colormap[i][ptr + k] = (_JSAMPLE)val;
|
||||
}
|
||||
}
|
||||
blkdist = blksize; /* blksize of this color is blkdist of next */
|
||||
|
|
@ -337,25 +338,25 @@ LOCAL(void)
|
|||
create_colorindex(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
JSAMPROW indexptr;
|
||||
_JSAMPROW indexptr;
|
||||
int i, j, k, nci, blksize, val, pad;
|
||||
|
||||
/* For ordered dither, we pad the color index tables by MAXJSAMPLE in
|
||||
* each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE).
|
||||
/* For ordered dither, we pad the color index tables by _MAXJSAMPLE in
|
||||
* each direction (input index values can be -_MAXJSAMPLE .. 2*_MAXJSAMPLE).
|
||||
* This is not necessary in the other dithering modes. However, we
|
||||
* flag whether it was done in case user changes dithering mode.
|
||||
*/
|
||||
if (cinfo->dither_mode == JDITHER_ORDERED) {
|
||||
pad = MAXJSAMPLE * 2;
|
||||
pad = _MAXJSAMPLE * 2;
|
||||
cquantize->is_padded = TRUE;
|
||||
} else {
|
||||
pad = 0;
|
||||
cquantize->is_padded = FALSE;
|
||||
}
|
||||
|
||||
cquantize->colorindex = (*cinfo->mem->alloc_sarray)
|
||||
cquantize->colorindex = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION)(MAXJSAMPLE + 1 + pad),
|
||||
(JDIMENSION)(_MAXJSAMPLE + 1 + pad),
|
||||
(JDIMENSION)cinfo->out_color_components);
|
||||
|
||||
/* blksize is number of adjacent repeated entries for a component */
|
||||
|
|
@ -368,24 +369,24 @@ create_colorindex(j_decompress_ptr cinfo)
|
|||
|
||||
/* adjust colorindex pointers to provide padding at negative indexes. */
|
||||
if (pad)
|
||||
cquantize->colorindex[i] += MAXJSAMPLE;
|
||||
cquantize->colorindex[i] += _MAXJSAMPLE;
|
||||
|
||||
/* in loop, val = index of current output value, */
|
||||
/* and k = largest j that maps to current val */
|
||||
indexptr = cquantize->colorindex[i];
|
||||
val = 0;
|
||||
k = largest_input_value(cinfo, i, 0, nci - 1);
|
||||
for (j = 0; j <= MAXJSAMPLE; j++) {
|
||||
for (j = 0; j <= _MAXJSAMPLE; j++) {
|
||||
while (j > k) /* advance val if past boundary */
|
||||
k = largest_input_value(cinfo, i, ++val, nci - 1);
|
||||
/* premultiply so that no multiplication needed in main processing */
|
||||
indexptr[j] = (JSAMPLE)(val * blksize);
|
||||
indexptr[j] = (_JSAMPLE)(val * blksize);
|
||||
}
|
||||
/* Pad at both ends if necessary */
|
||||
if (pad)
|
||||
for (j = 1; j <= MAXJSAMPLE; j++) {
|
||||
for (j = 1; j <= _MAXJSAMPLE; j++) {
|
||||
indexptr[-j] = indexptr[0];
|
||||
indexptr[MAXJSAMPLE + j] = indexptr[MAXJSAMPLE];
|
||||
indexptr[_MAXJSAMPLE + j] = indexptr[_MAXJSAMPLE];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -406,16 +407,16 @@ make_odither_array(j_decompress_ptr cinfo, int ncolors)
|
|||
odither = (ODITHER_MATRIX_PTR)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(ODITHER_MATRIX));
|
||||
/* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1).
|
||||
/* The inter-value distance for this color is _MAXJSAMPLE/(ncolors-1).
|
||||
* Hence the dither value for the matrix cell with fill order f
|
||||
* (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1).
|
||||
* (f=0..N-1) should be (N-1-2*f)/(2*N) * _MAXJSAMPLE/(ncolors-1).
|
||||
* On 16-bit-int machine, be careful to avoid overflow.
|
||||
*/
|
||||
den = 2 * ODITHER_CELLS * ((JLONG)(ncolors - 1));
|
||||
for (j = 0; j < ODITHER_SIZE; j++) {
|
||||
for (k = 0; k < ODITHER_SIZE; k++) {
|
||||
num = ((JLONG)(ODITHER_CELLS - 1 -
|
||||
2 * ((int)base_dither_matrix[j][k]))) * MAXJSAMPLE;
|
||||
2 * ((int)base_dither_matrix[j][k]))) * _MAXJSAMPLE;
|
||||
/* Ensure round towards zero despite C's lack of consistency
|
||||
* about rounding negative values in integer division...
|
||||
*/
|
||||
|
|
@ -460,14 +461,14 @@ create_odither_tables(j_decompress_ptr cinfo)
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
color_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
color_quantize(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
/* General case, no dithering */
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
JSAMPARRAY colorindex = cquantize->colorindex;
|
||||
_JSAMPARRAY colorindex = cquantize->colorindex;
|
||||
register int pixcode, ci;
|
||||
register JSAMPROW ptrin, ptrout;
|
||||
register _JSAMPROW ptrin, ptrout;
|
||||
int row;
|
||||
JDIMENSION col;
|
||||
JDIMENSION width = cinfo->output_width;
|
||||
|
|
@ -481,23 +482,23 @@ color_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
for (ci = 0; ci < nc; ci++) {
|
||||
pixcode += colorindex[ci][*ptrin++];
|
||||
}
|
||||
*ptrout++ = (JSAMPLE)pixcode;
|
||||
*ptrout++ = (_JSAMPLE)pixcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
color_quantize3(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
color_quantize3(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
/* Fast path for out_color_components==3, no dithering */
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
register int pixcode;
|
||||
register JSAMPROW ptrin, ptrout;
|
||||
JSAMPROW colorindex0 = cquantize->colorindex[0];
|
||||
JSAMPROW colorindex1 = cquantize->colorindex[1];
|
||||
JSAMPROW colorindex2 = cquantize->colorindex[2];
|
||||
register _JSAMPROW ptrin, ptrout;
|
||||
_JSAMPROW colorindex0 = cquantize->colorindex[0];
|
||||
_JSAMPROW colorindex1 = cquantize->colorindex[1];
|
||||
_JSAMPROW colorindex2 = cquantize->colorindex[2];
|
||||
int row;
|
||||
JDIMENSION col;
|
||||
JDIMENSION width = cinfo->output_width;
|
||||
|
|
@ -509,21 +510,21 @@ color_quantize3(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
pixcode = colorindex0[*ptrin++];
|
||||
pixcode += colorindex1[*ptrin++];
|
||||
pixcode += colorindex2[*ptrin++];
|
||||
*ptrout++ = (JSAMPLE)pixcode;
|
||||
*ptrout++ = (_JSAMPLE)pixcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
quantize_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
quantize_ord_dither(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
/* General case, with ordered dithering */
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
register JSAMPROW input_ptr;
|
||||
register JSAMPROW output_ptr;
|
||||
JSAMPROW colorindex_ci;
|
||||
register _JSAMPROW input_ptr;
|
||||
register _JSAMPROW output_ptr;
|
||||
_JSAMPROW colorindex_ci;
|
||||
int *dither; /* points to active row of dither matrix */
|
||||
int row_index, col_index; /* current indexes into dither matrix */
|
||||
int nc = cinfo->out_color_components;
|
||||
|
|
@ -534,7 +535,7 @@ quantize_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
|
||||
for (row = 0; row < num_rows; row++) {
|
||||
/* Initialize output values to 0 so can process components separately */
|
||||
jzero_far((void *)output_buf[row], (size_t)(width * sizeof(JSAMPLE)));
|
||||
jzero_far((void *)output_buf[row], (size_t)(width * sizeof(_JSAMPLE)));
|
||||
row_index = cquantize->row_index;
|
||||
for (ci = 0; ci < nc; ci++) {
|
||||
input_ptr = input_buf[row] + ci;
|
||||
|
|
@ -544,11 +545,11 @@ quantize_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
col_index = 0;
|
||||
|
||||
for (col = width; col > 0; col--) {
|
||||
/* Form pixel value + dither, range-limit to 0..MAXJSAMPLE,
|
||||
/* Form pixel value + dither, range-limit to 0.._MAXJSAMPLE,
|
||||
* select output value, accumulate into output code for this pixel.
|
||||
* Range-limiting need not be done explicitly, as we have extended
|
||||
* the colorindex table to produce the right answers for out-of-range
|
||||
* inputs. The maximum dither is +- MAXJSAMPLE; this sets the
|
||||
* inputs. The maximum dither is +- _MAXJSAMPLE; this sets the
|
||||
* required amount of padding.
|
||||
*/
|
||||
*output_ptr +=
|
||||
|
|
@ -566,17 +567,17 @@ quantize_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
|
||||
|
||||
METHODDEF(void)
|
||||
quantize3_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
quantize3_ord_dither(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
/* Fast path for out_color_components==3, with ordered dithering */
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
register int pixcode;
|
||||
register JSAMPROW input_ptr;
|
||||
register JSAMPROW output_ptr;
|
||||
JSAMPROW colorindex0 = cquantize->colorindex[0];
|
||||
JSAMPROW colorindex1 = cquantize->colorindex[1];
|
||||
JSAMPROW colorindex2 = cquantize->colorindex[2];
|
||||
register _JSAMPROW input_ptr;
|
||||
register _JSAMPROW output_ptr;
|
||||
_JSAMPROW colorindex0 = cquantize->colorindex[0];
|
||||
_JSAMPROW colorindex1 = cquantize->colorindex[1];
|
||||
_JSAMPROW colorindex2 = cquantize->colorindex[2];
|
||||
int *dither0; /* points to active row of dither matrix */
|
||||
int *dither1;
|
||||
int *dither2;
|
||||
|
|
@ -598,7 +599,7 @@ quantize3_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
pixcode = colorindex0[(*input_ptr++) + dither0[col_index]];
|
||||
pixcode += colorindex1[(*input_ptr++) + dither1[col_index]];
|
||||
pixcode += colorindex2[(*input_ptr++) + dither2[col_index]];
|
||||
*output_ptr++ = (JSAMPLE)pixcode;
|
||||
*output_ptr++ = (_JSAMPLE)pixcode;
|
||||
col_index = (col_index + 1) & ODITHER_MASK;
|
||||
}
|
||||
row_index = (row_index + 1) & ODITHER_MASK;
|
||||
|
|
@ -608,8 +609,8 @@ quantize3_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
|
||||
|
||||
METHODDEF(void)
|
||||
quantize_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
quantize_fs_dither(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
/* General case, with Floyd-Steinberg dithering */
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
|
|
@ -619,10 +620,10 @@ quantize_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
LOCFSERROR bnexterr; /* error for below/next col */
|
||||
LOCFSERROR delta;
|
||||
register FSERRPTR errorptr; /* => fserrors[] at column before current */
|
||||
register JSAMPROW input_ptr;
|
||||
register JSAMPROW output_ptr;
|
||||
JSAMPROW colorindex_ci;
|
||||
JSAMPROW colormap_ci;
|
||||
register _JSAMPROW input_ptr;
|
||||
register _JSAMPROW output_ptr;
|
||||
_JSAMPROW colorindex_ci;
|
||||
_JSAMPROW colormap_ci;
|
||||
int pixcode;
|
||||
int nc = cinfo->out_color_components;
|
||||
int dir; /* 1 for left-to-right, -1 for right-to-left */
|
||||
|
|
@ -631,12 +632,12 @@ quantize_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
int row;
|
||||
JDIMENSION col;
|
||||
JDIMENSION width = cinfo->output_width;
|
||||
JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
_JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
SHIFT_TEMPS
|
||||
|
||||
for (row = 0; row < num_rows; row++) {
|
||||
/* Initialize output values to 0 so can process components separately */
|
||||
jzero_far((void *)output_buf[row], (size_t)(width * sizeof(JSAMPLE)));
|
||||
jzero_far((void *)output_buf[row], (size_t)(width * sizeof(_JSAMPLE)));
|
||||
for (ci = 0; ci < nc; ci++) {
|
||||
input_ptr = input_buf[row] + ci;
|
||||
output_ptr = output_buf[row];
|
||||
|
|
@ -670,15 +671,15 @@ quantize_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
* Note: errorptr points to *previous* column's array entry.
|
||||
*/
|
||||
cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4);
|
||||
/* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
|
||||
* The maximum error is +- MAXJSAMPLE; this sets the required size
|
||||
/* Form pixel value + error, and range-limit to 0.._MAXJSAMPLE.
|
||||
* The maximum error is +- _MAXJSAMPLE; this sets the required size
|
||||
* of the range_limit array.
|
||||
*/
|
||||
cur += *input_ptr;
|
||||
cur = range_limit[cur];
|
||||
/* Select output value, accumulate into output code for this pixel */
|
||||
pixcode = colorindex_ci[cur];
|
||||
*output_ptr += (JSAMPLE)pixcode;
|
||||
*output_ptr += (_JSAMPLE)pixcode;
|
||||
/* Compute actual representation error at this pixel */
|
||||
/* Note: we can do this even though we don't have the final */
|
||||
/* pixel code, because the colormap is orthogonal. */
|
||||
|
|
@ -745,22 +746,22 @@ start_pass_1_quant(j_decompress_ptr cinfo, boolean is_pre_scan)
|
|||
int i;
|
||||
|
||||
/* Install my colormap. */
|
||||
cinfo->colormap = cquantize->sv_colormap;
|
||||
cinfo->colormap = (JSAMPARRAY)cquantize->sv_colormap;
|
||||
cinfo->actual_number_of_colors = cquantize->sv_actual;
|
||||
|
||||
/* Initialize for desired dithering mode. */
|
||||
switch (cinfo->dither_mode) {
|
||||
case JDITHER_NONE:
|
||||
if (cinfo->out_color_components == 3)
|
||||
cquantize->pub.color_quantize = color_quantize3;
|
||||
cquantize->pub._color_quantize = color_quantize3;
|
||||
else
|
||||
cquantize->pub.color_quantize = color_quantize;
|
||||
cquantize->pub._color_quantize = color_quantize;
|
||||
break;
|
||||
case JDITHER_ORDERED:
|
||||
if (cinfo->out_color_components == 3)
|
||||
cquantize->pub.color_quantize = quantize3_ord_dither;
|
||||
cquantize->pub._color_quantize = quantize3_ord_dither;
|
||||
else
|
||||
cquantize->pub.color_quantize = quantize_ord_dither;
|
||||
cquantize->pub._color_quantize = quantize_ord_dither;
|
||||
cquantize->row_index = 0; /* initialize state for ordered dither */
|
||||
/* If user changed to ordered dither from another mode,
|
||||
* we must recreate the color index table with padding.
|
||||
|
|
@ -773,7 +774,7 @@ start_pass_1_quant(j_decompress_ptr cinfo, boolean is_pre_scan)
|
|||
create_odither_tables(cinfo);
|
||||
break;
|
||||
case JDITHER_FS:
|
||||
cquantize->pub.color_quantize = quantize_fs_dither;
|
||||
cquantize->pub._color_quantize = quantize_fs_dither;
|
||||
cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */
|
||||
/* Allocate Floyd-Steinberg workspace if didn't already. */
|
||||
if (cquantize->fserrors[0] == NULL)
|
||||
|
|
@ -818,10 +819,17 @@ new_color_map_1_quant(j_decompress_ptr cinfo)
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_1pass_quantizer(j_decompress_ptr cinfo)
|
||||
_jinit_1pass_quantizer(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_cquantize_ptr cquantize;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
/* Color quantization is not supported with lossless JPEG images */
|
||||
if (cinfo->master->lossless)
|
||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
||||
|
||||
cquantize = (my_cquantize_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_cquantizer));
|
||||
|
|
@ -835,9 +843,9 @@ jinit_1pass_quantizer(j_decompress_ptr cinfo)
|
|||
/* Make sure my internal arrays won't overflow */
|
||||
if (cinfo->out_color_components > MAX_Q_COMPS)
|
||||
ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS);
|
||||
/* Make sure colormap indexes can be represented by JSAMPLEs */
|
||||
if (cinfo->desired_number_of_colors > (MAXJSAMPLE + 1))
|
||||
ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE + 1);
|
||||
/* Make sure colormap indexes can be represented by _JSAMPLEs */
|
||||
if (cinfo->desired_number_of_colors > (_MAXJSAMPLE + 1))
|
||||
ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, _MAXJSAMPLE + 1);
|
||||
|
||||
/* Create the colormap and color index table. */
|
||||
create_colormap(cinfo);
|
||||
|
|
@ -853,4 +861,4 @@ jinit_1pass_quantizer(j_decompress_ptr cinfo)
|
|||
alloc_fs_workspace(cinfo);
|
||||
}
|
||||
|
||||
#endif /* QUANT_1PASS_SUPPORTED */
|
||||
#endif /* defined(QUANT_1PASS_SUPPORTED) && BITS_IN_JSAMPLE != 16 */
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* This file was part of the Independent JPEG Group's software:
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2009, 2014-2015, 2020, D. R. Commander.
|
||||
* Copyright (C) 2009, 2014-2015, 2020, 2022-2023, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*
|
||||
|
|
@ -23,8 +23,9 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
#ifdef QUANT_2PASS_SUPPORTED
|
||||
#if defined(QUANT_2PASS_SUPPORTED) && BITS_IN_JSAMPLE != 16
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -106,7 +107,7 @@ static const int c_scales[3] = { R_SCALE, G_SCALE, B_SCALE };
|
|||
* each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries.
|
||||
*/
|
||||
|
||||
#define MAXNUMCOLORS (MAXJSAMPLE + 1) /* maximum size of colormap */
|
||||
#define MAXNUMCOLORS (_MAXJSAMPLE + 1) /* maximum size of colormap */
|
||||
|
||||
/* These will do the right thing for either R,G,B or B,G,R color order,
|
||||
* but you may not like the results for other color orders.
|
||||
|
|
@ -173,7 +174,7 @@ typedef struct {
|
|||
struct jpeg_color_quantizer pub; /* public fields */
|
||||
|
||||
/* Space for the eventually created colormap is stashed here */
|
||||
JSAMPARRAY sv_colormap; /* colormap allocated at init time */
|
||||
_JSAMPARRAY sv_colormap; /* colormap allocated at init time */
|
||||
int desired; /* desired # of colors = size of colormap */
|
||||
|
||||
/* Variables for accumulating image statistics */
|
||||
|
|
@ -200,11 +201,11 @@ typedef my_cquantizer *my_cquantize_ptr;
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
prescan_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
prescan_quantize(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
register JSAMPROW ptr;
|
||||
register _JSAMPROW ptr;
|
||||
register histptr histp;
|
||||
register hist3d histogram = cquantize->histogram;
|
||||
int row;
|
||||
|
|
@ -377,7 +378,7 @@ have_c2max:
|
|||
* against making long narrow boxes, and it has the side benefit that
|
||||
* a box is splittable iff norm > 0.
|
||||
* Since the differences are expressed in histogram-cell units,
|
||||
* we have to shift back to JSAMPLE units to get consistent distances;
|
||||
* we have to shift back to _JSAMPLE units to get consistent distances;
|
||||
* after which, we scale according to the selected distance scale factors.
|
||||
*/
|
||||
dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE;
|
||||
|
|
@ -508,9 +509,12 @@ compute_color(j_decompress_ptr cinfo, boxptr boxp, int icolor)
|
|||
}
|
||||
}
|
||||
|
||||
cinfo->colormap[0][icolor] = (JSAMPLE)((c0total + (total >> 1)) / total);
|
||||
cinfo->colormap[1][icolor] = (JSAMPLE)((c1total + (total >> 1)) / total);
|
||||
cinfo->colormap[2][icolor] = (JSAMPLE)((c2total + (total >> 1)) / total);
|
||||
((_JSAMPARRAY)cinfo->colormap)[0][icolor] =
|
||||
(_JSAMPLE)((c0total + (total >> 1)) / total);
|
||||
((_JSAMPARRAY)cinfo->colormap)[1][icolor] =
|
||||
(_JSAMPLE)((c1total + (total >> 1)) / total);
|
||||
((_JSAMPARRAY)cinfo->colormap)[2][icolor] =
|
||||
(_JSAMPLE)((c2total + (total >> 1)) / total);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -528,11 +532,11 @@ select_colors(j_decompress_ptr cinfo, int desired_colors)
|
|||
/* Initialize one box containing whole space */
|
||||
numboxes = 1;
|
||||
boxlist[0].c0min = 0;
|
||||
boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT;
|
||||
boxlist[0].c0max = _MAXJSAMPLE >> C0_SHIFT;
|
||||
boxlist[0].c1min = 0;
|
||||
boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT;
|
||||
boxlist[0].c1max = _MAXJSAMPLE >> C1_SHIFT;
|
||||
boxlist[0].c2min = 0;
|
||||
boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT;
|
||||
boxlist[0].c2max = _MAXJSAMPLE >> C2_SHIFT;
|
||||
/* Shrink it to actually-used volume and set its statistics */
|
||||
update_box(cinfo, &boxlist[0]);
|
||||
/* Perform median-cut to produce final box list */
|
||||
|
|
@ -623,7 +627,7 @@ select_colors(j_decompress_ptr cinfo, int desired_colors)
|
|||
|
||||
LOCAL(int)
|
||||
find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
||||
JSAMPLE colorlist[])
|
||||
_JSAMPLE colorlist[])
|
||||
/* Locate the colormap entries close enough to an update box to be candidates
|
||||
* for the nearest entry to some cell(s) in the update box. The update box
|
||||
* is specified by the center coordinates of its first cell. The number of
|
||||
|
|
@ -665,7 +669,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
|||
|
||||
for (i = 0; i < numcolors; i++) {
|
||||
/* We compute the squared-c0-distance term, then add in the other two. */
|
||||
x = cinfo->colormap[0][i];
|
||||
x = ((_JSAMPARRAY)cinfo->colormap)[0][i];
|
||||
if (x < minc0) {
|
||||
tdist = (x - minc0) * C0_SCALE;
|
||||
min_dist = tdist * tdist;
|
||||
|
|
@ -688,7 +692,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
|||
}
|
||||
}
|
||||
|
||||
x = cinfo->colormap[1][i];
|
||||
x = ((_JSAMPARRAY)cinfo->colormap)[1][i];
|
||||
if (x < minc1) {
|
||||
tdist = (x - minc1) * C1_SCALE;
|
||||
min_dist += tdist * tdist;
|
||||
|
|
@ -710,7 +714,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
|||
}
|
||||
}
|
||||
|
||||
x = cinfo->colormap[2][i];
|
||||
x = ((_JSAMPARRAY)cinfo->colormap)[2][i];
|
||||
if (x < minc2) {
|
||||
tdist = (x - minc2) * C2_SCALE;
|
||||
min_dist += tdist * tdist;
|
||||
|
|
@ -744,7 +748,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
|||
ncolors = 0;
|
||||
for (i = 0; i < numcolors; i++) {
|
||||
if (mindist[i] <= minmaxdist)
|
||||
colorlist[ncolors++] = (JSAMPLE)i;
|
||||
colorlist[ncolors++] = (_JSAMPLE)i;
|
||||
}
|
||||
return ncolors;
|
||||
}
|
||||
|
|
@ -752,7 +756,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
|||
|
||||
LOCAL(void)
|
||||
find_best_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
||||
int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[])
|
||||
int numcolors, _JSAMPLE colorlist[], _JSAMPLE bestcolor[])
|
||||
/* Find the closest colormap entry for each cell in the update box,
|
||||
* given the list of candidate colors prepared by find_nearby_colors.
|
||||
* Return the indexes of the closest entries in the bestcolor[] array.
|
||||
|
|
@ -763,7 +767,7 @@ find_best_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
|||
int ic0, ic1, ic2;
|
||||
int i, icolor;
|
||||
register JLONG *bptr; /* pointer into bestdist[] array */
|
||||
JSAMPLE *cptr; /* pointer into bestcolor[] array */
|
||||
_JSAMPLE *cptr; /* pointer into bestcolor[] array */
|
||||
JLONG dist0, dist1; /* initial distance values */
|
||||
register JLONG dist2; /* current distance in inner loop */
|
||||
JLONG xx0, xx1; /* distance increments */
|
||||
|
|
@ -790,11 +794,11 @@ find_best_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
|||
for (i = 0; i < numcolors; i++) {
|
||||
icolor = colorlist[i];
|
||||
/* Compute (square of) distance from minc0/c1/c2 to this color */
|
||||
inc0 = (minc0 - cinfo->colormap[0][icolor]) * C0_SCALE;
|
||||
inc0 = (minc0 - ((_JSAMPARRAY)cinfo->colormap)[0][icolor]) * C0_SCALE;
|
||||
dist0 = inc0 * inc0;
|
||||
inc1 = (minc1 - cinfo->colormap[1][icolor]) * C1_SCALE;
|
||||
inc1 = (minc1 - ((_JSAMPARRAY)cinfo->colormap)[1][icolor]) * C1_SCALE;
|
||||
dist0 += inc1 * inc1;
|
||||
inc2 = (minc2 - cinfo->colormap[2][icolor]) * C2_SCALE;
|
||||
inc2 = (minc2 - ((_JSAMPARRAY)cinfo->colormap)[2][icolor]) * C2_SCALE;
|
||||
dist0 += inc2 * inc2;
|
||||
/* Form the initial difference increments */
|
||||
inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
|
||||
|
|
@ -813,7 +817,7 @@ find_best_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
|
|||
for (ic2 = BOX_C2_ELEMS - 1; ic2 >= 0; ic2--) {
|
||||
if (dist2 < *bptr) {
|
||||
*bptr = dist2;
|
||||
*cptr = (JSAMPLE)icolor;
|
||||
*cptr = (_JSAMPLE)icolor;
|
||||
}
|
||||
dist2 += xx2;
|
||||
xx2 += 2 * STEP_C2 * STEP_C2;
|
||||
|
|
@ -840,13 +844,13 @@ fill_inverse_cmap(j_decompress_ptr cinfo, int c0, int c1, int c2)
|
|||
hist3d histogram = cquantize->histogram;
|
||||
int minc0, minc1, minc2; /* lower left corner of update box */
|
||||
int ic0, ic1, ic2;
|
||||
register JSAMPLE *cptr; /* pointer into bestcolor[] array */
|
||||
register _JSAMPLE *cptr; /* pointer into bestcolor[] array */
|
||||
register histptr cachep; /* pointer into main cache array */
|
||||
/* This array lists the candidate colormap indexes. */
|
||||
JSAMPLE colorlist[MAXNUMCOLORS];
|
||||
_JSAMPLE colorlist[MAXNUMCOLORS];
|
||||
int numcolors; /* number of candidate colors */
|
||||
/* This array holds the actually closest colormap index for each cell. */
|
||||
JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
|
||||
_JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
|
||||
|
||||
/* Convert cell coordinates to update box ID */
|
||||
c0 >>= BOX_C0_LOG;
|
||||
|
|
@ -891,13 +895,13 @@ fill_inverse_cmap(j_decompress_ptr cinfo, int c0, int c1, int c2)
|
|||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
pass2_no_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
pass2_no_dither(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
/* This version performs no dithering */
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
hist3d histogram = cquantize->histogram;
|
||||
register JSAMPROW inptr, outptr;
|
||||
register _JSAMPROW inptr, outptr;
|
||||
register histptr cachep;
|
||||
register int c0, c1, c2;
|
||||
int row;
|
||||
|
|
@ -918,15 +922,15 @@ pass2_no_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
if (*cachep == 0)
|
||||
fill_inverse_cmap(cinfo, c0, c1, c2);
|
||||
/* Now emit the colormap index for this cell */
|
||||
*outptr++ = (JSAMPLE)(*cachep - 1);
|
||||
*outptr++ = (_JSAMPLE)(*cachep - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
pass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
pass2_fs_dither(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
/* This version performs Floyd-Steinberg dithering */
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
|
|
@ -935,19 +939,19 @@ pass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */
|
||||
LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */
|
||||
register FSERRPTR errorptr; /* => fserrors[] at column before current */
|
||||
JSAMPROW inptr; /* => current input pixel */
|
||||
JSAMPROW outptr; /* => current output pixel */
|
||||
_JSAMPROW inptr; /* => current input pixel */
|
||||
_JSAMPROW outptr; /* => current output pixel */
|
||||
histptr cachep;
|
||||
int dir; /* +1 or -1 depending on direction */
|
||||
int dir3; /* 3*dir, for advancing inptr & errorptr */
|
||||
int row;
|
||||
JDIMENSION col;
|
||||
JDIMENSION width = cinfo->output_width;
|
||||
JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
_JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
int *error_limit = cquantize->error_limiter;
|
||||
JSAMPROW colormap0 = cinfo->colormap[0];
|
||||
JSAMPROW colormap1 = cinfo->colormap[1];
|
||||
JSAMPROW colormap2 = cinfo->colormap[2];
|
||||
_JSAMPROW colormap0 = ((_JSAMPARRAY)cinfo->colormap)[0];
|
||||
_JSAMPROW colormap1 = ((_JSAMPARRAY)cinfo->colormap)[1];
|
||||
_JSAMPROW colormap2 = ((_JSAMPARRAY)cinfo->colormap)[2];
|
||||
SHIFT_TEMPS
|
||||
|
||||
for (row = 0; row < num_rows; row++) {
|
||||
|
|
@ -992,8 +996,8 @@ pass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
cur0 = error_limit[cur0];
|
||||
cur1 = error_limit[cur1];
|
||||
cur2 = error_limit[cur2];
|
||||
/* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
|
||||
* The maximum error is +- MAXJSAMPLE (or less with error limiting);
|
||||
/* Form pixel value + error, and range-limit to 0.._MAXJSAMPLE.
|
||||
* The maximum error is +- _MAXJSAMPLE (or less with error limiting);
|
||||
* this sets the required size of the range_limit array.
|
||||
*/
|
||||
cur0 += inptr[0];
|
||||
|
|
@ -1013,7 +1017,7 @@ pass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
/* Now emit the colormap index for this cell */
|
||||
{
|
||||
register int pixcode = *cachep - 1;
|
||||
*outptr = (JSAMPLE)pixcode;
|
||||
*outptr = (_JSAMPLE)pixcode;
|
||||
/* Compute representation error for this pixel */
|
||||
cur0 -= colormap0[pixcode];
|
||||
cur1 -= colormap1[pixcode];
|
||||
|
|
@ -1064,7 +1068,7 @@ pass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
/*
|
||||
* Initialize the error-limiting transfer function (lookup table).
|
||||
* The raw F-S error computation can potentially compute error values of up to
|
||||
* +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be
|
||||
* +- _MAXJSAMPLE. But we want the maximum correction applied to a pixel to be
|
||||
* much less, otherwise obviously wrong pixels will be created. (Typical
|
||||
* effects include weird fringes at color-area boundaries, isolated bright
|
||||
* pixels in a dark area, etc.) The standard advice for avoiding this problem
|
||||
|
|
@ -1073,7 +1077,7 @@ pass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|||
* error buildup. However, that only prevents the error from getting
|
||||
* completely out of hand; Aaron Giles reports that error limiting improves
|
||||
* the results even with corner colors allocated.
|
||||
* A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty
|
||||
* A simple clamping of the error values to about +- _MAXJSAMPLE/8 works pretty
|
||||
* well, but the smoother transfer function used below is even better. Thanks
|
||||
* to Aaron Giles for this idea.
|
||||
*/
|
||||
|
|
@ -1087,22 +1091,22 @@ init_error_limit(j_decompress_ptr cinfo)
|
|||
int in, out;
|
||||
|
||||
table = (int *)(*cinfo->mem->alloc_small)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE, (MAXJSAMPLE * 2 + 1) * sizeof(int));
|
||||
table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE, (_MAXJSAMPLE * 2 + 1) * sizeof(int));
|
||||
table += _MAXJSAMPLE; /* so can index -_MAXJSAMPLE .. +_MAXJSAMPLE */
|
||||
cquantize->error_limiter = table;
|
||||
|
||||
#define STEPSIZE ((MAXJSAMPLE + 1) / 16)
|
||||
/* Map errors 1:1 up to +- MAXJSAMPLE/16 */
|
||||
#define STEPSIZE ((_MAXJSAMPLE + 1) / 16)
|
||||
/* Map errors 1:1 up to +- _MAXJSAMPLE/16 */
|
||||
out = 0;
|
||||
for (in = 0; in < STEPSIZE; in++, out++) {
|
||||
table[in] = out; table[-in] = -out;
|
||||
}
|
||||
/* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */
|
||||
/* Map errors 1:2 up to +- 3*_MAXJSAMPLE/16 */
|
||||
for (; in < STEPSIZE * 3; in++, out += (in & 1) ? 0 : 1) {
|
||||
table[in] = out; table[-in] = -out;
|
||||
}
|
||||
/* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */
|
||||
for (; in <= MAXJSAMPLE; in++) {
|
||||
/* Clamp the rest to final out value (which is (_MAXJSAMPLE+1)/8) */
|
||||
for (; in <= _MAXJSAMPLE; in++) {
|
||||
table[in] = out; table[-in] = -out;
|
||||
}
|
||||
#undef STEPSIZE
|
||||
|
|
@ -1119,7 +1123,7 @@ finish_pass1(j_decompress_ptr cinfo)
|
|||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
|
||||
/* Select the representative colors and fill in cinfo->colormap */
|
||||
cinfo->colormap = cquantize->sv_colormap;
|
||||
cinfo->colormap = (JSAMPARRAY)cquantize->sv_colormap;
|
||||
select_colors(cinfo, cquantize->desired);
|
||||
/* Force next pass to zero the color index table */
|
||||
cquantize->needs_zeroed = TRUE;
|
||||
|
|
@ -1151,15 +1155,15 @@ start_pass_2_quant(j_decompress_ptr cinfo, boolean is_pre_scan)
|
|||
|
||||
if (is_pre_scan) {
|
||||
/* Set up method pointers */
|
||||
cquantize->pub.color_quantize = prescan_quantize;
|
||||
cquantize->pub._color_quantize = prescan_quantize;
|
||||
cquantize->pub.finish_pass = finish_pass1;
|
||||
cquantize->needs_zeroed = TRUE; /* Always zero histogram */
|
||||
} else {
|
||||
/* Set up method pointers */
|
||||
if (cinfo->dither_mode == JDITHER_FS)
|
||||
cquantize->pub.color_quantize = pass2_fs_dither;
|
||||
cquantize->pub._color_quantize = pass2_fs_dither;
|
||||
else
|
||||
cquantize->pub.color_quantize = pass2_no_dither;
|
||||
cquantize->pub._color_quantize = pass2_no_dither;
|
||||
cquantize->pub.finish_pass = finish_pass2;
|
||||
|
||||
/* Make sure color count is acceptable */
|
||||
|
|
@ -1215,11 +1219,14 @@ new_color_map_2_quant(j_decompress_ptr cinfo)
|
|||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_2pass_quantizer(j_decompress_ptr cinfo)
|
||||
_jinit_2pass_quantizer(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_cquantize_ptr cquantize;
|
||||
int i;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
cquantize = (my_cquantize_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_cquantizer));
|
||||
|
|
@ -1230,7 +1237,8 @@ jinit_2pass_quantizer(j_decompress_ptr cinfo)
|
|||
cquantize->error_limiter = NULL;
|
||||
|
||||
/* Make sure jdmaster didn't give me a case I can't handle */
|
||||
if (cinfo->out_color_components != 3)
|
||||
if (cinfo->out_color_components != 3 ||
|
||||
cinfo->out_color_space == JCS_RGB565 || cinfo->master->lossless)
|
||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
||||
|
||||
/* Allocate the histogram/inverse colormap storage */
|
||||
|
|
@ -1253,10 +1261,10 @@ jinit_2pass_quantizer(j_decompress_ptr cinfo)
|
|||
/* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
|
||||
if (desired < 8)
|
||||
ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8);
|
||||
/* Make sure colormap indexes can be represented by JSAMPLEs */
|
||||
/* Make sure colormap indexes can be represented by _JSAMPLEs */
|
||||
if (desired > MAXNUMCOLORS)
|
||||
ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
|
||||
cquantize->sv_colormap = (*cinfo->mem->alloc_sarray)
|
||||
cquantize->sv_colormap = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)desired, (JDIMENSION)3);
|
||||
cquantize->desired = desired;
|
||||
} else
|
||||
|
|
@ -1282,4 +1290,4 @@ jinit_2pass_quantizer(j_decompress_ptr cinfo)
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* QUANT_2PASS_SUPPORTED */
|
||||
#endif /* defined(QUANT_2PASS_SUPPORTED) && BITS_IN_JSAMPLE != 16 */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,336 @@
|
|||
/*
|
||||
* jsamplecomp.h
|
||||
*
|
||||
* Copyright (C) 2022, D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
*/
|
||||
|
||||
/* In source files that must be compiled for multiple data precisions, we
|
||||
* prefix all precision-dependent data types, macros, methods, fields, and
|
||||
* function names with an underscore. Including this file replaces those
|
||||
* precision-independent tokens with their precision-dependent equivalents,
|
||||
* based on the value of BITS_IN_JSAMPLE.
|
||||
*/
|
||||
|
||||
#ifndef JSAMPLECOMP_H
|
||||
#define JSAMPLECOMP_H
|
||||
|
||||
#if BITS_IN_JSAMPLE == 16
|
||||
|
||||
/* Sample data types and macros (jmorecfg.h) */
|
||||
#define _JSAMPLE J16SAMPLE
|
||||
|
||||
#define _MAXJSAMPLE MAXJ16SAMPLE
|
||||
#define _CENTERJSAMPLE CENTERJ16SAMPLE
|
||||
|
||||
#define _JSAMPROW J16SAMPROW
|
||||
#define _JSAMPARRAY J16SAMPARRAY
|
||||
#define _JSAMPIMAGE J16SAMPIMAGE
|
||||
|
||||
/* External functions (jpeglib.h) */
|
||||
#define _jpeg_write_scanlines jpeg16_write_scanlines
|
||||
#define _jpeg_read_scanlines jpeg16_read_scanlines
|
||||
|
||||
/* Internal methods (jpegint.h) */
|
||||
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
/* Use the 16-bit method in the jpeg_c_main_controller structure. */
|
||||
#define _process_data process_data_16
|
||||
/* Use the 16-bit method in the jpeg_c_prep_controller structure. */
|
||||
#define _pre_process_data pre_process_data_16
|
||||
/* Use the 16-bit method in the jpeg_c_coef_controller structure. */
|
||||
#define _compress_data compress_data_16
|
||||
/* Use the 16-bit method in the jpeg_color_converter structure. */
|
||||
#define _color_convert color_convert_16
|
||||
/* Use the 16-bit method in the jpeg_downsampler structure. */
|
||||
#define _downsample downsample_16
|
||||
#endif
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
/* Use the 16-bit method in the jpeg_d_main_controller structure. */
|
||||
#define _process_data process_data_16
|
||||
/* Use the 16-bit method in the jpeg_d_coef_controller structure. */
|
||||
#define _decompress_data decompress_data_16
|
||||
/* Use the 16-bit method in the jpeg_d_post_controller structure. */
|
||||
#define _post_process_data post_process_data_16
|
||||
/* Use the 16-bit method in the jpeg_upsampler structure. */
|
||||
#define _upsample upsample_16
|
||||
/* Use the 16-bit method in the jpeg_color_converter structure. */
|
||||
#define _color_convert color_convert_16
|
||||
#endif
|
||||
|
||||
/* Global internal functions (jpegint.h) */
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
#define _jinit_c_main_controller j16init_c_main_controller
|
||||
#define _jinit_c_prep_controller j16init_c_prep_controller
|
||||
#define _jinit_color_converter j16init_color_converter
|
||||
#define _jinit_downsampler j16init_downsampler
|
||||
#define _jinit_c_diff_controller j16init_c_diff_controller
|
||||
#define _jinit_lossless_compressor j16init_lossless_compressor
|
||||
#endif
|
||||
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
#define _jinit_d_main_controller j16init_d_main_controller
|
||||
#define _jinit_d_post_controller j16init_d_post_controller
|
||||
#define _jinit_upsampler j16init_upsampler
|
||||
#define _jinit_color_deconverter j16init_color_deconverter
|
||||
#define _jinit_merged_upsampler j16init_merged_upsampler
|
||||
#define _jinit_d_diff_controller j16init_d_diff_controller
|
||||
#define _jinit_lossless_decompressor j16init_lossless_decompressor
|
||||
#endif
|
||||
|
||||
#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
|
||||
#define _jcopy_sample_rows j16copy_sample_rows
|
||||
#endif
|
||||
|
||||
/* Internal fields (cdjpeg.h) */
|
||||
|
||||
#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
|
||||
/* Use the 16-bit buffer in the cjpeg_source_struct and djpeg_dest_struct
|
||||
structures. */
|
||||
#define _buffer buffer16
|
||||
#endif
|
||||
|
||||
/* Image I/O functions (cdjpeg.h) */
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
#define _jinit_read_gif j16init_read_gif
|
||||
#define _jinit_read_ppm j16init_read_ppm
|
||||
#endif
|
||||
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
#define _jinit_write_ppm j16init_write_ppm
|
||||
#endif
|
||||
|
||||
#elif BITS_IN_JSAMPLE == 12
|
||||
|
||||
/* Sample data types and macros (jmorecfg.h) */
|
||||
#define _JSAMPLE J12SAMPLE
|
||||
|
||||
#define _MAXJSAMPLE MAXJ12SAMPLE
|
||||
#define _CENTERJSAMPLE CENTERJ12SAMPLE
|
||||
|
||||
#define _JSAMPROW J12SAMPROW
|
||||
#define _JSAMPARRAY J12SAMPARRAY
|
||||
#define _JSAMPIMAGE J12SAMPIMAGE
|
||||
|
||||
/* External functions (jpeglib.h) */
|
||||
#define _jpeg_write_scanlines jpeg12_write_scanlines
|
||||
#define _jpeg_write_raw_data jpeg12_write_raw_data
|
||||
#define _jpeg_read_scanlines jpeg12_read_scanlines
|
||||
#define _jpeg_skip_scanlines jpeg12_skip_scanlines
|
||||
#define _jpeg_crop_scanline jpeg12_crop_scanline
|
||||
#define _jpeg_read_raw_data jpeg12_read_raw_data
|
||||
|
||||
/* Internal methods (jpegint.h) */
|
||||
|
||||
/* Use the 12-bit method in the jpeg_c_main_controller structure. */
|
||||
#define _process_data process_data_12
|
||||
/* Use the 12-bit method in the jpeg_c_prep_controller structure. */
|
||||
#define _pre_process_data pre_process_data_12
|
||||
/* Use the 12-bit method in the jpeg_c_coef_controller structure. */
|
||||
#define _compress_data compress_data_12
|
||||
/* Use the 12-bit method in the jpeg_color_converter structure. */
|
||||
#define _color_convert color_convert_12
|
||||
/* Use the 12-bit method in the jpeg_downsampler structure. */
|
||||
#define _downsample downsample_12
|
||||
/* Use the 12-bit method in the jpeg_forward_dct structure. */
|
||||
#define _forward_DCT forward_DCT_12
|
||||
/* Use the 12-bit method in the jpeg_d_main_controller structure. */
|
||||
#define _process_data process_data_12
|
||||
/* Use the 12-bit method in the jpeg_d_coef_controller structure. */
|
||||
#define _decompress_data decompress_data_12
|
||||
/* Use the 12-bit method in the jpeg_d_post_controller structure. */
|
||||
#define _post_process_data post_process_data_12
|
||||
/* Use the 12-bit method in the jpeg_inverse_dct structure. */
|
||||
#define _inverse_DCT_method_ptr inverse_DCT_12_method_ptr
|
||||
#define _inverse_DCT inverse_DCT_12
|
||||
/* Use the 12-bit method in the jpeg_upsampler structure. */
|
||||
#define _upsample upsample_12
|
||||
/* Use the 12-bit method in the jpeg_color_converter structure. */
|
||||
#define _color_convert color_convert_12
|
||||
/* Use the 12-bit method in the jpeg_color_quantizer structure. */
|
||||
#define _color_quantize color_quantize_12
|
||||
|
||||
/* Global internal functions (jpegint.h) */
|
||||
#define _jinit_c_main_controller j12init_c_main_controller
|
||||
#define _jinit_c_prep_controller j12init_c_prep_controller
|
||||
#define _jinit_c_coef_controller j12init_c_coef_controller
|
||||
#define _jinit_color_converter j12init_color_converter
|
||||
#define _jinit_downsampler j12init_downsampler
|
||||
#define _jinit_forward_dct j12init_forward_dct
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
#define _jinit_c_diff_controller j12init_c_diff_controller
|
||||
#define _jinit_lossless_compressor j12init_lossless_compressor
|
||||
#endif
|
||||
|
||||
#define _jinit_d_main_controller j12init_d_main_controller
|
||||
#define _jinit_d_coef_controller j12init_d_coef_controller
|
||||
#define _jinit_d_post_controller j12init_d_post_controller
|
||||
#define _jinit_inverse_dct j12init_inverse_dct
|
||||
#define _jinit_upsampler j12init_upsampler
|
||||
#define _jinit_color_deconverter j12init_color_deconverter
|
||||
#define _jinit_1pass_quantizer j12init_1pass_quantizer
|
||||
#define _jinit_2pass_quantizer j12init_2pass_quantizer
|
||||
#define _jinit_merged_upsampler j12init_merged_upsampler
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
#define _jinit_d_diff_controller j12init_d_diff_controller
|
||||
#define _jinit_lossless_decompressor j12init_lossless_decompressor
|
||||
#endif
|
||||
|
||||
#define _jcopy_sample_rows j12copy_sample_rows
|
||||
|
||||
/* Global internal functions (jdct.h) */
|
||||
#define _jpeg_fdct_islow jpeg12_fdct_islow
|
||||
#define _jpeg_fdct_ifast jpeg12_fdct_ifast
|
||||
|
||||
#define _jpeg_idct_islow jpeg12_idct_islow
|
||||
#define _jpeg_idct_ifast jpeg12_idct_ifast
|
||||
#define _jpeg_idct_float jpeg12_idct_float
|
||||
#define _jpeg_idct_7x7 jpeg12_idct_7x7
|
||||
#define _jpeg_idct_6x6 jpeg12_idct_6x6
|
||||
#define _jpeg_idct_5x5 jpeg12_idct_5x5
|
||||
#define _jpeg_idct_4x4 jpeg12_idct_4x4
|
||||
#define _jpeg_idct_3x3 jpeg12_idct_3x3
|
||||
#define _jpeg_idct_2x2 jpeg12_idct_2x2
|
||||
#define _jpeg_idct_1x1 jpeg12_idct_1x1
|
||||
#define _jpeg_idct_9x9 jpeg12_idct_9x9
|
||||
#define _jpeg_idct_10x10 jpeg12_idct_10x10
|
||||
#define _jpeg_idct_11x11 jpeg12_idct_11x11
|
||||
#define _jpeg_idct_12x12 jpeg12_idct_12x12
|
||||
#define _jpeg_idct_13x13 jpeg12_idct_13x13
|
||||
#define _jpeg_idct_14x14 jpeg12_idct_14x14
|
||||
#define _jpeg_idct_15x15 jpeg12_idct_15x15
|
||||
#define _jpeg_idct_16x16 jpeg12_idct_16x16
|
||||
|
||||
/* Internal fields (cdjpeg.h) */
|
||||
|
||||
/* Use the 12-bit buffer in the cjpeg_source_struct and djpeg_dest_struct
|
||||
structures. */
|
||||
#define _buffer buffer12
|
||||
|
||||
/* Image I/O functions (cdjpeg.h) */
|
||||
#define _jinit_read_gif j12init_read_gif
|
||||
#define _jinit_write_gif j12init_write_gif
|
||||
#define _jinit_read_ppm j12init_read_ppm
|
||||
#define _jinit_write_ppm j12init_write_ppm
|
||||
|
||||
#define _read_color_map read_color_map_12
|
||||
|
||||
#else /* BITS_IN_JSAMPLE */
|
||||
|
||||
/* Sample data types and macros (jmorecfg.h) */
|
||||
#define _JSAMPLE JSAMPLE
|
||||
|
||||
#define _MAXJSAMPLE MAXJSAMPLE
|
||||
#define _CENTERJSAMPLE CENTERJSAMPLE
|
||||
|
||||
#define _JSAMPROW JSAMPROW
|
||||
#define _JSAMPARRAY JSAMPARRAY
|
||||
#define _JSAMPIMAGE JSAMPIMAGE
|
||||
|
||||
/* External functions (jpeglib.h) */
|
||||
#define _jpeg_write_scanlines jpeg_write_scanlines
|
||||
#define _jpeg_write_raw_data jpeg_write_raw_data
|
||||
#define _jpeg_read_scanlines jpeg_read_scanlines
|
||||
#define _jpeg_skip_scanlines jpeg_skip_scanlines
|
||||
#define _jpeg_crop_scanline jpeg_crop_scanline
|
||||
#define _jpeg_read_raw_data jpeg_read_raw_data
|
||||
|
||||
/* Internal methods (jpegint.h) */
|
||||
|
||||
/* Use the 8-bit method in the jpeg_c_main_controller structure. */
|
||||
#define _process_data process_data
|
||||
/* Use the 8-bit method in the jpeg_c_prep_controller structure. */
|
||||
#define _pre_process_data pre_process_data
|
||||
/* Use the 8-bit method in the jpeg_c_coef_controller structure. */
|
||||
#define _compress_data compress_data
|
||||
/* Use the 8-bit method in the jpeg_color_converter structure. */
|
||||
#define _color_convert color_convert
|
||||
/* Use the 8-bit method in the jpeg_downsampler structure. */
|
||||
#define _downsample downsample
|
||||
/* Use the 8-bit method in the jpeg_forward_dct structure. */
|
||||
#define _forward_DCT forward_DCT
|
||||
/* Use the 8-bit method in the jpeg_d_main_controller structure. */
|
||||
#define _process_data process_data
|
||||
/* Use the 8-bit method in the jpeg_d_coef_controller structure. */
|
||||
#define _decompress_data decompress_data
|
||||
/* Use the 8-bit method in the jpeg_d_post_controller structure. */
|
||||
#define _post_process_data post_process_data
|
||||
/* Use the 8-bit method in the jpeg_inverse_dct structure. */
|
||||
#define _inverse_DCT_method_ptr inverse_DCT_method_ptr
|
||||
#define _inverse_DCT inverse_DCT
|
||||
/* Use the 8-bit method in the jpeg_upsampler structure. */
|
||||
#define _upsample upsample
|
||||
/* Use the 8-bit method in the jpeg_color_converter structure. */
|
||||
#define _color_convert color_convert
|
||||
/* Use the 8-bit method in the jpeg_color_quantizer structure. */
|
||||
#define _color_quantize color_quantize
|
||||
|
||||
/* Global internal functions (jpegint.h) */
|
||||
#define _jinit_c_main_controller jinit_c_main_controller
|
||||
#define _jinit_c_prep_controller jinit_c_prep_controller
|
||||
#define _jinit_c_coef_controller jinit_c_coef_controller
|
||||
#define _jinit_color_converter jinit_color_converter
|
||||
#define _jinit_downsampler jinit_downsampler
|
||||
#define _jinit_forward_dct jinit_forward_dct
|
||||
#ifdef C_LOSSLESS_SUPPORTED
|
||||
#define _jinit_c_diff_controller jinit_c_diff_controller
|
||||
#define _jinit_lossless_compressor jinit_lossless_compressor
|
||||
#endif
|
||||
|
||||
#define _jinit_d_main_controller jinit_d_main_controller
|
||||
#define _jinit_d_coef_controller jinit_d_coef_controller
|
||||
#define _jinit_d_post_controller jinit_d_post_controller
|
||||
#define _jinit_inverse_dct jinit_inverse_dct
|
||||
#define _jinit_upsampler jinit_upsampler
|
||||
#define _jinit_color_deconverter jinit_color_deconverter
|
||||
#define _jinit_1pass_quantizer jinit_1pass_quantizer
|
||||
#define _jinit_2pass_quantizer jinit_2pass_quantizer
|
||||
#define _jinit_merged_upsampler jinit_merged_upsampler
|
||||
#ifdef D_LOSSLESS_SUPPORTED
|
||||
#define _jinit_d_diff_controller jinit_d_diff_controller
|
||||
#define _jinit_lossless_decompressor jinit_lossless_decompressor
|
||||
#endif
|
||||
|
||||
#define _jcopy_sample_rows jcopy_sample_rows
|
||||
|
||||
/* Global internal functions (jdct.h) */
|
||||
#define _jpeg_fdct_islow jpeg_fdct_islow
|
||||
#define _jpeg_fdct_ifast jpeg_fdct_ifast
|
||||
|
||||
#define _jpeg_idct_islow jpeg_idct_islow
|
||||
#define _jpeg_idct_ifast jpeg_idct_ifast
|
||||
#define _jpeg_idct_float jpeg_idct_float
|
||||
#define _jpeg_idct_7x7 jpeg_idct_7x7
|
||||
#define _jpeg_idct_6x6 jpeg_idct_6x6
|
||||
#define _jpeg_idct_5x5 jpeg_idct_5x5
|
||||
#define _jpeg_idct_4x4 jpeg_idct_4x4
|
||||
#define _jpeg_idct_3x3 jpeg_idct_3x3
|
||||
#define _jpeg_idct_2x2 jpeg_idct_2x2
|
||||
#define _jpeg_idct_1x1 jpeg_idct_1x1
|
||||
#define _jpeg_idct_9x9 jpeg_idct_9x9
|
||||
#define _jpeg_idct_10x10 jpeg_idct_10x10
|
||||
#define _jpeg_idct_11x11 jpeg_idct_11x11
|
||||
#define _jpeg_idct_12x12 jpeg_idct_12x12
|
||||
#define _jpeg_idct_13x13 jpeg_idct_13x13
|
||||
#define _jpeg_idct_14x14 jpeg_idct_14x14
|
||||
#define _jpeg_idct_15x15 jpeg_idct_15x15
|
||||
#define _jpeg_idct_16x16 jpeg_idct_16x16
|
||||
|
||||
/* Internal fields (cdjpeg.h) */
|
||||
|
||||
/* Use the 8-bit buffer in the cjpeg_source_struct and djpeg_dest_struct
|
||||
structures. */
|
||||
#define _buffer buffer
|
||||
|
||||
/* Image I/O functions (cdjpeg.h) */
|
||||
#define _jinit_read_gif jinit_read_gif
|
||||
#define _jinit_write_gif jinit_write_gif
|
||||
#define _jinit_read_ppm jinit_read_ppm
|
||||
#define _jinit_write_ppm jinit_write_ppm
|
||||
|
||||
#define _read_color_map read_color_map
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE */
|
||||
|
||||
#endif /* JSAMPLECOMP_H */
|
||||
|
|
@ -12,6 +12,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef WITH_SIMD
|
||||
|
||||
#include "jchuff.h" /* Declarations shared with jcphuff.c */
|
||||
|
||||
EXTERN(int) jsimd_can_rgb_ycc(void);
|
||||
|
|
@ -121,3 +123,5 @@ EXTERN(int) jsimd_can_encode_mcu_AC_refine_prepare(void);
|
|||
EXTERN(int) jsimd_encode_mcu_AC_refine_prepare
|
||||
(const JCOEF *block, const int *jpeg_natural_order_start, int Sl, int Al,
|
||||
UJCOEF *absvalues, size_t *bits);
|
||||
|
||||
#endif /* WITH_SIMD */
|
||||
|
|
|
|||
|
|
@ -1,431 +0,0 @@
|
|||
/*
|
||||
* jsimd_none.c
|
||||
*
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2009-2011, 2014, 2022, D. R. Commander.
|
||||
* Copyright (C) 2015-2016, 2018, 2022, Matthieu Darbois.
|
||||
* Copyright (C) 2020, Arm Limited.
|
||||
*
|
||||
* Based on the x86 SIMD extension for IJG JPEG library,
|
||||
* Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
* For conditions of distribution and use, see copyright notice in jsimdext.inc
|
||||
*
|
||||
* This file contains stubs for when there is no SIMD support available.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsimd.h"
|
||||
#include "jdct.h"
|
||||
#include "jsimddct.h"
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_rgb_ycc(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_rgb_gray(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_ycc_rgb(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_ycc_rgb565(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_c_can_null_convert(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION input_row, JSAMPARRAY output_buf,
|
||||
int num_rows)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_c_null_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPIMAGE output_buf, JDIMENSION output_row,
|
||||
int num_rows)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v2_downsample(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v1_downsample(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v2_smooth_downsample(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v2_smooth_downsample(j_compress_ptr cinfo,
|
||||
jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v2_upsample(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v1_upsample(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_int_upsample(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_int_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v2_fancy_upsample(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v1_fancy_upsample(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h1v2_fancy_upsample(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v2_merged_upsample(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_h2v1_merged_upsample(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
||||
JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_convsamp(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_convsamp_float(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
|
||||
DCTELEM *workspace)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
|
||||
FAST_FLOAT *workspace)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_fdct_islow(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_fdct_ifast(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_fdct_float(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_fdct_islow(DCTELEM *data)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_fdct_ifast(DCTELEM *data)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_fdct_float(FAST_FLOAT *data)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_quantize(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_quantize_float(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
|
||||
FAST_FLOAT *workspace)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_idct_2x2(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_idct_4x4(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_idct_6x6(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_idct_12x12(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_idct_6x6(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_idct_12x12(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_idct_islow(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_idct_ifast(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_idct_float(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JCOEFPTR coef_block, JSAMPARRAY output_buf,
|
||||
JDIMENSION output_col)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_huff_encode_one_block(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(JOCTET *)
|
||||
jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
|
||||
int last_dc_val, c_derived_tbl *dctbl,
|
||||
c_derived_tbl *actbl)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_encode_mcu_AC_first_prepare(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
|
||||
const int *jpeg_natural_order_start, int Sl,
|
||||
int Al, UJCOEF *values, size_t *zerobits)
|
||||
{
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_can_encode_mcu_AC_refine_prepare(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLOBAL(int)
|
||||
jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
|
||||
const int *jpeg_natural_order_start, int Sl,
|
||||
int Al, UJCOEF *absvalues, size_t *bits)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -17,8 +17,11 @@
|
|||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
|
||||
/*
|
||||
* 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).
|
||||
|
|
@ -89,19 +92,24 @@ jround_up(long a, long b)
|
|||
return a - (a % b);
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 8 */
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16 || \
|
||||
defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
|
||||
|
||||
GLOBAL(void)
|
||||
jcopy_sample_rows(JSAMPARRAY input_array, int source_row,
|
||||
JSAMPARRAY output_array, int dest_row, int num_rows,
|
||||
JDIMENSION num_cols)
|
||||
_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.
|
||||
*/
|
||||
{
|
||||
register JSAMPROW inptr, outptr;
|
||||
register size_t count = (size_t)(num_cols * sizeof(JSAMPLE));
|
||||
register _JSAMPROW inptr, outptr;
|
||||
register size_t count = (size_t)(num_cols * sizeof(_JSAMPLE));
|
||||
register int row;
|
||||
|
||||
input_array += source_row;
|
||||
|
|
@ -114,6 +122,11 @@ jcopy_sample_rows(JSAMPARRAY input_array, int source_row,
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE != 16 ||
|
||||
defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED) */
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
|
||||
GLOBAL(void)
|
||||
jcopy_block_row(JBLOCKROW input_row, JBLOCKROW output_row,
|
||||
|
|
@ -131,3 +144,5 @@ jzero_far(void *target, size_t bytestozero)
|
|||
{
|
||||
memset(target, 0, bytestozero);
|
||||
}
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 8 */
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
"Copyright (C) 2009, 2012 Pierre Ossman for Cendio AB\n" \
|
||||
"Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \
|
||||
"Copyright (C) 1999-2006 MIYASAKA Masaru\n" \
|
||||
"Copyright (C) 1999 Ken Murchison\n" \
|
||||
"Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding"
|
||||
|
||||
#define JCOPYRIGHT_SHORT \
|
||||
|
|
|
|||
Loading…
Reference in New Issue