Пример #1
0
        // Decompression startup: read start of JPEG datastream to see what's there.
        // Need only initialize JPEG object and supply a data source before calling.
        //
        // This routine will read as far as the first SOS marker (ie, actual start of
        // compressed data), and will save all tables and parameters in the JPEG
        // object. It will also initialize the decompression parameters to default
        // values, and finally return JPEG_HEADER_OK. On return, the application may
        // adjust the decompression parameters and then call jpeg_start_decompress.
        // (Or, if the application only wanted to determine the image parameters,
        // the data need not be decompressed. In that case, call jpeg_abort or
        // jpeg_destroy to release any temporary space.)
        // If an abbreviated (tables only) datastream is presented, the routine will
        // return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then
        // re-use the JPEG object to read the abbreviated image datastream(s).
        // It is unnecessary (but OK) to call jpeg_abort in this case.
        // The JPEG_SUSPENDED return code only occurs if the data source module
        // requests suspension of the decompressor. In this case the application
        // should load more source data and then re-call jpeg_read_header to resume
        // processing.
        // If a non-suspending data source is used and require_image is true, then the
        // return code need not be inspected since only JPEG_HEADER_OK is possible.
        //
        // This routine is now just a front end to jpeg_consume_input, with some
        // extra error checking.
        public static CONSUME_INPUT jpeg_read_header(jpeg_decompress cinfo, bool require_image)
        {
            if (cinfo.global_state != STATE.DSTART && cinfo.global_state != STATE.DINHEADER)
            {
                ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_BAD_STATE, cinfo.global_state);
            }

            CONSUME_INPUT retcode = jpeg_consume_input(cinfo);

            switch (retcode)
            {
            case CONSUME_INPUT.JPEG_REACHED_SOS: return(CONSUME_INPUT.JPEG_HEADER_OK);

            case CONSUME_INPUT.JPEG_REACHED_EOI:
                if (require_image)
                {
                    ERREXIT(cinfo, J_MESSAGE_CODE.JERR_NO_IMAGE);                                       // Complain if application wanted an image
                }
                // Reset to start state; it would be safer to require the application to
                // call jpeg_abort, but we can't change it now for compatibility reasons.
                // A side effect is to free any temporary memory (there shouldn't be any).
                jpeg_abort(cinfo);                         // sets state=DSTART
                return(CONSUME_INPUT.JPEG_HEADER_TABLES_ONLY);
            }

            return(retcode);
        }
Пример #2
0
        // Consume data in advance of what the decompressor requires.
        // This can be called at any time once the decompressor object has
        // been created and a data source has been set up.
        //
        // This routine is essentially a state machine that handles a couple
        // of critical state-transition actions, namely initial setup and
        // transition from header scanning to ready-for-start_decompress.
        // All the actual input is done via the input controller's consume_input
        // method.
        public static CONSUME_INPUT jpeg_consume_input(jpeg_decompress cinfo)
        {
            CONSUME_INPUT retcode = CONSUME_INPUT.JPEG_SUSPENDED;

            // NB: every possible DSTATE value should be listed in this switch
            switch (cinfo.global_state)
            {
            case STATE.DSTART:
                // Start-of-datastream actions: reset appropriate modules
                cinfo.inputctl.reset_input_controller(cinfo);
                // Initialize application's data source module
                cinfo.src.init_source(cinfo);
                cinfo.global_state = STATE.DINHEADER;
                goto case STATE.DINHEADER;                         // FALLTHROUGH

            case STATE.DINHEADER:
                retcode = cinfo.inputctl.consume_input(cinfo);
                if (retcode == CONSUME_INPUT.JPEG_REACHED_SOS)
                {                         // Found SOS, prepare to decompress
                    // Set up default parameters based on header data
                    default_decompress_parms(cinfo);

                    // Set global state: ready for start_decompress
                    cinfo.global_state = STATE.DREADY;
                }
                break;

            case STATE.DREADY: retcode = CONSUME_INPUT.JPEG_REACHED_SOS; break;                  // Can't advance past first SOS until start_decompress is called

            case STATE.DPRELOAD:
            case STATE.DPRESCAN:
            case STATE.DSCANNING:
            case STATE.DRAW_OK:
            case STATE.DBUFIMAGE:
            case STATE.DBUFPOST:
            case STATE.DSTOPPING: retcode = cinfo.inputctl.consume_input(cinfo); break;

            default: ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_BAD_STATE, cinfo.global_state); break;
            }
            return(retcode);
        }
Пример #3
0
        // Decompression initialization.
        // jpeg_read_header must be completed before calling this.
        //
        // If a multipass operating mode was selected, this will do all but the
        // last pass, and thus may take a great deal of time.
        //
        // Returns false if suspended. The return value need be inspected only if
        // a suspending data source is used.
        public static bool jpeg_start_decompress(jpeg_decompress cinfo)
        {
            if (cinfo.global_state == STATE.DREADY)
            {
                // First call: initialize master control, select active modules
                jinit_master_decompress(cinfo);
                if (cinfo.buffered_image)
                {
                    // No more work here; expecting jpeg_start_output next
                    cinfo.global_state = STATE.DBUFIMAGE;
                    return(true);
                }
                cinfo.global_state = STATE.DPRELOAD;
            }

            if (cinfo.global_state == STATE.DPRELOAD)
            {
                // If file has multiple scans, absorb them all into the coef buffer
                if (cinfo.inputctl.has_multiple_scans)
                {
#if D_MULTISCAN_FILES_SUPPORTED
                    for (; ;)
                    {
                        // Call progress monitor hook if present
                        if (cinfo.progress != null)
                        {
                            cinfo.progress.progress_monitor(cinfo);
                        }
                        // Absorb some more input
                        CONSUME_INPUT retcode = cinfo.inputctl.consume_input(cinfo);
                        if (retcode == CONSUME_INPUT.JPEG_SUSPENDED)
                        {
                            return(false);
                        }
                        if (retcode == CONSUME_INPUT.JPEG_REACHED_EOI)
                        {
                            break;
                        }

                        // Advance progress counter if appropriate
                        if (cinfo.progress != null && (retcode == CONSUME_INPUT.JPEG_ROW_COMPLETED || retcode == CONSUME_INPUT.JPEG_REACHED_SOS))
                        {
                            if (++cinfo.progress.pass_counter >= cinfo.progress.pass_limit)
                            {
                                // jdmaster underestimated number of scans; ratchet up one scan
                                cinfo.progress.pass_limit += (int)cinfo.total_iMCU_rows;
                            }
                        }
                    }
#else
                    ERREXIT(cinfo, J_MESSAGE_CODE.JERR_NOT_COMPILED);
#endif // D_MULTISCAN_FILES_SUPPORTED
                }
                cinfo.output_scan_number = cinfo.input_scan_number;
            }
            else if (cinfo.global_state != STATE.DPRESCAN)
            {
                ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_BAD_STATE, cinfo.global_state);
            }

            // Perform any dummy output passes, and set up for the final pass
            return(output_pass_setup(cinfo));
        }
Пример #4
0
        // Read JPEG markers before, between, or after compressed-data scans.
        // Change state as necessary when a new scan is reached.
        // Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
        //
        // The consume_input method pointer points either here or to the
        // coefficient controller's consume_data routine, depending on whether
        // we are reading a compressed data segment or inter-segment markers.
        //
        // Note: This function should NOT return a pseudo SOS marker (with zero
        // component number) to the caller.  A pseudo marker received by
        // read_markers is processed and then skipped for other markers.
        static CONSUME_INPUT consume_markers_d_input(jpeg_decompress cinfo)
        {
            my_input_controller inputctl = (my_input_controller)cinfo.inputctl;

            if (inputctl.eoi_reached)
            {
                return(CONSUME_INPUT.JPEG_REACHED_EOI);                                 // After hitting EOI, read no further
            }
            CONSUME_INPUT val = cinfo.marker.read_markers(cinfo);

            for (; ;)             // Loop to pass pseudo SOS marker
            {
                switch (val)
                {
                case CONSUME_INPUT.JPEG_REACHED_SOS: // Found SOS
                    if (inputctl.inheaders != 0)
                    {                                // 1st SOS
                        if (inputctl.inheaders == 1)
                        {
                            initial_setup_d_input(cinfo);

                            // Initialize the decompression codec. We need to do this here so that
                            // any codec-specific fields and function pointers are available to
                            // the rest of the library.
                            jinit_d_codec(cinfo);
                        }

                        if (cinfo.comps_in_scan == 0)                              // pseudo SOS marker
                        {
                            inputctl.inheaders = 2;
                            break;
                        }

                        inputctl.inheaders = 0;
                        // Note: start_input_pass must be called by jdmaster.cs
                        // before any more input can be consumed. jdapimin.cs is
                        // responsible for enforcing this sequencing.
                    }
                    else
                    {                             // 2nd or later SOS marker
                        if (!inputctl.has_multiple_scans)
                        {
                            ERREXIT(cinfo, J_MESSAGE_CODE.JERR_EOI_EXPECTED);      // Oops, I wasn't expecting this!
                        }
                        if (cinfo.comps_in_scan == 0)                              // unexpected pseudo SOS marker
                        {
                            break;
                        }
                        start_input_pass_d_input(cinfo);
                    }
                    return(val);

                case CONSUME_INPUT.JPEG_REACHED_EOI:                         // Found EOI
                    inputctl.eoi_reached = true;
                    if (inputctl.inheaders != 0)
                    {                                   // Tables-only datastream, apparently
                        if (cinfo.marker.saw_SOF)
                        {
                            ERREXIT(cinfo, J_MESSAGE_CODE.JERR_SOF_NO_SOS);
                        }
                    }
                    else
                    {
                        // Prevent infinite loop in coef ctlr's decompress_data routine
                        // if user set output_scan_number larger than number of scans.
                        if (cinfo.output_scan_number > cinfo.input_scan_number)
                        {
                            cinfo.output_scan_number = cinfo.input_scan_number;
                        }
                    }
                    return(val);

                case CONSUME_INPUT.JPEG_SUSPENDED:
                    return(val);
                }
            }
        }