70 Commits

Author SHA1 Message Date
DRC
4851cbe406 djpeg/jpeg_crop_scanline(): Disallow crop vals < 0
Because the crop spec was parsed using unsigned 32-bit integers,
negative numbers were interpreted as values ~= UINT_MAX (4,294,967,295).
This had the following ramifications:

- If the cropping region width was negative and the adjusted width + the
  adjusted left boundary was greater than 0, then the 32-bit unsigned
  integer bounds checks in djpeg and jpeg_crop_scanline() overflowed and
  failed to detect the out-of-bounds width, jpeg_crop_scanline() set
  cinfo->output_width to a value ~= UINT_MAX, and a buffer overrun and
  subsequent segfault occurred in the upsampling or color conversion
  routine.  The segfault occurred in the body of
  jpeg_skip_scanlines() --> read_and_discard_scanlines() if the cropping
  region upper boundary was greater than 0 and the JPEG image used
  chrominance subsampling and in the body of jpeg_read_scanlines()
  otherwise.

- If the cropping region width was negative and the adjusted width + the
  adjusted left boundary was 0, then a zero-width output image was
  generated.

- If the cropping region left boundary was negative, then an output
  image with bogus data was generated.

This commit modifies djpeg and jpeg_crop_scanline() so that the
aforementioned bounds checks use 64-bit unsigned integers, thus guarding
against overflow.  It similarly modifies jpeg_skip_scanlines().  In the
case of jpeg_skip_scanlines(), the issue was not reproducible with
djpeg, but passing a negative number of lines to jpeg_skip_scanlines()
caused a similar overflow if the number of lines +
cinfo->output_scanline was greater than 0.  That caused
jpeg_skip_scanlines() to read past the end of the JPEG image, throw a
warning ("Corrupt JPEG data: premature end of data segment"), and fail
to return unless warnings were treated as fatal.  Also, djpeg now parses
the crop spec using signed integers and checks for negative values.
2024-08-26 16:24:33 -04:00
DRC
a9723f8a98 cjpeg/djpeg/jpegtran: Restore jpeg-6b arg abbrevs
There are two approaches to handling abbreviated command-line options:

1. If a new option is introduced that begins with the same letters as an
existing option, require a longer abbreviation for the existing option
in order to ensure that abbreviations are always unique.

2. Require a unique abbreviation only for new options, and match all
non-unique abbreviations with existing options, thus maintaining
backward compatibility.

keymatch() supports either approach, and Tom Lane historically seemed to
prefer Approach 2, whereas both approaches have been applied
inconsistently in the years since.  This commit consistently applies
Approach 2.

More specific notes:

We unnecessarily required 'cjpeg -progressive' to be abbreviated as
'cjpeg -pro' rather than 'cjpeg -p' when the -precision option was
introduced in libjpeg-turbo 3.0 beta.

The IJG unnecessarily required 'cjpeg -scans' to be abbreviated as
'cjpeg -scan' rather than 'cjpeg -sc' when the -scale option was
introduced in jpeg-7.  We even more unnecessarily adopted that
requirement, even though we never adopted the -scale option.

We unnecessarily required 'djpeg -scale' to be abbreviated as
'djpeg -sc' rather than 'djpeg -s' when the -skip option was introduced
in libjpeg-turbo 1.5 beta.

The IJG unnecessarily required 'jpegtran -copy' to be abbreviated as
'jpegtran -co' rather than 'jpegtran -c' when the -crop option was
introduced in jpeg-7.

The IJG unnecessarily required 'jpegtran -progressive' to be abbreviated
as 'jpegtran -pr' rather than 'jpegtran -p' when the -perfect option was
introduced in jpeg-7.
2024-08-19 17:12:33 -04:00
DRC
94c64ead85 Various doc tweaks
- "bits per component" = "bits per sample"

  Describing the data precision of a JPEG image using "bits per
  component" is technically correct, but "bits per sample" is the
  terminology that the JPEG-1 spec uses.  Also, "bits per component" is
  more commonly used to describe the precision of packed-pixel formats
  (as opposed to "bits per pixel") rather than planar formats, in which
  all components are grouped together.

- Unmention legacy display technologies.  Colormapped and monochrome
  displays aren't a thing anymore, and even when they were still a
  thing, it was possible to display full-color images to them.  In 1991,
  when JPEG decompression time was measured in minutes per megapixel, it
  made sense to keep a decompressed copy of JPEG images on disk, in a
  format that could be displayed without further color conversion (since
  color conversion was slow and memory-intensive.)  In 2024, JPEG
  decompression time is measured in milliseconds per megapixel, and
  color conversion is even faster.  Thus, JPEG images can be
  decompressed, displayed, and color-converted (if necessary) "on the
  fly" at speeds too fast for human vision to perceive.  (In fact, your
  TV performs much more complicated decompression algorithms at least 60
  times per second.)

- Document that color quantization (and associated features), GIF
  input/output, Targa input/output, and OS/2 BMP input/output are legacy
  features.  Legacy status doesn't necessarily mean that the features
  are deprecated.  Rather, it is meant to discourage users from using
  features that may be of little or no benefit on modern machines (such
  as low-quality modes that had significant performance advantages in
  the early 1990s but no longer do) and that are maintained on a
  break/fix basis only.

- General wordsmithing, grammar/punctuation policing, and formatting
  tweaks

- Clarify which data precisions each cjpeg input format and each djpeg
  output format supports.

- cjpeg.1: Remove unnecessary and impolitic statement about the -targa
  switch.

- Adjust or remove performance claims to reflect the fact that:
  * On modern machines, the djpeg "-fast" switch has a negligible effect
    on performance.
  * There is a measurable difference between the performance of Floyd-
    Steinberg dithering and no dithering, but it is not likely
    perceptible to most users.
  * There is a measurable difference between the performance of 1-pass
    and 2-pass color quantization, but it is not likely perceptible to
    most users.
  * There is a measurable difference between the performance of
    full-color and grayscale output when decompressing a full-color JPEG
    image, but it is not likely perceptible to most users.
  * IDCT scaling does not necessarily improve performance.  (It
    generally does if the scaling factor is <= 1/2 and generally doesn't
    if the scaling factor is > 1/2, at least on my machine.  The
    performance claim made in jpeg-6b was probably invalidated when we
    merged the additional scaling factors from jpeg-7.)

- Clarify which djpeg switches/output formats cannot be used when
  decompressing lossless JPEG images.

- Remove djpeg hints, since those involve quality vs. speed tradeoffs
  that are no longer relevant for modern machines.

- Remove documentation regarding using color quantization with 16-bit
  data precision.  (Color quantization requires lossy mode.)

- Java: Fix typos in TJDecompressor.decompress12() and
  TJDecompressor.decompress16() documentation.

- jpegtran.1: Fix truncated paragraph

  In a man page, a single quote at the start of a line is interpreted as
  a macro.

  Closes #775

- libjpeg.txt:
  * Mention J16SAMPLE data type (oversight.)
  * Remove statement about extending jdcolor.c.  (libjpeg-turbo is not
    quite as DIY as libjpeg once was.)
  * Remove paragraph about tweaking the various typedefs in jmorecfg.h.
    It is no longer relevant for modern machines.
  * Remove caveat regarding systems with ints less than 16 bits wide.
    (ANSI/ISO C requires an int to be at least 16 bits wide, and
    libjpeg-turbo has never supported non-ANSI compilers.)

- usage.txt:
  * Add copyright header.
  * Document cjpeg -icc, -memdst, -report, -strict, and -version
    switches.
  * Document djpeg -icc, -maxscans, -memsrc, -report, -skip, -crop,
    -strict, and -version switches.
  * Document jpegtran -icc, -maxscans, -report, -strict, and -version
    switches.
2024-06-24 22:11:43 -04:00
DRC
dfde1f857d Fix (and test) more Clang 14 compiler warnings
-Woverlength-strings, -Wshift-negative-value, -Wsign-compare
2024-03-08 12:50:32 -05:00
DRC
34c055851e Fix warnings with -Wmissing-variable-declarations 2024-03-06 15:17:08 -05:00
DRC
7173889223 djpeg: Fix -map option with 12-bit data precision 2023-06-29 16:36:43 -04:00
DRC
bf9f319cb4 Disallow color quantization with lossless decomp
Color quantization is a legacy feature that serves little or no purpose
with lossless JPEG images.  9f756bc67a
eliminated interaction issues between the lossless decompressor and the
color quantizers related to out-of-range 12-bit samples, but referring
to #701, other interaction issues apparently still exist.  Such issues
are likely, given the fact that the color quantizers were not designed
with lossless decompression in mind.

This commit reverts 9f756bc67a, since the
issues it fixed are no longer relevant because of this commit and
2192560d74.

Fixed #672
Fixes #673
Fixes #674
Fixes #676
Fixes #677
Fixes #678
Fixes #679
Fixes #681
Fixes #683
Fixes #701
2023-06-29 16:36:29 -04:00
DRC
2241434eb9 16-bit lossless JPEG support 2022-12-16 13:57:03 -06:00
DRC
73ca9712e3 Merge branch 'main' into dev 2022-11-30 11:03:43 -06:00
DRC
403cfad611 djpeg.c: Fix build if !SAVE_MARKERS_SUPPORTED 2022-11-30 10:43:29 -06:00
DRC
b5a9ef64ea Don't allow 12-bit JPEG support to be disabled
In libjpeg-turbo 2.1.x and prior, the WITH_12BIT CMake variable was used
to enable 12-bit JPEG support at compile time, because the libjpeg API
library could not handle multiple JPEG data precisions at run time.  The
initial approach to handling multiple JPEG data precisions at run time
(7fec5074f9) created a whole new API,
library, and applications for 12-bit data precision, so it made sense to
repurpose WITH_12BIT to allow 12-bit data precision to be disabled.
e8b40f3c2b made it so that the libjpeg API
library can handle multiple JPEG data precisions at run time via a
handful of straightforward API extensions.  Referring to
6c2bc901e2, it hasn't been possible to
build libjpeg-turbo with both forward and backward libjpeg API/ABI
compatibility since libjpeg-turbo 1.4.x.  Thus, whereas we retain full
backward API/ABI compatibility with libjpeg v6b-v8, forward libjpeg
API/ABI compatibility ceased being realistic years ago, so it no longer
makes sense to provide compile-time options that give a false sense of
forward API/ABI compatibility by allowing some (but not all) of our
libjpeg API extensions to be disabled.  Such options are difficult to
maintain and clutter the code with #ifdefs.
2022-11-13 13:38:48 -06:00
DRC
e8b40f3c2b Vastly improve 12-bit JPEG integration
The Gordian knot that 7fec5074f9 attempted
to unravel was caused by the fact that there are several
data-precision-dependent (JSAMPLE-dependent) fields and methods in the
exposed libjpeg API structures, and if you change the exposed libjpeg
API structures, then you have to change the whole API.  If you change
the whole API, then you have to provide a whole new library to support
the new API, and that makes it difficult to support multiple data
precisions in the same application.  (It is not impossible, as example.c
demonstrated, but using data-precision-dependent libjpeg API structures
would have made the cjpeg, djpeg, and jpegtran source code hard to read,
so it made more sense to build, install, and package 12-bit-specific
versions of those applications.)

Unfortunately, the result of that initial integration effort was an
unreadable and unmaintainable mess, which is a problem for a library
that is an ISO/ITU-T reference implementation.  Also, as I dug into the
problem of lossless JPEG support, I realized that 16-bit lossless JPEG
images are a thing, and supporting yet another version of the libjpeg
API just for those images is untenable.

In fact, however, the touch points for JSAMPLE in the exposed libjpeg
API structures are minimal:

  - The colormap and sample_range_limit fields in jpeg_decompress_struct
  - The alloc_sarray() and access_virt_sarray() methods in
    jpeg_memory_mgr
  - jpeg_write_scanlines() and jpeg_write_raw_data()
  - jpeg_read_scanlines() and jpeg_read_raw_data()
  - jpeg_skip_scanlines() and jpeg_crop_scanline()
    (This is subtle, but both of those functions use JSAMPLE-dependent
    opaque structures behind the scenes.)

It is much more readable and maintainable to provide 12-bit-specific
versions of those six top-level API functions and to document that the
aforementioned methods and fields must be type-cast when using 12-bit
samples.  Since that eliminates the need to provide a 12-bit-specific
version of the exposed libjpeg API structures, we can:

  - Compile only the precision-dependent libjpeg modules (the
    coefficient buffer controllers, the colorspace converters, the
    DCT/IDCT managers, the main buffer controllers, the preprocessing
    and postprocessing controller, the downsampler and upsamplers, the
    quantizers, the integer DCT methods, and the IDCT methods) for
    multiple data precisions.
  - Introduce 12-bit-specific methods into the various internal
    structures defined in jpegint.h.
  - Create precision-independent data type, macro, method, field, and
    function names that are prefixed by an underscore, and use an
    internal header to convert those into precision-dependent data
    type, macro, method, field, and function names, based on the value
    of BITS_IN_JSAMPLE, when compiling the precision-dependent libjpeg
    modules.
  - Expose precision-dependent jinit*() functions for each of the
    precision-dependent libjpeg modules.
  - Abstract the precision-dependent libjpeg modules by calling the
    appropriate precision-dependent jinit*() function, based on the
    value of cinfo->data_precision, from top-level libjpeg API
    functions.
2022-11-04 12:30:33 -05:00
DRC
6c2bc901e2 Don't allow disabling in-memory src/dest managers
By default, libjpeg-turbo 1.3.x and later have enabled the in-memory
source/destination manager functions from libjpeg v8 when emulating the
libjpeg v6b or v7 API/ABI, which has allowed operating system
distributors to provide those functions without adopting the
backward-incompatible libjpeg v8 API/ABI.

Prior to libjpeg-turbo 1.5.x, it made sense to allow users to disable
the in-memory source/destination manager functions at build time and
thus retain both backward and forward API/ABI compatibility relative to
libjpeg v6b or v7.  Since then, however, we have introduced several new
libjpeg API functions that break forward API/ABI compatibility, so it no
longer makes sense to allow the in-memory source/destination managers to
be disabled.  libjpeg-turbo only claims to be
backward-API/ABI-compatible, i.e. to allow applications built against
libjpeg or an older version of libjpeg-turbo to work properly with the
current version of libjpeg-turbo.
2022-11-03 15:22:19 -05:00
DRC
fdab4a7af4 Progs: Eliminate obsolete Mac ccommand() interface
ccommand() was a 1990s-vintage hack for running console applications
without a console.  It doesn't exist in any modern macOS compiler.
2022-03-08 17:31:11 -06:00
DRC
607b668ff9 MSVC: Eliminate C4996 warnings in API libs
The primary purpose of this is to encourage adoption of libjpeg-turbo in
downstream Windows projects that forbid the use of "deprecated"
functions.  libjpeg-turbo's usage of those functions was not actually
unsafe, because:

- libjpeg-turbo always checks the return value of fopen() and ensures
  that a NULL filename can never be passed to it.

- libjpeg-turbo always checks the return value of getenv() and never
  passes a NULL argument to it.

- The sprintf() calls in format_message() (jerror.c) could never
  overflow the destination string buffer or leave it unterminated as
  long as the buffer was at least JMSG_LENGTH_MAX bytes in length, as
  instructed. (Regardless, this commit replaces those calls with
  snprintf() calls.)

- libjpeg-turbo never uses sscanf() to read strings or multi-byte
  character arrays.

- Because of b7d6e84d6a, wrjpgcom
  explicitly checks the bounds of the source and destination strings
  before calling strcat() and strcpy().

- libjpeg-turbo always ensures that the destination string is
  terminated when using strncpy().
  (548490fe5e made this explicit.)

Regarding thread safety:

Technically speaking, getenv() is not thread-safe, because the returned
pointer may be invalidated if another thread sets the same environment
variable between the time that the first thread calls getenv() and the
time that that thread uses the return value.  In practice, however, this
could only occur with libjpeg-turbo if:

(1) A multithreaded calling application used the deprecated and
undocumented TJFLAG_FORCEMMX/TJFLAG_FORCESSE/TJFLAG_FORCESSE2 flags in
the TurboJPEG API or set one of the corresponding environment variables
(which are only intended for testing purposes.)  Since the TurboJPEG API
library only ever passed string constants to putenv(), the only inherent
risk (i.e. the only risk introduced by the library and not the calling
application) was that the SIMD extensions may have read an incorrect
value from one of the aforementioned environment variables.

or

(2) A multithreaded calling application modified the value of the
JPEGMEM environment variable in one thread while another thread was
reading the value of that environment variable (in the body of
jpeg_create_compress() or jpeg_create_decompress().)  Given that the
libjpeg API provides a thread-safe way for applications to modify the
default memory limit without using the JPEGMEM environment variable,
direct modification of that environment variable by calling applications
is not supported.

Microsoft's implementation of getenv_s() does not claim to be
thread-safe either, so this commit uses getenv_s() solely to mollify
Visual Studio.  New inline functions and macros (GETENV_S() and
PUTENV_S) wrap getenv_s()/_putenv_s() when building for Visual Studio
and getenv()/setenv() otherwise, but GETENV_S()/PUTENV_S() provide no
advantages over getenv()/setenv() other than parameter validation.  They
are implemented solely for convenience.

Technically speaking, strerror() is not thread-safe, because the
returned pointer may be invalidated if another thread changes the locale
and/or calls strerror() between the time that the first thread calls
strerror() and the time that that thread uses the return value.  In
practice, however, this could only occur with libjpeg-turbo if a
multithreaded calling application encountered a file I/O error in
tjLoadImage() or tjSaveImage().  Since both of those functions
immediately copy the string returned from strerror() into a thread-local
buffer, the risk is minimal, and the worst case would involve an
incorrect error string being reported to the calling application.
Regardless, this commit uses strerror_s() in the TurboJPEG API library
when building for Visual Studio.  Note that strerror_r() could have been
used on Un*x systems, but it would have been necessary to handle both
the POSIX and GNU implementations of that function and perform
widespread compatibility testing.  Such is left as an exercise for
another day.

Fixes #568
2022-02-23 15:57:01 -06:00
DRC
b579fc114d Eliminate unnecessary JFREAD()/JFWRITE() macros 2022-02-09 16:07:18 -06:00
DRC
1f55ae7b0f Fix -Wpedantic compiler warnings
... and test for those warnings (and others) when performing CI builds.
2022-01-06 12:33:22 -06:00
DRC
172972394a Eliminate non-ANSI C compatibility macros
libjpeg-turbo has never supported non-ANSI C compilers.  Per the spec,
ANSI C compilers must have locale.h, stddef.h, stdlib.h, memset(),
memcpy(), unsigned char, and unsigned short.  They must also handle
undefined structures.
2022-01-06 11:50:26 -06:00
DRC
7c1a1789d2 Merge branch 'master' into dev 2020-11-05 16:04:55 -06:00
DRC
6e632af9f6 Demote "fast" [I]DCT algorithms to legacy status
- Refer to the "slow" [I]DCT algorithms as "accurate" instead, since
  they are not slow under libjpeg-turbo.
- Adjust documentation claims to reflect the fact that the "slow" and
  "fast" algorithms produce about the same performance on AVX2-equipped
  CPUs (because of the dual-lane nature of AVX2, it was not possible to
  accelerate the "fast" algorithm beyond what was achievable with SSE2.)
  Also adjust the claims to reflect the fact that the "fast" algorithm
  tends to be ~5-15% faster than the "slow" algorithm on
  non-AVX2-equipped CPUs, regardless of the use of the libjpeg-turbo
  SIMD extensions.
- Indicate the legacy status of the "fast" and float algorithms in the
  documentation and cjpeg/djpeg usage info.
- Remove obsolete paragraph in the djpeg man page that suggested that
  the float algorithm could be faster than the "fast" algorithm on some
  CPUs.
2020-11-05 15:59:31 -06:00
DRC
88ae60986e Merge branch 'ijg' into dev
- Restore GIF read/compressed GIF write support from jpeg-6a and
  jpeg-9d.
- Integrate jpegtran -wipe and -drop options from jpeg-9a and jpeg-9d.
- Integrate jpegtran -crop extension (for expanding the image size) from
  jpeg-9a and jpeg-9d.
- Integrate other minor code tweaks from jpeg-9*
2020-10-27 13:32:13 -05:00
Guido Vollbeding
9fc018fd1a The Independent JPEG Group's JPEG software v9d 2020-10-23 10:00:48 -05:00
DRC
fe79f56b77 Merge branch 'master' into dev 2020-07-28 15:09:00 -05:00
DRC
c1037f4380 Fix bad return val when skipping past end of image
Fixes #439
2020-07-28 14:59:41 -05:00
DRC
167b5a8059 Merge branch 'master' into dev 2020-01-08 15:02:58 -06:00
DRC
f81833aed6 Remove more unnecessary NULL checks before free() 2020-01-08 15:01:38 -06:00
DRC
c4675d62e8 Merge branch 'master' into dev 2019-12-31 00:58:42 -06:00
DRC
fe50cd9978 djpeg.c: Fix compiler warning w/o mem. src manager
insize is only used when the in-memory source manager is compiled in.
2019-12-31 00:05:05 -06:00
DRC
80acd5c4a7 Remove code for the obsolete RLE image format
libjpeg-turbo never included that code, because it requires an external
library (the Utah Raster Toolkit.)  The RLE image format was supplanted
by GIF in the late 1980s, so it is rarely seen these days.  (It had a
lousy Weissman score, anyhow.)
2019-12-19 10:36:26 -06:00
DRC
e98b061282 Add fault tolerance features to djpeg and jpegtran
- Enable progress reporting at run time using a new -report argument
  (cjpeg now supports that argument as well)
- Limit the allowable number of scans using a new -maxscans argument
- Treat warnings as fatal using a new -strict argument

This mainly demonstrates how to work around the two issues with the
JPEG standard described here:
https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf
since those and similar issues continue to be erroneously reported as
libjpeg-turbo bugs.
2019-12-18 15:35:56 -06:00
DRC
52fef34928 Eliminate internal use of GETJOCTET() macro
Because of 01e3032354 (officially
eliminating support for compilers without unsigned char, since we never
effectively supported those compilers anyhow), GETJOCTET() is now a
no-op.  Since that macro is in jmorecfg.h, it is part of the de facto
libjpeg API and must remain in the public headers.  However, there is no
reason to continue using it internally, and eliminating its internal use
improves code readability.
2019-12-10 19:10:55 -06:00
DRC
19c791cdac Improve code formatting consistency
With rare exceptions ...
- Always separate line continuation characters by one space from
  preceding code.
- Always use two-space indentation.  Never use tabs.
- Always use K&R-style conditional blocks.
- Always surround operators with spaces, except in raw assembly code.
- Always put a space after, but not before, a comma.
- Never put a space between type casts and variables/function calls.
- Never put a space between the function name and the argument list in
  function declarations and prototypes.
- Always surround braces ('{' and '}') with spaces.
- Always surround statements (if, for, else, catch, while, do, switch)
  with spaces.
- Always attach pointer symbols ('*' and '**') to the variable or
  function name.
- Always precede pointer symbols ('*' and '**') by a space in type
  casts.
- Use the MIN() macro from jpegint.h within the libjpeg and TurboJPEG
  API libraries (using min() from tjutil.h is still necessary for
  TJBench.)
- Where it makes sense (particularly in the TurboJPEG code), put a blank
  line after variable declaration blocks.
- Always separate statements in one-liners by two spaces.

The purpose of this was to ease maintenance on my part and also to make
it easier for contributors to figure out how to format patch
submissions.  This was admittedly confusing (even to me sometimes) when
we had 3 or 4 different style conventions in the same source tree.  The
new convention is more consistent with the formatting of other OSS code
bases.

This commit corrects deviations from the chosen formatting style in the
libjpeg API code and reformats the TurboJPEG API code such that it
conforms to the same standard.

NOTES:
- Although it is no longer necessary for the function name in function
  declarations to begin in Column 1 (this was historically necessary
  because of the ansi2knr utility, which allowed libjpeg to be built
  with non-ANSI compilers), we retain that formatting for the libjpeg
  code because it improves readability when using libjpeg's function
  attribute macros (GLOBAL(), etc.)
- This reformatting project was accomplished with the help of AStyle and
  Uncrustify, although neither was completely up to the task, and thus
  a great deal of manual tweaking was required.  Note to developers of
  code formatting utilities:  the libjpeg-turbo code base is an
  excellent test bed, because AFAICT, it breaks every single one of the
  utilities that are currently available.
- The legacy (MMX, SSE, 3DNow!) assembly code for i386 has been
  formatted to match the SSE2 code (refer to
  ff5685d5344273df321eb63a005eaae19d2496e3.)  I hadn't intended to
  bother with this, but the Loongson MMI implementation demonstrated
  that there is still academic value to the MMX implementation, as an
  algorithmic model for other 64-bit vector implementations.  Thus, it
  is desirable to improve its readability in the same manner as that of
  the SSE2 implementation.
2018-03-16 02:14:34 -05:00
DRC
aa7459050d TurboJPEG C API: Add BMP/PPM load/save functions
The main justification for this is to provide new libjpeg-turbo users
with a quick & easy way of developing a complete JPEG
compression/decompression program without requiring them to build
libjpeg-turbo from source (which was necessary in order to use the
project-private bmp API) or to use external libraries.  These new
functions build upon significant enhancements to rdbmp.c, wrbmp.c,
rdppm.c, and wrppm.c which allow those engines to convert directly
between the native pixel format of the file and a pixel format
("colorspace" in libjpeg parlance) specified by the calling program.
rdbmp.c and wrbmp.c have also been modified such that the calling
program can choose to read or write image rows in the native (bottom-up)
order of the file format, thus eliminating the need to use an inversion
array.  tjLoadImage() and tjSaveImage() leverage these new underlying
features in order to significantly improve upon the performance of the
old bmp API.

Because these new functions cannot work without the libjpeg-turbo
colorspace extensions, the libjpeg-compatible code in turbojpeg.c has
been removed.  That code was only there to serve as an example of how
to use the TurboJPEG API on top of libjpeg, but more specific, buildable
examples now exist in the https://github.com/libjpeg-turbo/ijg
repository.
2017-11-17 19:32:52 -06:00
DRC
4893e5d8b8 Merge branch 'master' into dev 2017-11-17 19:00:53 -06:00
DRC
5bc43c7821 Further partial image decompression fixes
- Referring to 073b0e88a1 and #185, the
  reason why BMP and RLE didn't (and won't) work with partial image
  decompression is that the output engines for both formats maintain a
  whole-image buffer, which is used to reverse the order of scanlines.
  However, it was straightforward to add -crop support for GIF and
  Targa, which is useful for testing partial image decompression along
  with color quantization.
- Such testing reproduced a bug reported by Mozilla (refer to PR #182)
  whereby jpeg_skip_scanlines() would segfault if color quantization was
  enabled.  To fix this issue, read_and_discard_scanlines() now sets up
  a dummy quantize function in the same manner that it sets up a dummy
  color conversion function.

Closes #182
2017-11-13 21:01:53 -06:00
DRC
073b0e88a1 djpeg -crop: Exit gracefully with non-PPM formats
... and document that only PPM/PGM output images are supported with the
-crop option for the moment.

I investigated the possibility of supporting -crop with -bmp, but even
after resetting the buffer dimensions, I still kept getting virtual
array access errors.  It seems that doing this the "right way" would
require creating a re-initialization function for each image format's
destination manager.  I'm disinclined to do that right now, given that
this feature was Google's baby (developed as a prerequisite for
including libjpeg-turbo in Android), and the -crop option in djpeg is
intended only as an example of how to use the partial image
decompression API.  Real-world applications would need to handle this
in their own destination managers.

It would probably be possible to make this work with Targa by employing
a similar hack to the one we used with PPM, but Targa isn't popular
enough to bother.

Fixes #185
2017-11-08 21:30:19 -06:00
DRC
44b2399a94 libjpeg API: Support reading/writing ICC profiles
This commit does the following:

-- Merges the two glueware functions (read_icc_profile() and
write_icc_profile()) from iccjpeg.c, which is contained in downstream
projects such as LCMS, Ghostscript, Mozilla, etc.  These functions were
originally intended for inclusion in libjpeg, but Tom Lane left the IJG
before that could be accomplished.  Since then, programs and libraries
that needed to embed/extract ICC profiles in JPEG files had to include
their own local copy of iccjpeg.c, which is suboptimal.

   -- The new functions were prefixed with jpeg_ and split into separate
   files for the compressor and decompressor, per the existing libjpeg
   coding standards.

   -- jpeg_write_icc_profile() was made slightly more fault-tolerant.
   It will now trigger a libjpeg error if it is called before
   jpeg_start_compress() or if it is passed NULL arguments.

   -- jpeg_read_icc_profile() was made slightly more fault-tolerant.
   It will now trigger a libjpeg error if it is called before
   jpeg_read_header() or if it is passed NULL arguments.  It will also
   now trigger libjpeg warnings if the ICC profile data is corrupt.

   -- The code comments have been wordsmithed.

   -- Note that the one-line setup_read_icc_profile() function was not
   included.  Instead, libjpeg.txt now documents the need to call
   jpeg_save_markers(cinfo, JPEG_APP0 + 2, 0xFFFF) prior to calling
   jpeg_read_header(), if jpeg_read_icc_profile() is to be used.

-- Adds documentation for the new functions to libjpeg.txt.

-- Adds an -icc switch to cjpeg and jpegtran that allows those programs
to embed an ICC profile in the JPEG files they generate.

-- Adds an -icc switch to djpeg that allows that program to extract an
ICC profile from a JPEG file while decompressing.

-- Adds appropriate unit tests for all of the above.

-- Bumps the SO_AGE of the libjpeg API library to indicate the presence
of new API functions.

Note that the licensing information was obtained from:
https://github.com/mm2/Little-CMS/issues/37#issuecomment-66450180
2017-01-19 19:06:22 -06:00
DRC
3ab68cf563 libjpeg API: Partial scanline decompression
This, in combination with the existing jpeg_skip_scanlines() function,
provides the ability to crop the image both horizontally and vertically
while decompressing (certain restrictions apply-- see libjpeg.txt.)

This also cleans up the documentation of the line skipping feature and
removes the "strip decompression" feature from djpeg, since the new
cropping feature is a superset of it.

Refer to #34 for discussion.

Closes #34
2016-02-19 21:07:39 -06:00
DRC
e621dfc508 More minor code formatting tweaks 2016-02-19 10:35:09 -06:00
DRC
bd49803f92 Use consistent/modern code formatting for pointers
The convention used by libjpeg:

    type * variable;

is not very common anymore, because it looks too much like
multiplication.  Some (particularly C++ programmers) prefer to tuck the
pointer symbol against the type:

    type* variable;

to emphasize that a pointer to a type is effectively a new type.
However, this can also be confusing, since defining multiple variables
on the same line would not work properly:

    type* variable1, variable2;  /* Only variable1 is actually a
                                    pointer. */

This commit reformats the entirety of the libjpeg-turbo code base so
that it uses the same code formatting convention for pointers that the
TurboJPEG API code uses:

    type *variable1, *variable2;

This seems to be the most common convention among C programmers, and
it is the convention used by other codec libraries, such as libpng and
libtiff.
2016-02-19 09:10:07 -06:00
DRC
54e6b8e806 Include some comments/doc tweaks from jpeg-9+ 2016-02-18 15:16:17 -06:00
Guido Vollbeding
a560e4b423 The Independent JPEG Group's JPEG software v9b 2016-02-16 12:27:41 -06:00
Guido Vollbeding
e7f88aec23 The Independent JPEG Group's JPEG software v9 2016-02-16 12:22:55 -06:00
DRC
1e32fe3113 Replace INT32 with a new internal datatype (JLONG)
These days, INT32 is a commonly-defined datatype in system headers.  We
cannot eliminate the definition of that datatype from jmorecfg.h, since
the INT32 typedef has technically been part of the libjpeg API since
version 5 (1994.)  However, using INT32 internally is risky, because the
inclusion of a particular header (Xmd.h, for instance) could change the
definition of INT32 from long to int on 64-bit platforms and thus change
the internal behavior of libjpeg-turbo in unexpected ways (for instance,
failing to correctly set __INT32_IS_ACTUALLY_LONG to match the INT32
typedef-- perhaps as a result of including the wrong version of
jpeglib.h-- could cause libjpeg-turbo to produce incorrect results.)

The library has always been built in environments in which INT32 is
effectively long (on Windows, long is always 32-bit, so effectively it's
the same as int), so it makes sense to turn INT32 into an explicitly
long datatype.  This ensures that libjpeg-turbo will always behave
consistently, regardless of the headers included at compile time.

Addresses a concern expressed in #26.
2015-10-14 20:34:32 -05:00
DRC
7e3acc0e0a Rename README, LICENSE, BUILDING text files
The IJG README file has been renamed to README.ijg, in order to avoid
confusion (many people were assuming that that was our project's README
file and weren't reading README-turbo.txt) and to lay the groundwork for
markdown versions of the libjpeg-turbo README and build instructions.
2015-10-10 10:31:33 -05:00
Guido Vollbeding
5996a25e2f The Independent JPEG Group's JPEG software v7 2015-07-27 13:44:25 -05:00
Thomas G. Lane
5ead57a34a The Independent JPEG Group's JPEG software v6b 2015-07-27 13:43:00 -05:00
Thomas G. Lane
489583f516 The Independent JPEG Group's JPEG software v6a 2015-07-29 15:32:35 -05:00
Thomas G. Lane
bc79e0680a The Independent JPEG Group's JPEG software v6 2015-07-29 15:31:30 -05:00
Thomas G. Lane
9ba2f5ed36 The Independent JPEG Group's JPEG software v5a 2015-07-29 15:29:17 -05:00