diff jpg.c @ 2:bac8ed8d6eb9

add jpeg coding and test stuff
author Peter Meerwald <pmeerw@pmeerw.net>
date Sun, 08 May 2011 18:22:22 +0200
parents
children e8957085fe8a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jpg.c	Sun May 08 18:22:22 2011 +0200
@@ -0,0 +1,124 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "jpeglib.h"
+#include "jerror.h"
+
+typedef struct {
+  struct jpeg_destination_mgr pub; /* public fields */
+
+  unsigned char ** outbuffer;	/* target buffer */
+  unsigned long * outsize;
+  unsigned char * newbuffer;	/* newly allocated buffer */
+  JOCTET * buffer;		/* start of buffer */
+  size_t bufsize;
+} mem_dest_mgr;
+
+typedef mem_dest_mgr * mem_dest_mgr_ptr;
+
+void init_mem_destination (j_compress_ptr cinfo) {
+}
+
+boolean empty_mem_output_buffer(j_compress_ptr cinfo) {
+  size_t nextsize;
+  JOCTET * nextbuffer;
+  mem_dest_mgr_ptr dest = (mem_dest_mgr_ptr) cinfo->dest;
+
+  /* Try to allocate new buffer with double size */
+  nextsize = dest->bufsize * 2;
+  nextbuffer = malloc(nextsize);
+
+  if (nextbuffer == NULL)
+    ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
+
+  memcpy(nextbuffer, dest->buffer, dest->bufsize);
+
+  if (dest->newbuffer != NULL)
+    free(dest->newbuffer);
+
+  dest->newbuffer = nextbuffer;
+
+  dest->pub.next_output_byte = nextbuffer + dest->bufsize;
+  dest->pub.free_in_buffer = dest->bufsize;
+
+  dest->buffer = nextbuffer;
+  dest->bufsize = nextsize;
+
+  return TRUE;
+}
+
+void term_mem_destination(j_compress_ptr cinfo) {
+  mem_dest_mgr_ptr dest = (mem_dest_mgr_ptr) cinfo->dest;
+
+  *dest->outbuffer = dest->buffer;
+  *dest->outsize = dest->bufsize - dest->pub.free_in_buffer;
+}
+
+void jpeg_mem_dest(j_compress_ptr cinfo, unsigned char ** outbuffer, unsigned long * outsize) {
+  mem_dest_mgr_ptr dest;
+
+  if (outbuffer == NULL || outsize == NULL)	/* sanity check */
+    ERREXIT(cinfo, JERR_BUFFER_SIZE);
+
+  /* The destination object is made permanent so that multiple JPEG images
+   * can be written to the same buffer without re-executing jpeg_mem_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(mem_dest_mgr));
+  }
+
+  dest = (mem_dest_mgr_ptr) cinfo->dest;
+  dest->pub.init_destination = init_mem_destination;
+  dest->pub.empty_output_buffer = empty_mem_output_buffer;
+  dest->pub.term_destination = term_mem_destination;
+  dest->outbuffer = outbuffer;
+  dest->outsize = outsize;
+  dest->newbuffer = NULL;
+
+  if (*outbuffer == NULL || *outsize == 0) {
+    /* Allocate initial buffer */
+    dest->newbuffer = *outbuffer = malloc(65536);
+    if (dest->newbuffer == NULL)
+      ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
+    *outsize = 65536;
+  }
+
+  dest->pub.next_output_byte = dest->buffer = *outbuffer;
+  dest->pub.free_in_buffer = dest->bufsize = *outsize;
+}
+
+
+int build_jpg(JSAMPLE *image_buf, int width, int height) {
+  int scanline;
+  struct jpeg_compress_struct cinfo;
+  struct jpeg_error_mgr jerr;
+  
+  cinfo.err = jpeg_std_error(&jerr);
+  jpeg_create_compress(&cinfo);
+
+  unsigned long out_size = 1<<20;
+  unsigned char *out_buf = NULL;
+  jpeg_mem_dest(&cinfo, &out_buf, &out_size);
+
+  cinfo.image_width = width;
+  cinfo.image_height = height;
+  cinfo.input_components = 3;
+  cinfo.in_color_space = JCS_RGB;
+  jpeg_set_defaults(&cinfo);
+
+  jpeg_start_compress(&cinfo, TRUE);
+
+  for (scanline = 0; scanline < height; scanline++) {
+    JSAMPROW *row_ptr;
+    row_ptr = &image_buf[scanline * width];
+    jpeg_write_scanlines(&cinfo, row_ptr, 1);
+  }
+
+  jpeg_finish_compress(&cinfo);
+
+  jpeg_destroy_compress(&cinfo);
+
+  return 0;
+}

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.