19f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 29f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * jdatadst.c 39f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 49f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Copyright (C) 1994-1996, Thomas G. Lane. 59f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This file is part of the Independent JPEG Group's software. 69f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * For conditions of distribution and use, see the accompanying README file. 79f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 89f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This file contains compression data destination routines for the case of 99f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * emitting JPEG data to a file (or any stdio stream). While these routines 109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * are sufficient for most applications, some will want to use a different 119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * destination manager. 129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * IMPORTANT: we assume that fwrite() will correctly transcribe an array of 139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * JOCTETs into 8-bit-wide elements on external storage. If char is wider 149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * than 8 bits on your machine, you may need to do some tweaking. 159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ 189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "jinclude.h" 199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "jpeglib.h" 209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "jerror.h" 219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Expanded data destination object for stdio output */ 249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef struct { 269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project struct jpeg_destination_mgr pub; /* public fields */ 279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project FILE * outfile; /* target stream */ 299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JOCTET * buffer; /* start of buffer */ 309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} my_destination_mgr; 319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef my_destination_mgr * my_dest_ptr; 339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ 359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Initialize destination --- called by jpeg_start_compress 399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * before any data is actually written. 409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectinit_destination (j_compress_ptr cinfo) 449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_dest_ptr dest = (my_dest_ptr) cinfo->dest; 469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Allocate the output buffer --- it will be released when done with image */ 489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dest->buffer = (JOCTET *) 499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); 519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dest->pub.next_output_byte = dest->buffer; 539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; 549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Empty the output buffer --- called whenever buffer fills up. 599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * In typical applications, this should write the entire output buffer 619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * (ignoring the current state of next_output_byte & free_in_buffer), 629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * reset the pointer & count to the start of the buffer, and return TRUE 639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * indicating that the buffer has been dumped. 649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * In applications that need to be able to suspend compression due to output 669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * overrun, a FALSE return indicates that the buffer cannot be emptied now. 679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * In this situation, the compressor will return to its caller (possibly with 689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * an indication that it has not accepted all the supplied scanlines). The 699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * application should resume compression after it has made more room in the 709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * output buffer. Note that there are substantial restrictions on the use of 719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * suspension --- see the documentation. 729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * When suspending, the compressor will back up to a convenient restart point 749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * (typically the start of the current MCU). next_output_byte & free_in_buffer 759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * indicate where the restart point will be if the current call returns FALSE. 769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Data beyond this point will be regenerated after resumption, so do not 779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * write it out when emptying the buffer externally. 789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(boolean) 819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectempty_output_buffer (j_compress_ptr cinfo) 829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_dest_ptr dest = (my_dest_ptr) cinfo->dest; 849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) != 869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (size_t) OUTPUT_BUF_SIZE) 879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ERREXIT(cinfo, JERR_FILE_WRITE); 889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dest->pub.next_output_byte = dest->buffer; 909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; 919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project return TRUE; 939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Terminate destination --- called by jpeg_finish_compress 989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * after all data has been written. Usually needs to flush buffer. 999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 1009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding 1019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * application must deal with any cleanup that should happen even 1029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * for error exit. 1039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 1049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 1069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectterm_destination (j_compress_ptr cinfo) 1079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 1089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_dest_ptr dest = (my_dest_ptr) cinfo->dest; 1099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; 1109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Write any data remaining in the buffer */ 1129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (datacount > 0) { 1139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount) 1149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ERREXIT(cinfo, JERR_FILE_WRITE); 1159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 1169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project fflush(dest->outfile); 1179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Make sure we wrote the output file OK */ 1189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (ferror(dest->outfile)) 1199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ERREXIT(cinfo, JERR_FILE_WRITE); 1209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 1219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 1249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Prepare for output to a stdio stream. 1259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The caller must have already opened the stream, and is responsible 1269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * for closing it after finishing compression. 1279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 1289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectGLOBAL(void) 1309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectjpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile) 1319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 1329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_dest_ptr dest; 1339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* The destination object is made permanent so that multiple JPEG images 1359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * can be written to the same file without re-executing jpeg_stdio_dest. 1369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This makes it dangerous to use this manager and a different destination 1379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * manager serially with the same JPEG object, because their private object 1389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * sizes may be different. Caveat programmer. 1399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 1409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cinfo->dest == NULL) { /* first time for this JPEG object? */ 1419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cinfo->dest = (struct jpeg_destination_mgr *) 1429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 1439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project SIZEOF(my_destination_mgr)); 1449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 1459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dest = (my_dest_ptr) cinfo->dest; 1479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dest->pub.init_destination = init_destination; 1489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dest->pub.empty_output_buffer = empty_output_buffer; 1499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dest->pub.term_destination = term_destination; 1509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project dest->outfile = outfile; 1519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 152