Repository navigation
Conversation
The host buffer for CPU Huffman coding was allocated with the current data_size but gpujpeg_coder_init_image() keeps it as long as the image fits data_allocated_size (the device buffer). After switching to a layout with larger data_size that still fits (eg. 4:2:0 -> 4:4:4 after a bigger image was coded), the CPU Huffman decoder wrote past the buffer and the host<->device copies exceeded it (encoder with restart interval 0, decoder with < 32 segments, eg. any JPEG without restart markers).
The preprocessor (kernel selection and component buffer pointers) was reinitialized only when the input image parameters changed. Changing eg. only the subsampling for the same input produced a wrong JPEG or even wrote to the freed device buffers (if they were reallocated).
Reuses one encoder and one decoder for a sequence of layouts (subsampling, restart interval -> GPU/CPU Huffman coder) and an output format change and compares the results with freshly created coders.
Compare while the fresh encoder lives and decode the reused encoder's output, which stays valid until its next encode.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two bugs when reusing an encoder/decoder with a different JPEG layout (e.g. subsampling) at the same image size:
Encoder: preprocessor not reinitialized.
gpujpeg_preprocessor_encoder_init()was only called onimg_changed, so after 4:4:4 → 4:2:0 it kept the old component pointers, widths and sampling ratios. Result: wrong chroma in the JPEG; ifgpujpeg_coder_init_image()reallocated the buffers (4:2:0 → 4:4:4), it writes to freed device memory. Now it is also reinitialized whengpujpeg_parameters_equals()reports a change (function made non-static).CPU Huffman host buffer overflow.
data_quantizedwas allocated withdata_size, butgpujpeg_coder_init_image()keeps it as long as the frame fitsdata_allocated_size. Example: 4:4:4 with restart markers (GPU Huffman, large device buffer), then 4:2:0 without restart markers (host buffer allocated at 4:2:0 size), then 4:4:4 without restart markers → 2× overflow. This affects the encoder withrestart_interval == 0and the decoder with < 32 segments. Now it is allocated withdata_allocated_size.Test:
test_coder_reinitreuses one encoder and one decoder for 256×256 frames: 444/RI 8 → 420/RI 0 → 444/RI 0 → 420/RI 8, plus a step that changes only the decoder output format. After each step it compares the result with a fresh coder.reused encoder differs from a fresh one), so the overflow step is never reached there.compute-sanitizermemcheck on the test reports 0 errors and 0 leaks (RTX 4090, CUDA 13.4).