// Convert a stream into a destination manager. public static void StreamToDestinationManager (ref jpeg_compress_struct cinfo, Stream stream) { // Allocate a state structure and store it in "cinfo". IntPtr buf = Marshal.AllocHGlobal(4096); StreamState state = new StreamState(); state.buf = buf; state.buffer = new byte [4096]; state.stream = stream; cinfo.client_data = (IntPtr)(GCHandle.Alloc(state)); // Create the managed version of "jpeg_destination_mgr". jpeg_destination_mgr mgr = new jpeg_destination_mgr(); mgr.next_output_byte = buf; mgr.free_in_buffer = (size_t)4096; mgr.init_destination = new init_destination_type(init_destination); mgr.empty_output_buffer = new empty_output_buffer_type(empty_output_buffer); mgr.term_destination = new term_destination_type(term_destination); // Convert it into the unmanaged version and store it. #if __CSCC__ IntPtr umgr = Marshal.AllocHGlobal (sizeof(jpeg_destination_mgr)); Marshal.StructureToPtr(mgr, umgr, false); cinfo.dest = (jpeg_destination_mgr *)umgr; #endif }
// Basic output routines. // // Note that we do not support suspension while writing a marker. // Therefore, an application using suspension must ensure that there is // enough buffer space for the initial markers (typ. 600-700 bytes) before // calling jpeg_start_compress, and enough space to write the trailing EOI // (a few bytes) before calling jpeg_finish_compress. Multipass compression // modes are not supported at all with suspension, so those two are the only // points where markers will be written. // Emit a byte static void emit_byte(jpeg_compress cinfo, int val) { jpeg_destination_mgr dest=cinfo.dest; dest.output_bytes[dest.next_output_byte++]=(byte)val; if(--dest.free_in_buffer==0) { if(!dest.empty_output_buffer(cinfo)) ERREXIT(cinfo, J_MESSAGE_CODE.JERR_CANT_SUSPEND); } }
// Outputting bytes to the file. // NB: these must be called only when actually outputting, // that is, entropy.gather_statistics == false. // Empty the output buffer; we do not support suspension in this module. static void dump_buffer(phuff_entropy_encoder entropy) { jpeg_destination_mgr dest = entropy.cinfo.dest; if (!dest.empty_output_buffer(entropy.cinfo)) { ERREXIT(entropy.cinfo, J_MESSAGE_CODE.JERR_CANT_SUSPEND); } // After a successful buffer dump, must reset buffer pointers entropy.output_bytes = dest.output_bytes; entropy.next_output_byte = dest.next_output_byte; entropy.free_in_buffer = dest.free_in_buffer; }
// Outputting bytes to the file // Empty the output buffer; return true if successful, false if must suspend static bool dump_buffer(ref working_state_ls state) { jpeg_destination_mgr dest = state.cinfo.dest; if (!dest.empty_output_buffer(state.cinfo)) { return(false); } // After a successful buffer dump, must reset buffer pointers state.output_bytes = dest.output_bytes; state.next_output_byte = dest.next_output_byte; state.free_in_buffer = dest.free_in_buffer; return(true); }