Both decoders treated every 3-component image as YCbCr, so RGB JPEGs
(as written by cjpeg -rgb, and by some Adobe software) came out with
wrong colours.
Decide the colour space as libjpeg does: a JFIF marker means YCbCr;
otherwise the transform flag of an Adobe APP14 marker decides (0 is
RGB); otherwise component IDs 'R', 'G', 'B' mean RGB.
Core loader: on colour targets R, G and B are stored in place in the
row buffer and the YUV conversion is skipped. Greyscale builds now
also decode G and B for RGB and combine them into luma per block,
which needs every component to be one block per MCU; other RGB
layouts are rejected there.
Plugin: RGB needs one block per MCU for every component, otherwise it
is rejected (colour targets fall back to jpegp). Colour builds convert
the R, G and B planes to YCbCr in place after decoding, so display and
greyscale view modes are unchanged; greyscale builds combine R, G and
B into luma per block as the core does.
Code size on the e200: core loader +351 bytes, plugin decoder +603
bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Ib24a0b7690ca4c00b3ac01b2f511309efeac5975
Damaged and truncated JPEGs could make the image viewer read or write
outside its buffers:
- process_markers() trusted segment lengths, and Huffman table symbol
counts, so a segment running past the end of the file was parsed
from whatever memory followed it. Check that each marker segment,
and each Huffman table in it, lies within the file.
- A file without a complete SOS header was decoded from a NULL entropy
data pointer, as load_image() checked only for DQT and SOF. Require
SOS as well.
- img_mem() computed the image size in an int, which overflows for a
large image (a 65535x65535 file came out as 0), so the decode wrote
far past the buffer. Compute it in 64 bits and saturate.
Found with the jpeg-conformance files of the imazen codec-corpus,
which include truncated files and files from fuzzing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I1e2a9a4346fd1c0e34b0813267c6317dbf704bc7
Both JPEG decoders accepted several baseline layouts they cannot decode
and produced garbage without an error:
- chroma with sampling factors other than 1x1 (the MCU layout is chosen
from luma alone, so any other chroma layout desynchronises)
- files written as more than one scan, where the first scan does not
hold every component (it was decoded as if it were interleaved)
- scans whose components are not in frame order
- a height of 0 in SOF, to be defined later by a DNL marker
Reject these in process_markers(). The imageviewer then falls back to
the jpegp decoder on colour targets, which handles all of them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Ia3373f2b934eef6e3f354b4d064faf2d89868050
Both JPEG decoders ignored the Tq selector in the frame header and
always dequantized luma with table 0 and chroma with table 1. Files
with a single shared table multiplied chroma by an empty table, and
files with separate Cb and Cr tables used the wrong one for Cr.
imageviewer/jpeg: build one dequantization table per component (3
instead of 2, +256 bytes) from the table it selects. tab_membership is
no longer used and is removed.
Core loader: the raw tables are pre-scaled in place for the IDCT, and
luma and chroma can use different IDCT scales. fix_quant_tables() now
maps each component to a table slot, copying a table that luma and
chroma share at different scales to a slot no component uses (there are
4 slots and at most 3 components, so one is always free), and rewrites
quanttable_select to that slot. No extra memory.
Selectors above 3 are rejected.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: If04c61fb0fef95da11d98d9918ea7225d8a440b0
Both JPEG decoders ignored the DC/AC table selectors in the SOS header
and always decoded luma with tables 0 and chroma with tables 1, the
layout libjpeg writes by default. Files where all components share
table 0, or where the slots are assigned differently, decoded to noise.
Look up each component's tables from its selectors instead. Baseline
JPEG only allows tables 0 and 1, which both decoders already hold, so
this needs no extra memory; selectors above 1 are rejected. In the core
loader tab_membership is no longer used and is removed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Ie1ec407ddecf1256fef410b1256b97af412fb194
The bit reader refilled from the input buffer without checking its end.
The end-of-data check in the decode loops only runs once per MCU row, so
a stream that desynchronises (or is truncated) read past the end of the
file buffer for the rest of the row. Return zero bytes past the end
instead; the pointer still advances so the per-row check stops the
decode.
Found with AddressSanitizer on a JPEG whose chroma is sampled more
densely than its luma.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Iaada1bc3cbf62b18f10fb2377c12d4d5cb9524de
A single-component (grayscale) scan is non-interleaved, so its MCU is
one 8x8 block regardless of the sampling factors in the frame header
(T.81 A.2.2). Some encoders write H=2,V=2 for the lone component, which
sent both the imageviewer plugin decoder and the core loader down the
4:2:0 path: 6 blocks per 16x16 MCU, the image treated as colour, and
the entropy data overrun.
Force 1x1 sampling for single-component frames when parsing SOF0 so
these images use the 4:4:4 layout with one block per MCU. Also add the
missing else in fix_headers() in the core loader, matching the plugin.
Tested on a Sansa e200 with both the plugin and the core loader, and
the plugin in the e200 simulator and built for PC and for ARM (qemu).
Fixes FS#13749.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Iac2f925aab8cd602930470dca5da7dfb44e15961
This changes JPEG fill and invalid byte handling to be like
mozjpeg, and bases entropy data start on SOS marker location.
Thanks to Stefan Waldmann and Dean Tersigni for reporting.
Change-Id: I3c79cc6ac8d714fdc75c12b57ba427d611c99519
Chaange-Id: Ibc7c17d38d5be63642bdaf6adfd6acc2a6cf4450
* Created new directory, imageviewer/ and moved both jpeg/ and png/ under it.
- this still doesn't merge the two plugins. i.e. both jpeg.rock and png.rock will be made for color targets.
- I'm thinking to merge the two plugins to single image viewer later.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24272 a1c6a512-1295-4272-9138-f99709370657
2010-01-18 12:46:19 +00:00
Renamed from apps/plugins/jpeg/jpeg_decoder.c (Browse further)