/* * jmemdest.cpp * * This file contains a compression data destination which takes a * memory region as destination. * The only thing these routines really do is tell the library where the * data is on construction (jpeg_mem_dest()). Everything else is there * for error checking purposes. * Adapted from jdatasrc.c 9/96 by Ulrich von Zadow. * Adapted from jmemsrc.c 3.6.99 by MS */ /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ #include "pldatasink.h" #include #include "jpeglib.h" #include "jerror.h" #include "jmemdest.h" #include #define JPEG_WORK_BUFFER_SIZE 8192 // 8KB Work Buffer typedef struct { struct jpeg_destination_mgr pub; // public fields PLDataSink * pDataSink ; // Data Sink JOCTET * buffer; } datasink_dest_mgr; /* * Initialize destination * before any data is actually written. */ METHODDEF(void) jpeg_mem_dest_init (j_compress_ptr cinfo) { /* Set up data pointer */ datasink_dest_mgr * dest = (datasink_dest_mgr * ) cinfo->dest; /* Allocate the output buffer --- it will be released when done with image */ dest->buffer = (JOCTET *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, JPEG_WORK_BUFFER_SIZE); dest->pub.next_output_byte = dest->buffer; dest->pub.free_in_buffer = JPEG_WORK_BUFFER_SIZE; } /* * Flush the output buffer --- called whenever buffer is full. * * If this procedure gets called, we have a buffer overrun condition - * We now send the data to the DataSink */ METHODDEF(boolean) jpeg_mem_dest_empty_output_buffer (j_compress_ptr cinfo) { datasink_dest_mgr * dest = (datasink_dest_mgr *) cinfo->dest; if (dest->pDataSink->WriteNBytes(JPEG_WORK_BUFFER_SIZE, dest->buffer) != (size_t) JPEG_WORK_BUFFER_SIZE) ERREXIT(cinfo, JERR_FILE_WRITE); dest->pub.next_output_byte = dest->buffer; dest->pub.free_in_buffer = JPEG_WORK_BUFFER_SIZE; return true; } /* * Terminate source --- called by jpeg_finish_compress * after all data has been written. * * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding * application must deal with any cleanup that should happen even * for error exit. */ METHODDEF(void) jpeg_mem_dest_term (j_compress_ptr cinfo) { datasink_dest_mgr * dest = (datasink_dest_mgr *) cinfo->dest; size_t datacount = JPEG_WORK_BUFFER_SIZE - dest->pub.free_in_buffer; /* Write any data remaining in the buffer */ if (datacount > 0) { if (dest->pDataSink->WriteNBytes(datacount, dest->buffer) != datacount) ERREXIT(cinfo, JERR_FILE_WRITE); } } /* * Prepare for ouput. This routine tells the jpeg library where to find * the output buffer & sets up the function pointers the library needs. * */ GLOBAL(void) jpeg_mem_dest( j_compress_ptr cinfo, JOCTET * pData, int FileSize, PLDataSink * pDataSink ) { datasink_dest_mgr * dest; if (cinfo->dest == NULL) { /* first time for this JPEG object? */ cinfo->dest = (struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(datasink_dest_mgr)); } dest = (datasink_dest_mgr *) cinfo->dest; dest->pub.init_destination = jpeg_mem_dest_init; dest->pub.empty_output_buffer = jpeg_mem_dest_empty_output_buffer; dest->pub.term_destination = jpeg_mem_dest_term; dest->pDataSink = pDataSink; }