jdtrans.cpp (4133B)
1 /* 2 * jdtrans.c 3 * 4 * Copyright (C) 1995, Thomas G. Lane. 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 library routines for transcoding decompression, 9 * that is, reading raw DCT coefficient arrays from an input JPEG file. 10 * The routines in jdapimin.c will also be needed by a transcoder. 11 */ 12 13 #define JPEG_INTERNALS 14 #include "jinclude.h" 15 #include "jpeglib.h" 16 17 18 /* Forward declarations */ 19 LOCAL void transdecode_master_selection JPP((j_decompress_ptr cinfo)); 20 21 22 /* 23 * Read the coefficient arrays from a JPEG file. 24 * jpeg_read_header must be completed before calling this. 25 * 26 * The entire image is read into a set of virtual coefficient-block arrays, 27 * one per component. The return value is a pointer to the array of 28 * virtual-array descriptors. These can be manipulated directly via the 29 * JPEG memory manager, or handed off to jpeg_write_coefficients(). 30 * To release the memory occupied by the virtual arrays, call 31 * jpeg_finish_decompress() when done with the data. 32 * 33 * Returns NULL if suspended. This case need be checked only if 34 * a suspending data source is used. 35 */ 36 37 GLOBAL jvirt_barray_ptr * 38 jpeg_read_coefficients (j_decompress_ptr cinfo) 39 { 40 if (cinfo->global_state == DSTATE_READY) { 41 /* First call: initialize active modules */ 42 transdecode_master_selection(cinfo); 43 cinfo->global_state = DSTATE_RDCOEFS; 44 } else if (cinfo->global_state != DSTATE_RDCOEFS) 45 ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 46 /* Absorb whole file into the coef buffer */ 47 for (;;) { 48 int retcode; 49 /* Call progress monitor hook if present */ 50 if (cinfo->progress != NULL) 51 (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); 52 /* Absorb some more input */ 53 retcode = (*cinfo->inputctl->consume_input) (cinfo); 54 if (retcode == JPEG_SUSPENDED) 55 return NULL; 56 if (retcode == JPEG_REACHED_EOI) 57 break; 58 /* Advance progress counter if appropriate */ 59 if (cinfo->progress != NULL && 60 (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { 61 if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { 62 /* startup underestimated number of scans; ratchet up one scan */ 63 cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; 64 } 65 } 66 } 67 /* Set state so that jpeg_finish_decompress does the right thing */ 68 cinfo->global_state = DSTATE_STOPPING; 69 return cinfo->coef->coef_arrays; 70 } 71 72 73 /* 74 * Master selection of decompression modules for transcoding. 75 * This substitutes for jdmaster.c's initialization of the full decompressor. 76 */ 77 78 LOCAL void 79 transdecode_master_selection (j_decompress_ptr cinfo) 80 { 81 /* Entropy decoding: either Huffman or arithmetic coding. */ 82 if (cinfo->arith_code) { 83 ERREXIT(cinfo, JERR_ARITH_NOTIMPL); 84 } else { 85 if (cinfo->progressive_mode) { 86 #ifdef D_PROGRESSIVE_SUPPORTED 87 jinit_phuff_decoder(cinfo); 88 #else 89 ERREXIT(cinfo, JERR_NOT_COMPILED); 90 #endif 91 } else 92 jinit_huff_decoder(cinfo); 93 } 94 95 /* Always get a full-image coefficient buffer. */ 96 jinit_d_coef_controller(cinfo, TRUE); 97 98 /* We can now tell the memory manager to allocate virtual arrays. */ 99 (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); 100 101 /* Initialize input side of decompressor to consume first scan. */ 102 (*cinfo->inputctl->start_input_pass) (cinfo); 103 104 /* Initialize progress monitoring. */ 105 if (cinfo->progress != NULL) { 106 int nscans; 107 /* Estimate number of scans to set pass_limit. */ 108 if (cinfo->progressive_mode) { 109 /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ 110 nscans = 2 + 3 * cinfo->num_components; 111 } else if (cinfo->inputctl->has_multiple_scans) { 112 /* For a nonprogressive multiscan file, estimate 1 scan per component. */ 113 nscans = cinfo->num_components; 114 } else { 115 nscans = 1; 116 } 117 cinfo->progress->pass_counter = 0L; 118 cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; 119 cinfo->progress->completed_passes = 0; 120 cinfo->progress->total_passes = 1; 121 } 122 }