Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/libjpeg/jdatasrc.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 * jdatasrc.c | |
| 3 * | |
| 4 * Copyright (C) 1994-1996, Thomas G. Lane. | |
| 5 * Modified 2009-2022 by Guido Vollbeding. | |
| 6 * This file is part of the Independent JPEG Group's software. | |
| 7 * For conditions of distribution and use, see the accompanying README file. | |
| 8 * | |
| 9 * This file contains decompression data source routines for the case of | |
| 10 * reading JPEG data from memory or from a file (or any stdio stream). | |
| 11 * While these routines are sufficient for most applications, | |
| 12 * some will want to use a different source manager. | |
| 13 * IMPORTANT: we assume that fread() will correctly transcribe an array of | |
| 14 * JOCTETs from 8-bit-wide elements on external storage. If char is wider | |
| 15 * than 8 bits on your machine, you may need to do some tweaking. | |
| 16 */ | |
| 17 | |
| 18 /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ | |
| 19 #include "jinclude.h" | |
| 20 #include "jpeglib.h" | |
| 21 #include "jerror.h" | |
| 22 | |
| 23 | |
| 24 /* Expanded data source object for stdio input */ | |
| 25 | |
| 26 #define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ | |
| 27 | |
| 28 typedef struct { | |
| 29 struct jpeg_source_mgr pub; /* public fields */ | |
| 30 | |
| 31 FILE * infile; /* source stream */ | |
| 32 JOCTET buffer[INPUT_BUF_SIZE]; /* input buffer */ | |
| 33 boolean start_of_file; /* have we gotten any data yet? */ | |
| 34 } my_source_mgr; | |
| 35 | |
| 36 typedef my_source_mgr * my_src_ptr; | |
| 37 | |
| 38 | |
| 39 /* | |
| 40 * Initialize source --- called by jpeg_read_header | |
| 41 * before any data is actually read. | |
| 42 */ | |
| 43 | |
| 44 METHODDEF(void) | |
| 45 init_source (j_decompress_ptr cinfo) | |
| 46 { | |
| 47 my_src_ptr src = (my_src_ptr) cinfo->src; | |
| 48 | |
| 49 /* We reset the empty-input-file flag for each image, | |
| 50 * but we don't clear the input buffer. | |
| 51 * This is correct behavior for reading a series of images from one source. | |
| 52 */ | |
| 53 src->start_of_file = TRUE; | |
| 54 } | |
| 55 | |
| 56 METHODDEF(void) | |
| 57 init_mem_source (j_decompress_ptr cinfo) | |
| 58 { | |
| 59 /* no work necessary here */ | |
| 60 } | |
| 61 | |
| 62 | |
| 63 /* | |
| 64 * Fill the input buffer --- called whenever buffer is emptied. | |
| 65 * | |
| 66 * In typical applications, this should read fresh data into the buffer | |
| 67 * (ignoring the current state of next_input_byte & bytes_in_buffer), | |
| 68 * reset the pointer & count to the start of the buffer, and return TRUE | |
| 69 * indicating that the buffer has been reloaded. It is not necessary to | |
| 70 * fill the buffer entirely, only to obtain at least one more byte. | |
| 71 * | |
| 72 * There is no such thing as an EOF return. If the end of the file has been | |
| 73 * reached, the routine has a choice of ERREXIT() or inserting fake data into | |
| 74 * the buffer. In most cases, generating a warning message and inserting a | |
| 75 * fake EOI marker is the best course of action --- this will allow the | |
| 76 * decompressor to output however much of the image is there. However, | |
| 77 * the resulting error message is misleading if the real problem is an empty | |
| 78 * input file, so we handle that case specially. | |
| 79 * | |
| 80 * In applications that need to be able to suspend compression due to input | |
| 81 * not being available yet, a FALSE return indicates that no more data can be | |
| 82 * obtained right now, but more may be forthcoming later. In this situation, | |
| 83 * the decompressor will return to its caller (with an indication of the | |
| 84 * number of scanlines it has read, if any). The application should resume | |
| 85 * decompression after it has loaded more data into the input buffer. Note | |
| 86 * that there are substantial restrictions on the use of suspension --- see | |
| 87 * the documentation. | |
| 88 * | |
| 89 * When suspending, the decompressor will back up to a convenient restart point | |
| 90 * (typically the start of the current MCU). next_input_byte & bytes_in_buffer | |
| 91 * indicate where the restart point will be if the current call returns FALSE. | |
| 92 * Data beyond this point must be rescanned after resumption, so move it to | |
| 93 * the front of the buffer rather than discarding it. | |
| 94 */ | |
| 95 | |
| 96 METHODDEF(boolean) | |
| 97 fill_input_buffer (j_decompress_ptr cinfo) | |
| 98 { | |
| 99 my_src_ptr src = (my_src_ptr) cinfo->src; | |
| 100 size_t nbytes; | |
| 101 | |
| 102 nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE); | |
| 103 | |
| 104 if (nbytes <= 0) { | |
| 105 if (src->start_of_file) /* Treat empty input file as fatal error */ | |
| 106 ERREXIT(cinfo, JERR_INPUT_EMPTY); | |
| 107 WARNMS(cinfo, JWRN_JPEG_EOF); | |
| 108 /* Insert a fake EOI marker */ | |
| 109 src->buffer[0] = (JOCTET) 0xFF; | |
| 110 src->buffer[1] = (JOCTET) JPEG_EOI; | |
| 111 nbytes = 2; | |
| 112 } | |
| 113 | |
| 114 src->pub.next_input_byte = src->buffer; | |
| 115 src->pub.bytes_in_buffer = nbytes; | |
| 116 src->start_of_file = FALSE; | |
| 117 | |
| 118 return TRUE; | |
| 119 } | |
| 120 | |
| 121 METHODDEF(boolean) | |
| 122 fill_mem_input_buffer (j_decompress_ptr cinfo) | |
| 123 { | |
| 124 static const JOCTET mybuffer[4] = { | |
| 125 (JOCTET) 0xFF, (JOCTET) JPEG_EOI, 0, 0 | |
| 126 }; | |
| 127 | |
| 128 /* The whole JPEG data is expected to reside in the supplied memory | |
| 129 * buffer, so any request for more data beyond the given buffer size | |
| 130 * is treated as an error. | |
| 131 */ | |
| 132 WARNMS(cinfo, JWRN_JPEG_EOF); | |
| 133 | |
| 134 /* Insert a fake EOI marker */ | |
| 135 | |
| 136 cinfo->src->next_input_byte = mybuffer; | |
| 137 cinfo->src->bytes_in_buffer = 2; | |
| 138 | |
| 139 return TRUE; | |
| 140 } | |
| 141 | |
| 142 | |
| 143 /* | |
| 144 * Skip data --- used to skip over a potentially large amount of | |
| 145 * uninteresting data (such as an APPn marker). | |
| 146 * | |
| 147 * Writers of suspendable-input applications must note that skip_input_data | |
| 148 * is not granted the right to give a suspension return. If the skip extends | |
| 149 * beyond the data currently in the buffer, the buffer can be marked empty so | |
| 150 * that the next read will cause a fill_input_buffer call that can suspend. | |
| 151 * Arranging for additional bytes to be discarded before reloading the input | |
| 152 * buffer is the application writer's problem. | |
| 153 */ | |
| 154 | |
| 155 METHODDEF(void) | |
| 156 skip_input_data (j_decompress_ptr cinfo, long num_bytes) | |
| 157 { | |
| 158 struct jpeg_source_mgr * src = cinfo->src; | |
| 159 size_t nbytes; | |
| 160 | |
| 161 /* Just a dumb implementation for now. Could use fseek() except | |
| 162 * it doesn't work on pipes. Not clear that being smart is worth | |
| 163 * any trouble anyway --- large skips are infrequent. | |
| 164 */ | |
| 165 if (num_bytes > 0) { | |
| 166 nbytes = (size_t) num_bytes; | |
| 167 while (nbytes > src->bytes_in_buffer) { | |
| 168 nbytes -= src->bytes_in_buffer; | |
| 169 (void) (*src->fill_input_buffer) (cinfo); | |
| 170 /* note we assume that fill_input_buffer will never return FALSE, | |
| 171 * so suspension need not be handled. | |
| 172 */ | |
| 173 } | |
| 174 src->next_input_byte += nbytes; | |
| 175 src->bytes_in_buffer -= nbytes; | |
| 176 } | |
| 177 } | |
| 178 | |
| 179 | |
| 180 /* | |
| 181 * An additional method that can be provided by data source modules is the | |
| 182 * resync_to_restart method for error recovery in the presence of RST markers. | |
| 183 * For the moment, this source module just uses the default resync method | |
| 184 * provided by the JPEG library. That method assumes that no backtracking | |
| 185 * is possible. | |
| 186 */ | |
| 187 | |
| 188 | |
| 189 /* | |
| 190 * Terminate source --- called by jpeg_finish_decompress | |
| 191 * after all data has been read. Often a no-op. | |
| 192 * | |
| 193 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding | |
| 194 * application must deal with any cleanup that should happen even | |
| 195 * for error exit. | |
| 196 */ | |
| 197 | |
| 198 METHODDEF(void) | |
| 199 term_source (j_decompress_ptr cinfo) | |
| 200 { | |
| 201 /* no work necessary here */ | |
| 202 } | |
| 203 | |
| 204 | |
| 205 /* | |
| 206 * Prepare for input from a stdio stream. | |
| 207 * The caller must have already opened the stream, | |
| 208 * and is responsible for closing it after finishing decompression. | |
| 209 */ | |
| 210 | |
| 211 GLOBAL(void) | |
| 212 jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile) | |
| 213 { | |
| 214 my_src_ptr src; | |
| 215 | |
| 216 /* The source object including the input buffer is made permanent so that | |
| 217 * a series of JPEG images can be read from the same file by calling | |
| 218 * jpeg_stdio_src only before the first one. (If we discarded the buffer | |
| 219 * at the end of one image, we'd likely lose the start of the next one.) | |
| 220 * This makes it unsafe to use this manager and a different source | |
| 221 * manager serially with the same JPEG object. Caveat programmer. | |
| 222 */ | |
| 223 if (cinfo->src == NULL) { /* first time for this JPEG object? */ | |
| 224 cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small) | |
| 225 ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_source_mgr)); | |
| 226 } | |
| 227 | |
| 228 src = (my_src_ptr) cinfo->src; | |
| 229 src->pub.init_source = init_source; | |
| 230 src->pub.fill_input_buffer = fill_input_buffer; | |
| 231 src->pub.skip_input_data = skip_input_data; | |
| 232 src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ | |
| 233 src->pub.term_source = term_source; | |
| 234 src->infile = infile; | |
| 235 src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ | |
| 236 src->pub.next_input_byte = NULL; /* until buffer loaded */ | |
| 237 } | |
| 238 | |
| 239 | |
| 240 /* | |
| 241 * Prepare for input from a supplied memory buffer. | |
| 242 * The buffer must contain the whole JPEG data. | |
| 243 */ | |
| 244 | |
| 245 GLOBAL(void) | |
| 246 jpeg_mem_src (j_decompress_ptr cinfo, | |
| 247 const unsigned char * inbuffer, size_t insize) | |
| 248 { | |
| 249 struct jpeg_source_mgr * src; | |
| 250 | |
| 251 if (inbuffer == NULL || insize == 0) /* Treat empty input as fatal error */ | |
| 252 ERREXIT(cinfo, JERR_INPUT_EMPTY); | |
| 253 | |
| 254 /* The source object is made permanent so that a series of JPEG images | |
| 255 * can be read from the same buffer by calling jpeg_mem_src only before | |
| 256 * the first one. | |
| 257 */ | |
| 258 if (cinfo->src == NULL) { /* first time for this JPEG object? */ | |
| 259 cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small) | |
| 260 ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(struct jpeg_source_mgr)); | |
| 261 } | |
| 262 | |
| 263 src = cinfo->src; | |
| 264 src->init_source = init_mem_source; | |
| 265 src->fill_input_buffer = fill_mem_input_buffer; | |
| 266 src->skip_input_data = skip_input_data; | |
| 267 src->resync_to_restart = jpeg_resync_to_restart; /* use default method */ | |
| 268 src->term_source = term_source; | |
| 269 src->bytes_in_buffer = insize; | |
| 270 src->next_input_byte = (const JOCTET *) inbuffer; | |
| 271 } |
