1 /* 2 3 Copyright (c) 2002-2003, Marcin 'Shard' Konicki 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions are met: 8 9 * Redistributions of source code must retain the above copyright notice, 10 this list of conditions and the following disclaimer. 11 * Redistributions in binary form must reproduce the above copyright notice, 12 this list of conditions and the following disclaimer in the documentation and/or 13 other materials provided with the distribution. 14 * Name "Marcin Konicki", "Shard" or any combination of them, 15 must not be used to endorse or promote products derived from this 16 software without specific prior written permission from Marcin Konicki. 17 18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 23 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 25 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 */ 31 32 33 /* 34 Modified jdatasrc.c from libjpeg 35 to use BPoistionIO instead of FILE 36 */ 37 38 39 //Be headers 40 #include <DataIO.h> 41 #include <stdio.h> 42 43 /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ 44 #include <jpeglib.h> 45 #include <jerror.h> 46 47 // instead of including jinclude - thx to it translator can be compiled 48 // without sources to jpeglib 49 #define SIZEOF(object) ((size_t) sizeof(object)) 50 51 /* Expanded data source object for stdio input */ 52 53 typedef struct { 54 struct jpeg_source_mgr pub; /* public fields */ 55 56 BPositionIO * infile; /* source stream */ 57 JOCTET * buffer; /* start of buffer */ 58 boolean start_of_file; /* have we gotten any data yet? */ 59 } be_source_mgr; 60 61 typedef be_source_mgr * be_src_ptr; 62 63 #define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ 64 65 66 /* 67 * Initialize source --- called by jpeg_read_header 68 * before any data is actually read. 69 */ 70 71 METHODDEF(void) 72 be_init_source (j_decompress_ptr cinfo) 73 { 74 be_src_ptr src = (be_src_ptr) cinfo->src; 75 76 /* We reset the empty-input-file flag for each image, 77 * but we don't clear the input buffer. 78 * This is correct behavior for reading a series of images from one source. 79 */ 80 src->start_of_file = TRUE; 81 } 82 83 84 /* 85 * Fill the input buffer --- called whenever buffer is emptied. 86 * 87 * In typical applications, this should read fresh data into the buffer 88 * (ignoring the current state of next_input_byte & bytes_in_buffer), 89 * reset the pointer & count to the start of the buffer, and return TRUE 90 * indicating that the buffer has been reloaded. It is not necessary to 91 * fill the buffer entirely, only to obtain at least one more byte. 92 * 93 * There is no such thing as an EOF return. If the end of the file has been 94 * reached, the routine has a choice of ERREXIT() or inserting fake data into 95 * the buffer. In most cases, generating a warning message and inserting a 96 * fake EOI marker is the best course of action --- this will allow the 97 * decompressor to output however much of the image is there. However, 98 * the resulting error message is misleading if the real problem is an empty 99 * input file, so we handle that case specially. 100 * 101 * In applications that need to be able to suspend compression due to input 102 * not being available yet, a FALSE return indicates that no more data can be 103 * obtained right now, but more may be forthcoming later. In this situation, 104 * the decompressor will return to its caller (with an indication of the 105 * number of scanlines it has read, if any). The application should resume 106 * decompression after it has loaded more data into the input buffer. Note 107 * that there are substantial restrictions on the use of suspension --- see 108 * the documentation. 109 * 110 * When suspending, the decompressor will back up to a convenient restart point 111 * (typically the start of the current MCU). next_input_byte & bytes_in_buffer 112 * indicate where the restart point will be if the current call returns FALSE. 113 * Data beyond this point must be rescanned after resumption, so move it to 114 * the front of the buffer rather than discarding it. 115 */ 116 117 METHODDEF(boolean) 118 be_fill_input_buffer (j_decompress_ptr cinfo) 119 { 120 be_src_ptr src = (be_src_ptr) cinfo->src; 121 size_t nbytes; 122 123 nbytes = src->infile->Read(src->buffer, INPUT_BUF_SIZE); 124 125 if (nbytes <= 0) { 126 if (src->start_of_file) /* Treat empty input file as fatal error */ 127 ERREXIT(cinfo, JERR_INPUT_EMPTY); 128 WARNMS(cinfo, JWRN_JPEG_EOF); 129 /* Insert a fake EOI marker */ 130 src->buffer[0] = (JOCTET) 0xFF; 131 src->buffer[1] = (JOCTET) JPEG_EOI; 132 nbytes = 2; 133 } 134 135 src->pub.next_input_byte = src->buffer; 136 src->pub.bytes_in_buffer = nbytes; 137 src->start_of_file = FALSE; 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 be_skip_input_data (j_decompress_ptr cinfo, long num_bytes) 157 { 158 be_src_ptr src = (be_src_ptr) cinfo->src; 159 160 /* Just a dumb implementation for now. Could use fseek() except 161 * it doesn't work on pipes. Not clear that being smart is worth 162 * any trouble anyway --- large skips are infrequent. 163 */ 164 if (num_bytes > 0) { 165 while (num_bytes > (long) src->pub.bytes_in_buffer) { 166 num_bytes -= (long) src->pub.bytes_in_buffer; 167 (void) be_fill_input_buffer(cinfo); 168 /* note we assume that fill_input_buffer will never return FALSE, 169 * so suspension need not be handled. 170 */ 171 } 172 src->pub.next_input_byte += (size_t) num_bytes; 173 src->pub.bytes_in_buffer -= (size_t) num_bytes; 174 } 175 } 176 177 178 /* 179 * An additional method that can be provided by data source modules is the 180 * resync_to_restart method for error recovery in the presence of RST markers. 181 * For the moment, this source module just uses the default resync method 182 * provided by the JPEG library. That method assumes that no backtracking 183 * is possible. 184 */ 185 186 187 /* 188 * Terminate source --- called by jpeg_finish_decompress 189 * after all data has been read. Often a no-op. 190 * 191 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding 192 * application must deal with any cleanup that should happen even 193 * for error exit. 194 */ 195 196 METHODDEF(void) 197 be_term_source (j_decompress_ptr cinfo) 198 { 199 /* no work necessary here */ 200 } 201 202 203 /* 204 * Prepare for input from a stdio stream. 205 * The caller must have already opened the stream, and is responsible 206 * for closing it after finishing decompression. 207 */ 208 209 GLOBAL(void) 210 be_jpeg_stdio_src (j_decompress_ptr cinfo, BPositionIO * infile) 211 { 212 be_src_ptr src; 213 214 /* The source object and input buffer are made permanent so that a series 215 * of JPEG images can be read from the same file by calling jpeg_stdio_src 216 * only before the first one. (If we discarded the buffer at the end of 217 * one image, we'd likely lose the start of the next one.) 218 * This makes it unsafe to use this manager and a different source 219 * manager serially with the same JPEG object. Caveat programmer. 220 */ 221 if (cinfo->src == NULL) { /* first time for this JPEG object? */ 222 cinfo->src = (struct jpeg_source_mgr *) 223 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 224 SIZEOF(be_source_mgr)); 225 src = (be_src_ptr) cinfo->src; 226 src->buffer = (JOCTET *) 227 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 228 INPUT_BUF_SIZE * SIZEOF(JOCTET)); 229 } 230 231 src = (be_src_ptr) cinfo->src; 232 src->pub.init_source = be_init_source; 233 src->pub.fill_input_buffer = be_fill_input_buffer; 234 src->pub.skip_input_data = be_skip_input_data; 235 src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ 236 src->pub.term_source = be_term_source; 237 src->infile = infile; 238 src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ 239 src->pub.next_input_byte = NULL; /* until buffer loaded */ 240 } 241