/* * libjpeg8-mem-dest - an example about reusing the memory buffer with libjpeg8 * * Copyright (C) 2013 Antonio Ospite * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #define WIDTH 800 #define HEIGHT 480 static unsigned char *new_image(void) { unsigned char *image; int i; image = malloc(WIDTH * HEIGHT * 3 * sizeof(*image)); if (image == NULL) { perror("malloc"); exit(EXIT_FAILURE); } for (i = 0; i < WIDTH * HEIGHT * 3; i++) image[i] = rand() % 0xff; return image; } int main(void) { int i; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; int row_stride; unsigned char *out_buf; unsigned long out_buf_size; unsigned char *input_image; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); out_buf = NULL; out_buf_size = 0; jpeg_mem_dest(&cinfo, &out_buf, &out_buf_size); 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, 80, TRUE); row_stride = WIDTH * 3; srand(time(NULL)); i = 0; while(i++ < 10) { input_image = new_image(); jpeg_start_compress(&cinfo, TRUE); while(cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = &input_image[cinfo.next_scanline * row_stride]; (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); free(input_image); /* Is out_buf_size the number of bytes of the jpeg image, or the * size of the allocated buffer? */ fprintf(stderr, "out_buf: %p out_buf_size: %ld\n", out_buf, out_buf_size); { char filename[256] = { 0 }; FILE *out_file; snprintf(filename, sizeof(filename), "out%03d.jpg", i); out_file = fopen(filename, "wb"); fwrite(out_buf, out_buf_size, 1, out_file); fclose(out_file); } #if 1 /* * Rewind the buffer, taken from: * http://sourceforge.net/p/libjpeg-turbo/discussion/1086868/thread/b797ffaf/ */ cinfo.dest->free_in_buffer += cinfo.dest->next_output_byte - out_buf; cinfo.dest->next_output_byte = out_buf; #else /* The code above avoids freeing and allocating a NEW buffer * Isn't there a more straightforward way to recycle the old * buffer after we consumed its content? */ free(out_buf); out_buf = NULL; out_buf_size = 0; jpeg_mem_dest(&cinfo, &out_buf, &out_buf_size); #endif } jpeg_destroy_compress(&cinfo); free(out_buf); return 0; }