Mercurial > hg > minimon
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 1:111d4bbce605 | 2:bac8ed8d6eb9 |
|---|---|
| 1 #include <stdlib.h> | |
| 2 #include <stdio.h> | |
| 3 #include <string.h> | |
| 4 #include "jpeglib.h" | |
| 5 #include "jerror.h" | |
| 6 | |
| 7 typedef struct { | |
| 8 struct jpeg_destination_mgr pub; /* public fields */ | |
| 9 | |
| 10 unsigned char ** outbuffer; /* target buffer */ | |
| 11 unsigned long * outsize; | |
| 12 unsigned char * newbuffer; /* newly allocated buffer */ | |
| 13 JOCTET * buffer; /* start of buffer */ | |
| 14 size_t bufsize; | |
| 15 } mem_dest_mgr; | |
| 16 | |
| 17 typedef mem_dest_mgr * mem_dest_mgr_ptr; | |
| 18 | |
| 19 void init_mem_destination (j_compress_ptr cinfo) { | |
| 20 } | |
| 21 | |
| 22 boolean empty_mem_output_buffer(j_compress_ptr cinfo) { | |
| 23 size_t nextsize; | |
| 24 JOCTET * nextbuffer; | |
| 25 mem_dest_mgr_ptr dest = (mem_dest_mgr_ptr) cinfo->dest; | |
| 26 | |
| 27 /* Try to allocate new buffer with double size */ | |
| 28 nextsize = dest->bufsize * 2; | |
| 29 nextbuffer = malloc(nextsize); | |
| 30 | |
| 31 if (nextbuffer == NULL) | |
| 32 ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); | |
| 33 | |
| 34 memcpy(nextbuffer, dest->buffer, dest->bufsize); | |
| 35 | |
| 36 if (dest->newbuffer != NULL) | |
| 37 free(dest->newbuffer); | |
| 38 | |
| 39 dest->newbuffer = nextbuffer; | |
| 40 | |
| 41 dest->pub.next_output_byte = nextbuffer + dest->bufsize; | |
| 42 dest->pub.free_in_buffer = dest->bufsize; | |
| 43 | |
| 44 dest->buffer = nextbuffer; | |
| 45 dest->bufsize = nextsize; | |
| 46 | |
| 47 return TRUE; | |
| 48 } | |
| 49 | |
| 50 void term_mem_destination(j_compress_ptr cinfo) { | |
| 51 mem_dest_mgr_ptr dest = (mem_dest_mgr_ptr) cinfo->dest; | |
| 52 | |
| 53 *dest->outbuffer = dest->buffer; | |
| 54 *dest->outsize = dest->bufsize - dest->pub.free_in_buffer; | |
| 55 } | |
| 56 | |
| 57 void jpeg_mem_dest(j_compress_ptr cinfo, unsigned char ** outbuffer, unsigned long * outsize) { | |
| 58 mem_dest_mgr_ptr dest; | |
| 59 | |
| 60 if (outbuffer == NULL || outsize == NULL) /* sanity check */ | |
| 61 ERREXIT(cinfo, JERR_BUFFER_SIZE); | |
| 62 | |
| 63 /* The destination object is made permanent so that multiple JPEG images | |
| 64 * can be written to the same buffer without re-executing jpeg_mem_dest. | |
| 65 */ | |
| 66 if (cinfo->dest == NULL) { /* first time for this JPEG object? */ | |
| 67 cinfo->dest = (struct jpeg_destination_mgr *) | |
| 68 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, | |
| 69 sizeof(mem_dest_mgr)); | |
| 70 } | |
| 71 | |
| 72 dest = (mem_dest_mgr_ptr) cinfo->dest; | |
| 73 dest->pub.init_destination = init_mem_destination; | |
| 74 dest->pub.empty_output_buffer = empty_mem_output_buffer; | |
| 75 dest->pub.term_destination = term_mem_destination; | |
| 76 dest->outbuffer = outbuffer; | |
| 77 dest->outsize = outsize; | |
| 78 dest->newbuffer = NULL; | |
| 79 | |
| 80 if (*outbuffer == NULL || *outsize == 0) { | |
| 81 /* Allocate initial buffer */ | |
| 82 dest->newbuffer = *outbuffer = malloc(65536); | |
| 83 if (dest->newbuffer == NULL) | |
| 84 ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); | |
| 85 *outsize = 65536; | |
| 86 } | |
| 87 | |
| 88 dest->pub.next_output_byte = dest->buffer = *outbuffer; | |
| 89 dest->pub.free_in_buffer = dest->bufsize = *outsize; | |
| 90 } | |
| 91 | |
| 92 | |
| 93 int build_jpg(JSAMPLE *image_buf, int width, int height) { | |
| 94 int scanline; | |
| 95 struct jpeg_compress_struct cinfo; | |
| 96 struct jpeg_error_mgr jerr; | |
| 97 | |
| 98 cinfo.err = jpeg_std_error(&jerr); | |
| 99 jpeg_create_compress(&cinfo); | |
| 100 | |
| 101 unsigned long out_size = 1<<20; | |
| 102 unsigned char *out_buf = NULL; | |
| 103 jpeg_mem_dest(&cinfo, &out_buf, &out_size); | |
| 104 | |
| 105 cinfo.image_width = width; | |
| 106 cinfo.image_height = height; | |
| 107 cinfo.input_components = 3; | |
| 108 cinfo.in_color_space = JCS_RGB; | |
| 109 jpeg_set_defaults(&cinfo); | |
| 110 | |
| 111 jpeg_start_compress(&cinfo, TRUE); | |
| 112 | |
| 113 for (scanline = 0; scanline < height; scanline++) { | |
| 114 JSAMPROW *row_ptr; | |
| 115 row_ptr = &image_buf[scanline * width]; | |
| 116 jpeg_write_scanlines(&cinfo, row_ptr, 1); | |
| 117 } | |
| 118 | |
| 119 jpeg_finish_compress(&cinfo); | |
| 120 | |
| 121 jpeg_destroy_compress(&cinfo); | |
| 122 | |
| 123 return 0; | |
| 124 } |
