00001 /* 00002 * jmemdst.c 00003 * 00004 * Copyright (C) 1994-1996, Toshihiro Matsui, Electrotechnical Laboratory 00005 */ 00006 00007 #include <stdio.h> 00008 #include <jpeglib.h> 00009 #include <jerror.h> 00010 00011 /* Expanded data destination object for stdio output */ 00012 00013 typedef struct { 00014 struct jpeg_destination_mgr pub; /* public fields */ 00015 JOCTET * buffer; /* start of buffer */ 00016 long * data_count_ptr; 00017 } my_destination_mgr; 00018 00019 typedef my_destination_mgr * my_dest_ptr; 00020 00021 /* 00022 * Initialize destination --- called by jpeg_start_compress 00023 * before any data is actually written. 00024 */ 00025 00026 00027 METHODDEF(void) 00028 init_destination (j_compress_ptr cinfo) 00029 { 00030 my_dest_ptr dest = (my_dest_ptr) cinfo->dest; 00031 00032 dest->pub.next_output_byte = dest->buffer; 00033 dest->pub.free_in_buffer = *dest->data_count_ptr; 00034 } 00035 00036 /* 00037 * Empty the output buffer --- called whenever buffer fills up. 00038 * 00039 * In typical applications, this should write the entire output buffer 00040 * (ignoring the current state of next_output_byte & free_in_buffer), 00041 * reset the pointer & count to the start of the buffer, and return TRUE 00042 * indicating that the buffer has been dumped. 00043 * 00044 * In applications that need to be able to suspend compression due to output 00045 * overrun, a FALSE return indicates that the buffer cannot be emptied now. 00046 * In this situation, the compressor will return to its caller (possibly with 00047 * an indication that it has not accepted all the supplied scanlines). The 00048 * application should resume compression after it has made more room in the 00049 * output buffer. Note that there are substantial restrictions on the use of 00050 * suspension --- see the documentation. 00051 * 00052 * When suspending, the compressor will back up to a convenient restart point 00053 * (typically the start of the current MCU). next_output_byte & free_in_buffer 00054 * indicate where the restart point will be if the current call returns FALSE. 00055 * Data beyond this point will be regenerated after resumption, so do not 00056 * write it out when emptying the buffer externally. 00057 */ 00058 00059 METHODDEF(boolean) 00060 empty_output_buffer (j_compress_ptr cinfo) 00061 { 00062 my_dest_ptr dest = (my_dest_ptr) cinfo->dest; 00063 00064 00065 fprintf(stderr, " : jpeg compression buffer overflow >%ld\n", 00066 *dest->data_count_ptr); 00067 00068 dest->pub.next_output_byte = dest->buffer; 00069 dest->pub.free_in_buffer = *dest->data_count_ptr; 00070 00071 return TRUE; 00072 } 00073 00074 /* 00075 * Terminate destination --- called by jpeg_finish_compress 00076 * after all data has been written. Usually needs to flush buffer. 00077 * 00078 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding 00079 * application must deal with any cleanup that should happen even 00080 * for error exit. 00081 */ 00082 00083 METHODDEF(void) 00084 term_destination (j_compress_ptr cinfo) 00085 { 00086 my_dest_ptr dest = (my_dest_ptr) cinfo->dest; 00087 size_t datacount = *dest->data_count_ptr - dest->pub.free_in_buffer; 00088 00089 *dest->data_count_ptr = datacount; 00090 } 00091 00092 00093 GLOBAL(void) 00094 jpeg_memio_dest (j_compress_ptr cinfo, JOCTET *jpegimgbuf, long *size) 00095 { 00096 my_dest_ptr dest; 00097 00098 /* RGB image (provided by the main) is compressed into jpegimgbuf 00099 * and the size of the resulted JPEG data appears in the size. 00100 * The size should hold the maximum size of the jpegimgbuf at the beginning. 00101 */ 00102 00103 if (cinfo->dest == NULL) { /* first time for this JPEG object? */ 00104 cinfo->dest = (struct jpeg_destination_mgr *) 00105 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 00106 sizeof(my_destination_mgr)); 00107 } 00108 00109 dest = (my_dest_ptr) cinfo->dest; 00110 dest->pub.init_destination = init_destination; 00111 dest->pub.empty_output_buffer = empty_output_buffer; 00112 dest->pub.term_destination = term_destination; 00113 dest->buffer = jpegimgbuf; 00114 dest->data_count_ptr = size; 00115 }