/packages/pasjpeg/src/jdinput.pas
Pascal | 416 lines | 244 code | 64 blank | 108 comment | 26 complexity | ff427832b00a28616cb65ce185e4d040 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, LGPL-3.0
1Unit JdInput; 2 3{ Original: jdinput.c ; Copyright (C) 1991-1997, Thomas G. Lane. } 4 5{ This file is part of the Independent JPEG Group's software. 6 For conditions of distribution and use, see the accompanying README file. 7 8 This file contains input control logic for the JPEG decompressor. 9 These routines are concerned with controlling the decompressor's input 10 processing (marker reading and coefficient decoding). The actual input 11 reading is done in jdmarker.c, jdhuff.c, and jdphuff.c. } 12 13interface 14 15{$I jconfig.inc} 16 17uses 18 jmorecfg, 19 jpeglib, 20 jdeferr, 21 jerror, 22 jinclude, jutils; 23 24{ Initialize the input controller module. 25 This is called only once, when the decompression object is created. } 26 27{GLOBAL} 28procedure jinit_input_controller (cinfo : j_decompress_ptr); 29 30implementation 31 32{ Private state } 33 34type 35 my_inputctl_ptr = ^my_input_controller; 36 my_input_controller = record 37 pub : jpeg_input_controller; { public fields } 38 39 inheaders : boolean; { TRUE until first SOS is reached } 40 end; {my_input_controller;} 41 42 43 44{ Forward declarations } 45{METHODDEF} 46function consume_markers (cinfo : j_decompress_ptr) : int; far; forward; 47 48 49{ Routines to calculate various quantities related to the size of the image. } 50 51{LOCAL} 52procedure initial_setup (cinfo : j_decompress_ptr); 53{ Called once, when first SOS marker is reached } 54var 55 ci : int; 56 compptr : jpeg_component_info_ptr; 57begin 58 { Make sure image isn't bigger than I can handle } 59 if (long(cinfo^.image_height) > long (JPEG_MAX_DIMENSION)) or 60 (long(cinfo^.image_width) > long(JPEG_MAX_DIMENSION)) then 61 ERREXIT1(j_common_ptr(cinfo), JERR_IMAGE_TOO_BIG, uInt(JPEG_MAX_DIMENSION)); 62 63 { For now, precision must match compiled-in value... } 64 if (cinfo^.data_precision <> BITS_IN_JSAMPLE) then 65 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PRECISION, cinfo^.data_precision); 66 67 { Check that number of components won't exceed internal array sizes } 68 if (cinfo^.num_components > MAX_COMPONENTS) then 69 ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, cinfo^.num_components, 70 MAX_COMPONENTS); 71 72 { Compute maximum sampling factors; check factor validity } 73 cinfo^.max_h_samp_factor := 1; 74 cinfo^.max_v_samp_factor := 1; 75 compptr := jpeg_component_info_ptr(cinfo^.comp_info); 76 for ci := 0 to pred(cinfo^.num_components) do 77 begin 78 if (compptr^.h_samp_factor<=0) or (compptr^.h_samp_factor>MAX_SAMP_FACTOR) or 79 (compptr^.v_samp_factor<=0) or (compptr^.v_samp_factor>MAX_SAMP_FACTOR) then 80 ERREXIT(j_common_ptr(cinfo), JERR_BAD_SAMPLING); 81 {cinfo^.max_h_samp_factor := MAX(cinfo^.max_h_samp_factor, 82 compptr^.h_samp_factor); 83 cinfo^.max_v_samp_factor := MAX(cinfo^.max_v_samp_factor, 84 compptr^.v_samp_factor);} 85 if cinfo^.max_h_samp_factor < compptr^.h_samp_factor then 86 cinfo^.max_h_samp_factor := compptr^.h_samp_factor; 87 if cinfo^.max_v_samp_factor < compptr^.v_samp_factor then 88 cinfo^.max_v_samp_factor := compptr^.v_samp_factor; 89 Inc(compptr); 90 end; 91 92 { We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE. 93 In the full decompressor, this will be overridden by jdmaster.c; 94 but in the transcoder, jdmaster.c is not used, so we must do it here. } 95 96 cinfo^.min_DCT_scaled_size := DCTSIZE; 97 98 { Compute dimensions of components } 99 compptr := jpeg_component_info_ptr(cinfo^.comp_info); 100 for ci := 0 to pred(cinfo^.num_components) do 101 begin 102 compptr^.DCT_scaled_size := DCTSIZE; 103 { Size in DCT blocks } 104 compptr^.width_in_blocks := JDIMENSION( 105 jdiv_round_up( long(cinfo^.image_width) * long(compptr^.h_samp_factor), 106 long(cinfo^.max_h_samp_factor * DCTSIZE)) ); 107 compptr^.height_in_blocks := JDIMENSION ( 108 jdiv_round_up(long (cinfo^.image_height) * long(compptr^.v_samp_factor), 109 long (cinfo^.max_v_samp_factor * DCTSIZE)) ); 110 { downsampled_width and downsampled_height will also be overridden by 111 jdmaster.c if we are doing full decompression. The transcoder library 112 doesn't use these values, but the calling application might. } 113 114 { Size in samples } 115 compptr^.downsampled_width := JDIMENSION ( 116 jdiv_round_up(long (cinfo^.image_width) * long(compptr^.h_samp_factor), 117 long (cinfo^.max_h_samp_factor)) ); 118 compptr^.downsampled_height := JDIMENSION ( 119 jdiv_round_up(long (cinfo^.image_height) * long(compptr^.v_samp_factor), 120 long (cinfo^.max_v_samp_factor)) ); 121 { Mark component needed, until color conversion says otherwise } 122 compptr^.component_needed := TRUE; 123 { Mark no quantization table yet saved for component } 124 compptr^.quant_table := NIL; 125 Inc(compptr); 126 end; 127 128 { Compute number of fully interleaved MCU rows. } 129 cinfo^.total_iMCU_rows := JDIMENSION( 130 jdiv_round_up(long(cinfo^.image_height), 131 long(cinfo^.max_v_samp_factor*DCTSIZE)) ); 132 133 { Decide whether file contains multiple scans } 134 if (cinfo^.comps_in_scan < cinfo^.num_components) or 135 (cinfo^.progressive_mode) then 136 cinfo^.inputctl^.has_multiple_scans := TRUE 137 else 138 cinfo^.inputctl^.has_multiple_scans := FALSE; 139end; 140 141 142{LOCAL} 143procedure per_scan_setup (cinfo : j_decompress_ptr); 144{ Do computations that are needed before processing a JPEG scan } 145{ cinfo^.comps_in_scan and cinfo^.cur_comp_info[] were set from SOS marker } 146var 147 ci, mcublks, tmp : int; 148 compptr : jpeg_component_info_ptr; 149begin 150 if (cinfo^.comps_in_scan = 1) then 151 begin 152 { Noninterleaved (single-component) scan } 153 compptr := cinfo^.cur_comp_info[0]; 154 155 { Overall image size in MCUs } 156 cinfo^.MCUs_per_row := compptr^.width_in_blocks; 157 cinfo^.MCU_rows_in_scan := compptr^.height_in_blocks; 158 159 { For noninterleaved scan, always one block per MCU } 160 compptr^.MCU_width := 1; 161 compptr^.MCU_height := 1; 162 compptr^.MCU_blocks := 1; 163 compptr^.MCU_sample_width := compptr^.DCT_scaled_size; 164 compptr^.last_col_width := 1; 165 { For noninterleaved scans, it is convenient to define last_row_height 166 as the number of block rows present in the last iMCU row. } 167 168 tmp := int (compptr^.height_in_blocks mod compptr^.v_samp_factor); 169 if (tmp = 0) then 170 tmp := compptr^.v_samp_factor; 171 compptr^.last_row_height := tmp; 172 173 { Prepare array describing MCU composition } 174 cinfo^.blocks_in_MCU := 1; 175 cinfo^.MCU_membership[0] := 0; 176 177 end 178 else 179 begin 180 181 { Interleaved (multi-component) scan } 182 if (cinfo^.comps_in_scan <= 0) or (cinfo^.comps_in_scan > MAX_COMPS_IN_SCAN) then 183 ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, cinfo^.comps_in_scan, 184 MAX_COMPS_IN_SCAN); 185 186 { Overall image size in MCUs } 187 cinfo^.MCUs_per_row := JDIMENSION ( 188 jdiv_round_up(long (cinfo^.image_width), 189 long (cinfo^.max_h_samp_factor*DCTSIZE)) ); 190 cinfo^.MCU_rows_in_scan := JDIMENSION ( 191 jdiv_round_up(long (cinfo^.image_height), 192 long (cinfo^.max_v_samp_factor*DCTSIZE)) ); 193 194 cinfo^.blocks_in_MCU := 0; 195 196 for ci := 0 to pred(cinfo^.comps_in_scan) do 197 begin 198 compptr := cinfo^.cur_comp_info[ci]; 199 { Sampling factors give # of blocks of component in each MCU } 200 compptr^.MCU_width := compptr^.h_samp_factor; 201 compptr^.MCU_height := compptr^.v_samp_factor; 202 compptr^.MCU_blocks := compptr^.MCU_width * compptr^.MCU_height; 203 compptr^.MCU_sample_width := compptr^.MCU_width * compptr^.DCT_scaled_size; 204 { Figure number of non-dummy blocks in last MCU column & row } 205 tmp := int (compptr^.width_in_blocks mod compptr^.MCU_width); 206 if (tmp = 0) then 207 tmp := compptr^.MCU_width; 208 compptr^.last_col_width := tmp; 209 tmp := int (compptr^.height_in_blocks mod compptr^.MCU_height); 210 if (tmp = 0) then 211 tmp := compptr^.MCU_height; 212 compptr^.last_row_height := tmp; 213 { Prepare array describing MCU composition } 214 mcublks := compptr^.MCU_blocks; 215 if (cinfo^.blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU) then 216 ERREXIT(j_common_ptr(cinfo), JERR_BAD_MCU_SIZE); 217 while (mcublks > 0) do 218 begin 219 Dec(mcublks); 220 cinfo^.MCU_membership[cinfo^.blocks_in_MCU] := ci; 221 Inc(cinfo^.blocks_in_MCU); 222 end; 223 end; 224 225 end; 226end; 227 228 229{ Save away a copy of the Q-table referenced by each component present 230 in the current scan, unless already saved during a prior scan. 231 232 In a multiple-scan JPEG file, the encoder could assign different components 233 the same Q-table slot number, but change table definitions between scans 234 so that each component uses a different Q-table. (The IJG encoder is not 235 currently capable of doing this, but other encoders might.) Since we want 236 to be able to dequantize all the components at the end of the file, this 237 means that we have to save away the table actually used for each component. 238 We do this by copying the table at the start of the first scan containing 239 the component. 240 The JPEG spec prohibits the encoder from changing the contents of a Q-table 241 slot between scans of a component using that slot. If the encoder does so 242 anyway, this decoder will simply use the Q-table values that were current 243 at the start of the first scan for the component. 244 245 The decompressor output side looks only at the saved quant tables, 246 not at the current Q-table slots. } 247 248{LOCAL} 249procedure latch_quant_tables (cinfo : j_decompress_ptr); 250var 251 ci, qtblno : int; 252 compptr : jpeg_component_info_ptr; 253 qtbl : JQUANT_TBL_PTR; 254begin 255 for ci := 0 to pred(cinfo^.comps_in_scan) do 256 begin 257 compptr := cinfo^.cur_comp_info[ci]; 258 { No work if we already saved Q-table for this component } 259 if (compptr^.quant_table <> NIL) then 260 continue; 261 { Make sure specified quantization table is present } 262 qtblno := compptr^.quant_tbl_no; 263 if (qtblno < 0) or (qtblno >= NUM_QUANT_TBLS) or 264 (cinfo^.quant_tbl_ptrs[qtblno] = NIL) then 265 ERREXIT1(j_common_ptr(cinfo), JERR_NO_QUANT_TABLE, qtblno); 266 { OK, save away the quantization table } 267 qtbl := JQUANT_TBL_PTR( 268 cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, 269 SIZEOF(JQUANT_TBL)) ); 270 MEMCOPY(qtbl, cinfo^.quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL)); 271 compptr^.quant_table := qtbl; 272 end; 273end; 274 275 276{ Initialize the input modules to read a scan of compressed data. 277 The first call to this is done by jdmaster.c after initializing 278 the entire decompressor (during jpeg_start_decompress). 279 Subsequent calls come from consume_markers, below. } 280 281{METHODDEF} 282procedure start_input_pass (cinfo : j_decompress_ptr); far; 283begin 284 per_scan_setup(cinfo); 285 latch_quant_tables(cinfo); 286 cinfo^.entropy^.start_pass (cinfo); 287 cinfo^.coef^.start_input_pass (cinfo); 288 cinfo^.inputctl^.consume_input := cinfo^.coef^.consume_data; 289end; 290 291 292{ Finish up after inputting a compressed-data scan. 293 This is called by the coefficient controller after it's read all 294 the expected data of the scan. } 295 296{METHODDEF} 297procedure finish_input_pass (cinfo : j_decompress_ptr); far; 298begin 299 cinfo^.inputctl^.consume_input := consume_markers; 300end; 301 302 303{ Read JPEG markers before, between, or after compressed-data scans. 304 Change state as necessary when a new scan is reached. 305 Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. 306 307 The consume_input method pointer points either here or to the 308 coefficient controller's consume_data routine, depending on whether 309 we are reading a compressed data segment or inter-segment markers. } 310 311{METHODDEF} 312function consume_markers (cinfo : j_decompress_ptr) : int; 313var 314 val : int; 315 inputctl : my_inputctl_ptr; 316begin 317 inputctl := my_inputctl_ptr (cinfo^.inputctl); 318 319 if (inputctl^.pub.eoi_reached) then { After hitting EOI, read no further } 320 begin 321 consume_markers := JPEG_REACHED_EOI; 322 exit; 323 end; 324 325 val := cinfo^.marker^.read_markers (cinfo); 326 327 case (val) of 328 JPEG_REACHED_SOS: { Found SOS } 329 begin 330 if (inputctl^.inheaders) then 331 begin { 1st SOS } 332 initial_setup(cinfo); 333 inputctl^.inheaders := FALSE; 334 { Note: start_input_pass must be called by jdmaster.c 335 before any more input can be consumed. jdapimin.c is 336 responsible for enforcing this sequencing. } 337 end 338 else 339 begin { 2nd or later SOS marker } 340 if (not inputctl^.pub.has_multiple_scans) then 341 ERREXIT(j_common_ptr(cinfo), JERR_EOI_EXPECTED); { Oops, I wasn't expecting this! } 342 start_input_pass(cinfo); 343 end; 344 end; 345 JPEG_REACHED_EOI: { Found EOI } 346 begin 347 inputctl^.pub.eoi_reached := TRUE; 348 if (inputctl^.inheaders) then 349 begin { Tables-only datastream, apparently } 350 if (cinfo^.marker^.saw_SOF) then 351 ERREXIT(j_common_ptr(cinfo), JERR_SOF_NO_SOS); 352 end 353 else 354 begin 355 { Prevent infinite loop in coef ctlr's decompress_data routine 356 if user set output_scan_number larger than number of scans. } 357 358 if (cinfo^.output_scan_number > cinfo^.input_scan_number) then 359 cinfo^.output_scan_number := cinfo^.input_scan_number; 360 end; 361 end; 362 JPEG_SUSPENDED:; 363 end; 364 365 consume_markers := val; 366end; 367 368 369{ Reset state to begin a fresh datastream. } 370 371{METHODDEF} 372procedure reset_input_controller (cinfo : j_decompress_ptr); far; 373var 374 inputctl : my_inputctl_ptr; 375begin 376 inputctl := my_inputctl_ptr (cinfo^.inputctl); 377 378 inputctl^.pub.consume_input := consume_markers; 379 inputctl^.pub.has_multiple_scans := FALSE; { "unknown" would be better } 380 inputctl^.pub.eoi_reached := FALSE; 381 inputctl^.inheaders := TRUE; 382 { Reset other modules } 383 cinfo^.err^.reset_error_mgr (j_common_ptr(cinfo)); 384 cinfo^.marker^.reset_marker_reader (cinfo); 385 { Reset progression state -- would be cleaner if entropy decoder did this } 386 cinfo^.coef_bits := NIL; 387end; 388 389 390{ Initialize the input controller module. 391 This is called only once, when the decompression object is created. } 392 393{GLOBAL} 394procedure jinit_input_controller (cinfo : j_decompress_ptr); 395var 396 inputctl : my_inputctl_ptr; 397begin 398 { Create subobject in permanent pool } 399 inputctl := my_inputctl_ptr( 400 cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, 401 SIZEOF(my_input_controller)) ); 402 cinfo^.inputctl := jpeg_input_controller_ptr(inputctl); 403 { Initialize method pointers } 404 inputctl^.pub.consume_input := consume_markers; 405 inputctl^.pub.reset_input_controller := reset_input_controller; 406 inputctl^.pub.start_input_pass := start_input_pass; 407 inputctl^.pub.finish_input_pass := finish_input_pass; 408 { Initialize state: can't use reset_input_controller since we don't 409 want to try to reset other modules yet. } 410 411 inputctl^.pub.has_multiple_scans := FALSE; { "unknown" would be better } 412 inputctl^.pub.eoi_reached := FALSE; 413 inputctl^.inheaders := TRUE; 414end; 415 416end.