From 6aed88dfdec745e702a15f44ea058a21342729a0 Mon Sep 17 00:00:00 2001 From: kramm Date: Sat, 5 Apr 2008 07:25:31 +0000 Subject: [PATCH] wrapper for libjpeg --- lib/jpeg.c | 398 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/jpeg.h | 20 +++ 2 files changed, 418 insertions(+) create mode 100644 lib/jpeg.c create mode 100644 lib/jpeg.h diff --git a/lib/jpeg.c b/lib/jpeg.c new file mode 100644 index 0000000..d58215c --- /dev/null +++ b/lib/jpeg.c @@ -0,0 +1,398 @@ +#include +#include +#include +#include "jpeg.h" +#include "../config.h" + +#ifdef HAVE_JPEGLIB +#define HAVE_BOOLEAN +#include + +#define OUTBUFFER_SIZE 0x8000 + +static FILE*fi; +static JOCTET * buffer; +static unsigned char*dest; +static int len; +static int destlen; +static unsigned char*data; +static int pos; +static int size; + +static void file_init_destination(j_compress_ptr cinfo) +{ + struct jpeg_destination_mgr*dmgr = + (struct jpeg_destination_mgr*)(cinfo->dest); + buffer = (JOCTET*)malloc(OUTBUFFER_SIZE); + if(!buffer) { + perror("malloc"); + printf("Out of memory!\n"); + exit(1); + } + dmgr->next_output_byte = buffer; + dmgr->free_in_buffer = OUTBUFFER_SIZE; +} + +static boolean file_empty_output_buffer(j_compress_ptr cinfo) +{ + struct jpeg_destination_mgr*dmgr = + (struct jpeg_destination_mgr*)(cinfo->dest); + if(fi) + fwrite(buffer, OUTBUFFER_SIZE, 1, fi); + dmgr->next_output_byte = buffer; + dmgr->free_in_buffer = OUTBUFFER_SIZE; + return 1; +} + +static void file_term_destination(j_compress_ptr cinfo) +{ struct jpeg_destination_mgr*dmgr = + (struct jpeg_destination_mgr*)(cinfo->dest); + if(fi) + fwrite(buffer, OUTBUFFER_SIZE-dmgr->free_in_buffer, 1, fi); + free(buffer); + buffer = 0; + dmgr->free_in_buffer = 0; +} + +static void mem_init_destination(j_compress_ptr cinfo) +{ + struct jpeg_destination_mgr*dmgr = + (struct jpeg_destination_mgr*)(cinfo->dest); + dmgr->next_output_byte = dest; + dmgr->free_in_buffer = destlen; +} + +static boolean mem_empty_output_buffer(j_compress_ptr cinfo) +{ + printf("jpeg mem overflow!\n"); + exit(1); +} + +static void mem_term_destination(j_compress_ptr cinfo) +{ + struct jpeg_destination_mgr*dmgr = + (struct jpeg_destination_mgr*)(cinfo->dest); + len = destlen - dmgr->free_in_buffer; + dmgr->free_in_buffer = 0; +} + +int jpeg_save(unsigned char*data, int width, int height, int quality, const char*filename) +{ + struct jpeg_destination_mgr mgr; + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + int t; + + if(filename) + fi = fopen(filename, "wb"); + else + fi = 0; + + memset(&cinfo, 0, sizeof(cinfo)); + memset(&jerr, 0, sizeof(jerr)); + memset(&mgr, 0, sizeof(mgr)); + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + + mgr.init_destination = file_init_destination; + mgr.empty_output_buffer = file_empty_output_buffer; + mgr.term_destination = file_term_destination; + cinfo.dest = &mgr; + + // init compression + + cinfo.image_width = width; + cinfo.image_height = height; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo,quality,TRUE); + + //jpeg_write_tables(&cinfo); + //jpeg_suppress_tables(&cinfo, TRUE); + jpeg_start_compress(&cinfo, FALSE); + + for(t=0;tsrc; + mgr->next_input_byte = data; + mgr->bytes_in_buffer = size; + //printf("init %d\n", size - mgr->bytes_in_buffer); +} + +boolean mem_fill_input_buffer (j_decompress_ptr cinfo) +{ + struct jpeg_source_mgr* mgr = cinfo->src; + printf("fill %d\n", size - mgr->bytes_in_buffer); + return 0; +} + +void mem_skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + struct jpeg_source_mgr* mgr = cinfo->src; + printf("skip %d +%d\n", size - mgr->bytes_in_buffer, num_bytes); + if(num_bytes<=0) + return; + mgr->next_input_byte += num_bytes; + mgr->bytes_in_buffer -= num_bytes; +} + +boolean mem_resync_to_restart (j_decompress_ptr cinfo, int desired) +{ + struct jpeg_source_mgr* mgr = cinfo->src; + printf("resync %d\n", size - mgr->bytes_in_buffer); + mgr->next_input_byte = data; + mgr->bytes_in_buffer = size; + return 1; +} + +void mem_term_source (j_decompress_ptr cinfo) +{ + struct jpeg_source_mgr* mgr = cinfo->src; + //printf("term %d\n", size - mgr->bytes_in_buffer); +} + +int jpeg_load_from_mem(unsigned char*_data, int _size, unsigned char*dest, int width, int height) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + struct jpeg_source_mgr mgr; + int y,x; + + data = _data; + size = _size; + + jpeg_create_decompress(&cinfo); + + mgr.next_input_byte = data; + mgr.bytes_in_buffer = size; + mgr.init_source =mem_init_source ; + mgr.fill_input_buffer =mem_fill_input_buffer ; + mgr.skip_input_data =mem_skip_input_data ; + mgr.resync_to_restart =mem_resync_to_restart ; + mgr.term_source =mem_term_source ; + + cinfo.err = jpeg_std_error(&jerr); + cinfo.src = &mgr; + + jpeg_read_header(&cinfo, TRUE); + jpeg_start_decompress(&cinfo); + + for(y=0;y= 0; x--) { + line[x].a = 255; + line[x].r = js[x*3+0]; + line[x].g = js[x*3+1]; + line[x].b = js[x*3+2]; + } + } else if (cinfo.out_color_space == JCS_YCCK) { + fprintf(stderr, "Error: Can't convert YCCK to RGB.\n"); + return 0; + } else if (cinfo.out_color_space == JCS_YCbCr) { + for (x = 0; x < width; x++) { + int y = js[x * 3 + 0]; + int u = js[x * 3 + 1]; + int v = js[x * 3 + 1]; + line[x].a = 255; + line[x].r = y + ((360 * (v - 128)) >> 8); + line[x].g = y - ((88 * (u - 128) + 183 * (v - 128)) >> 8); + line[x].b = y + ((455 * (u - 128)) >> 8); + } + } else if (cinfo.out_color_space == JCS_CMYK) { + for (x = 0; x < width; x++) { + int white = 255 - js[x * 4 + 3]; + line[x].a = 255; + line[x].r = white - ((js[x * 4] * white) >> 8); + line[x].g = white - ((js[x * 4 + 1] * white) >> 8); + line[x].b = white - ((js[x * 4 + 2] * white) >> 8); + } + } + } + + free(scanline); + + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + return 1; +} + +#else + +int jpeg_save(unsigned char*data, int width, int height, int quality, const char*filename) +{ + fprintf(stderr, "jpeg_save: No JPEG support compiled in\n"); + return 0; +} +int jpeg_save_to_file(unsigned char*data, int width, int height, int quality, FILE*fi) +{ + fprintf(stderr, "jpeg_save_to_file: No JPEG support compiled in\n"); + return 0; +} +int jpeg_save_to_mem(unsigned char*data, int width, int height, int quality, unsigned char*dest, int destsize) +{ + fprintf(stderr, "jpeg_save_tomem: No JPEG support compiled in\n"); + return 0; +} +int jpeg_load_from_mem(unsigned char*_data, int size, unsigned char*dest, int width, int height) +{ + fprintf(stderr, "jpeg_load_from_mem: No JPEG support compiled in\n"); + return 0; +} +int jpeg_load(const char*filename, unsigned char**dest, int*_width, int*_height) +{ + fprintf(stderr, "jpeg_load: No JPEG support compiled in\n"); + return 0; +} + +#endif diff --git a/lib/jpeg.h b/lib/jpeg.h new file mode 100644 index 0000000..9af70f5 --- /dev/null +++ b/lib/jpeg.h @@ -0,0 +1,20 @@ +#ifndef __jpeg_h__ +#define __jpeg_h__ + +#include + +#ifdef __CPLUSPLUS__ +extern "C" { +#endif + +int jpeg_save(unsigned char*data, int width, int height, int quality, const char*filename); +int jpeg_save_to_file(unsigned char*data, int width, int height, int quality, FILE*fi); +int jpeg_save_to_mem(unsigned char*data, int width, int height, int quality, unsigned char*dest, int destsize); +int jpeg_load(const char*filename, unsigned char**dest, int*width, int*height); +int jpeg_load_from_mem(unsigned char*_data, int size, unsigned char*dest, int width, int height); + +#ifdef __CPLUSPLUS__ +} +#endif + +#endif -- 1.7.10.4