1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file.
6 #include "lib/jpegli/decode.h"
7 #include "lib/jpegli/error.h"
8 #include "lib/jpegli/memory_manager.h"
12 void init_mem_source(j_decompress_ptr cinfo
) {}
13 void init_stdio_source(j_decompress_ptr cinfo
) {}
15 void skip_input_data(j_decompress_ptr cinfo
, long num_bytes
) {
16 if (num_bytes
<= 0) return;
17 while (num_bytes
> static_cast<long>(cinfo
->src
->bytes_in_buffer
)) {
18 num_bytes
-= cinfo
->src
->bytes_in_buffer
;
19 (*cinfo
->src
->fill_input_buffer
)(cinfo
);
21 cinfo
->src
->next_input_byte
+= num_bytes
;
22 cinfo
->src
->bytes_in_buffer
-= num_bytes
;
25 void term_source(j_decompress_ptr cinfo
) {}
27 boolean
EmitFakeEoiMarker(j_decompress_ptr cinfo
) {
28 static constexpr uint8_t kFakeEoiMarker
[2] = {0xff, 0xd9};
29 cinfo
->src
->next_input_byte
= kFakeEoiMarker
;
30 cinfo
->src
->bytes_in_buffer
= 2;
34 constexpr size_t kStdioBufferSize
= 64 << 10;
36 struct StdioSourceManager
{
41 static boolean
fill_input_buffer(j_decompress_ptr cinfo
) {
42 auto src
= reinterpret_cast<StdioSourceManager
*>(cinfo
->src
);
43 size_t num_bytes_read
= fread(src
->buffer
, 1, kStdioBufferSize
, src
->f
);
44 if (num_bytes_read
== 0) {
45 return EmitFakeEoiMarker(cinfo
);
47 src
->pub
.next_input_byte
= src
->buffer
;
48 src
->pub
.bytes_in_buffer
= num_bytes_read
;
55 void jpegli_mem_src(j_decompress_ptr cinfo
, const unsigned char* inbuffer
,
56 unsigned long insize
) {
57 if (cinfo
->src
&& cinfo
->src
->init_source
!= jpegli::init_mem_source
) {
58 JPEGLI_ERROR("jpegli_mem_src: a different source manager was already set");
61 cinfo
->src
= jpegli::Allocate
<jpeg_source_mgr
>(cinfo
, 1);
63 cinfo
->src
->next_input_byte
= inbuffer
;
64 cinfo
->src
->bytes_in_buffer
= insize
;
65 cinfo
->src
->init_source
= jpegli::init_mem_source
;
66 cinfo
->src
->fill_input_buffer
= jpegli::EmitFakeEoiMarker
;
67 cinfo
->src
->skip_input_data
= jpegli::skip_input_data
;
68 cinfo
->src
->resync_to_restart
= jpegli_resync_to_restart
;
69 cinfo
->src
->term_source
= jpegli::term_source
;
72 void jpegli_stdio_src(j_decompress_ptr cinfo
, FILE* infile
) {
73 if (cinfo
->src
&& cinfo
->src
->init_source
!= jpegli::init_stdio_source
) {
74 JPEGLI_ERROR("jpeg_stdio_src: a different source manager was already set");
77 cinfo
->src
= reinterpret_cast<jpeg_source_mgr
*>(
78 jpegli::Allocate
<jpegli::StdioSourceManager
>(cinfo
, 1));
80 auto src
= reinterpret_cast<jpegli::StdioSourceManager
*>(cinfo
->src
);
82 src
->buffer
= jpegli::Allocate
<uint8_t>(cinfo
, jpegli::kStdioBufferSize
);
83 src
->pub
.next_input_byte
= src
->buffer
;
84 src
->pub
.bytes_in_buffer
= 0;
85 src
->pub
.init_source
= jpegli::init_stdio_source
;
86 src
->pub
.fill_input_buffer
= jpegli::StdioSourceManager::fill_input_buffer
;
87 src
->pub
.skip_input_data
= jpegli::skip_input_data
;
88 src
->pub
.resync_to_restart
= jpegli_resync_to_restart
;
89 src
->pub
.term_source
= jpegli::term_source
;