summaryrefslogtreecommitdiff
path: root/src/img_encoder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/img_encoder.cc')
-rw-r--r--src/img_encoder.cc126
1 files changed, 9 insertions, 117 deletions
diff --git a/src/img_encoder.cc b/src/img_encoder.cc
index 1e8f4a6..1516fc0 100644
--- a/src/img_encoder.cc
+++ b/src/img_encoder.cc
@@ -37,6 +37,8 @@
#include "debug.h"
+#include "jpeg_mem_dest.h"
+
// Use libdv
#include <libdv/dv.h>
#include <libdv/dv_types.h>
@@ -104,114 +106,6 @@ void ImgEncoder::encode(Frame *dvframe, int quality)
writeJPEGFile(quality, (JSAMPLE*)rgb, 720, 576);
}
-#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently ?? size */
-
-/* Expanded data destination object for stdio output */
-typedef struct {
- struct jpeg_destination_mgr pub; /* public fields */
-
- JOCTET * outbuff; /* target buffer */
- size_t * size;
-} mem_destination_mgr;
-
-typedef mem_destination_mgr * mem_dest_ptr;
-
-/*
- * Initialize destination --- called by jpeg_start_compress
- * before any data is actually written.
- */
-void init_destination (j_compress_ptr cinfo)
-{
- mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
-
- *dest->size = 0;
- dest->pub.next_output_byte = dest->outbuff;
- dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
-}
-
-/*
- * Terminate destination --- called by jpeg_finish_compress
- * after all data has been written. Usually needs to flush buffer.
- *
- * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
- * application must deal with any cleanup that should happen even
- * for error exit.
- */
-void term_destination (j_compress_ptr cinfo)
-{
- mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
- size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
-
- /* Write any data remaining in the buffer */
- if (datacount > 0) {
- dest->outbuff+=datacount;
- *dest->size+=datacount;
- }
-}
-
-/*
- * Empty the output buffer --- called whenever buffer fills up.
- *
- * In typical applications, this should write the entire output buffer
- * (ignoring the current state of next_output_byte & free_in_buffer),
- * reset the pointer & count to the start of the buffer, and return TRUE
- * indicating that the buffer has been dumped.
- *
- * In applications that need to be able to suspend compression due to output
- * overrun, a FALSE return indicates that the buffer cannot be emptied now.
- * In this situation, the compressor will return to its caller (possibly with
- * an indication that it has not accepted all the supplied scanlines). The
- * application should resume compression after it has made more room in the
- * output buffer. Note that there are substantial restrictions on the use of
- * suspension --- see the documentation.
- *
- * When suspending, the compressor will back up to a convenient restart point
- * (typically the start of the current MCU). next_output_byte & free_in_buffer
- * indicate where the restart point will be if the current call returns FALSE.
- * Data beyond this point will be regenerated after resumption, so do not
- * write it out when emptying the buffer externally.
- */
-boolean empty_output_buffer (j_compress_ptr cinfo)
-{
- mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
-
- dest->outbuff+=OUTPUT_BUF_SIZE;
- *dest->size+=OUTPUT_BUF_SIZE;
-
- dest->pub.next_output_byte = dest->outbuff;
- dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
-
- return TRUE;
-}
-
-/*
- * Prepare for output to a memory buffer.
- . The caller must have already allocated the buffer, and is responsible
- * for closing it after finishing compression.
- */
-void jpeg_mem_dest (j_compress_ptr cinfo, char * outbuff, size_t * size)
-{
- mem_dest_ptr dest;
-
- /* The destination object is made permanent so that multiple JPEG images
- * can be written to the same file without re-executing jpeg_stdio_dest.
- * This makes it dangerous to use this manager and a different destination
- * manager serially with the same JPEG object, because their private object
- * sizes may be different. Caveat programmer.
- */
- 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(mem_destination_mgr));
- }
-
- dest = (mem_dest_ptr) cinfo->dest;
- dest->pub.init_destination = init_destination;
- dest->pub.empty_output_buffer = empty_output_buffer;
- dest->pub.term_destination = term_destination;
- dest->outbuff = (JOCTET *)outbuff;
- dest->size = (size_t *)size;
-}
void ImgEncoder::writeJPEGFile(int quality, JSAMPLE * image_buffer, int image_width, int image_height)
{
@@ -223,29 +117,27 @@ void ImgEncoder::writeJPEGFile(int quality, JSAMPLE * image_buffer, int image_wi
JSAMPROW row_pointer[1]; // pointer to JSAMPLE row[s]
int row_stride; // physical row width in image buffer
- // Step 1: allocate and initialize JPEG compression object
+ // Allocate and initialize JPEG compression object
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
- // Step 2: specify data destination (eg, a file)
- //jpeg_stdio_dest(&cinfo, file->getFP());
+ // Specify data destination (see jpeg_mem_dest)
jpeg_mem_dest(&cinfo, jpeg_output_buffer, &buffersize);
- // Step 3: set parameters for compression
+ // Set compression parameters
cinfo.image_width = image_width; // image width and height, in pixels
cinfo.image_height = image_height;
cinfo.input_components = 3; // # of color components per pixel
-
cinfo.in_color_space = JCS_RGB; // colorspace of input image
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE); // limit to baseline-JPEG values
- // Step 4: Start compressor
+ // Start compressor
jpeg_start_compress(&cinfo, TRUE);
- // Step 5: while (scan lines remain to be written)
+ // While (scan lines remain to be written)
row_stride = image_width * 3; // JSAMPLEs per row in image_buffer
while (cinfo.next_scanline < cinfo.image_height) {
@@ -253,10 +145,10 @@ void ImgEncoder::writeJPEGFile(int quality, JSAMPLE * image_buffer, int image_wi
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
- // Step 6: Finish compression
+ // Finish compression
jpeg_finish_compress(&cinfo);
- // Step 7: release JPEG compression object
+ // Release JPEG compression object
jpeg_destroy_compress(&cinfo);
info->info("JPEG buffersize: %d", buffersize);