1f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 2f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * jcapistd.c 3f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 4f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Copyright (C) 1994-1996, Thomas G. Lane. 5f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This file is part of the Independent JPEG Group's software. 6f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * For conditions of distribution and use, see the accompanying README file. 7f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 8f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This file contains application interface code for the compression half 9f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * of the JPEG library. These are the "standard" API routines that are 10f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * used in the normal full-compression case. They are not used by a 11f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * transcoding-only application. Note that if an application links in 12f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * jpeg_start_compress, it will end up linking in the entire compressor. 13f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * We thus must separate this file from jcapimin.c to avoid linking the 14f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * whole compression library into a transcoder. 15f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 16f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 17f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#define JPEG_INTERNALS 18f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include "jinclude.h" 19f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include "jpeglib.h" 20f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 21f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 22f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 23f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Compression initialization. 24f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Before calling this, all parameters and a data destination must be set up. 25f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 26f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * We require a write_all_tables parameter as a failsafe check when writing 27f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * multiple datastreams from the same compression object. Since prior runs 28f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * will have left all the tables marked sent_table=TRUE, a subsequent run 29f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * would emit an abbreviated stream (no tables) by default. This may be what 30f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * is wanted, but for safety's sake it should not be the default behavior: 31f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * programmers should have to make a deliberate choice to emit abbreviated 32f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * images. Therefore the documentation and examples should encourage people 33f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * to pass write_all_tables=TRUE; then it will take active thought to do the 34f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * wrong thing. 35f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 36f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 37f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(void) 38f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgjpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables) 39f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 40f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (cinfo->global_state != CSTATE_START) 41f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 42f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 43f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (write_all_tables) 44f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */ 45f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 46f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* (Re)initialize error mgr and destination modules */ 47f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); 48f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*cinfo->dest->init_destination) (cinfo); 49f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Perform master selection of active modules */ 50f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org jinit_compress_master(cinfo); 51f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Set up for the first pass */ 52f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*cinfo->master->prepare_for_pass) (cinfo); 53f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Ready for application to drive first pass through jpeg_write_scanlines 54f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * or jpeg_write_raw_data. 55f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 56f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->next_scanline = 0; 57f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING); 58f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 59f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 60f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 61f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 62f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Write some scanlines of data to the JPEG compressor. 63f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 64f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * The return value will be the number of lines actually written. 65f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This should be less than the supplied num_lines only in case that 66f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * the data destination module has requested suspension of the compressor, 67f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * or if more than image_height scanlines are passed in. 68f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 69f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Note: we warn about excess calls to jpeg_write_scanlines() since 70f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * this likely signals an application programmer error. However, 71f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * excess scanlines passed in the last valid call are *silently* ignored, 72f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * so that the application need not adjust num_lines for end-of-image 73f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * when using a multiple-scanline buffer. 74f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 75f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 76f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(JDIMENSION) 77f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgjpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, 78f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JDIMENSION num_lines) 79f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 80f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JDIMENSION row_ctr, rows_left; 81f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 82f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (cinfo->global_state != CSTATE_SCANNING) 83f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 84f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (cinfo->next_scanline >= cinfo->image_height) 85f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org WARNMS(cinfo, JWRN_TOO_MUCH_DATA); 86f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 87f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Call progress monitor hook if present */ 88f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (cinfo->progress != NULL) { 89f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->progress->pass_counter = (long) cinfo->next_scanline; 90f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->progress->pass_limit = (long) cinfo->image_height; 91f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); 92f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 93f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 94f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Give master control module another chance if this is first call to 95f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * jpeg_write_scanlines. This lets output of the frame/scan headers be 96f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * delayed so that application can write COM, etc, markers between 97f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * jpeg_start_compress and jpeg_write_scanlines. 98f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 99f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (cinfo->master->call_pass_startup) 100f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*cinfo->master->pass_startup) (cinfo); 101f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 102f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Ignore any extra scanlines at bottom of image. */ 103f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org rows_left = cinfo->image_height - cinfo->next_scanline; 104f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (num_lines > rows_left) 105f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org num_lines = rows_left; 106f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 107f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org row_ctr = 0; 108f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines); 109f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->next_scanline += row_ctr; 110f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return row_ctr; 111f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 112f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 113f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 114f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 115f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Alternate entry point to write raw data. 116f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Processes exactly one iMCU row per call, unless suspended. 117f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 118f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 119f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(JDIMENSION) 120f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgjpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data, 121f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JDIMENSION num_lines) 122f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 123f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JDIMENSION lines_per_iMCU_row; 124f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 125f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (cinfo->global_state != CSTATE_RAW_OK) 126f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 127f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (cinfo->next_scanline >= cinfo->image_height) { 128f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org WARNMS(cinfo, JWRN_TOO_MUCH_DATA); 129f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return 0; 130f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 131f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 132f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Call progress monitor hook if present */ 133f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (cinfo->progress != NULL) { 134f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->progress->pass_counter = (long) cinfo->next_scanline; 135f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->progress->pass_limit = (long) cinfo->image_height; 136f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); 137f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 138f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 139f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Give master control module another chance if this is first call to 140f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * jpeg_write_raw_data. This lets output of the frame/scan headers be 141f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * delayed so that application can write COM, etc, markers between 142f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * jpeg_start_compress and jpeg_write_raw_data. 143f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 144f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (cinfo->master->call_pass_startup) 145f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*cinfo->master->pass_startup) (cinfo); 146f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 147f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Verify that at least one iMCU row has been passed. */ 148f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE; 149f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (num_lines < lines_per_iMCU_row) 150f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_BUFFER_SIZE); 151f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 152f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Directly compress the row. */ 153f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (! (*cinfo->coef->compress_data) (cinfo, data)) { 154f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* If compressor did not consume the whole row, suspend processing. */ 155f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return 0; 156f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 157f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 158f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* OK, we processed one iMCU row. */ 159f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->next_scanline += lines_per_iMCU_row; 160f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return lines_per_iMCU_row; 161f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 162