ext/image_intensities/jpeg.c in image_intensities-1.0.2 vs ext/image_intensities/jpeg.c in image_intensities-1.0.3
- old
+ new
@@ -1,71 +1,60 @@
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
#include <stddef.h>
+#include <stdlib.h>
+#include <turbojpeg.h>
#include <fcntl.h>
-#include <string.h>
-#include <jpeglib.h>
-#include <setjmp.h>
+#include <unistd.h>
+#include <sys/mman.h>
#include "definitions.h"
-struct my_error_mgr {
- struct jpeg_error_mgr pub;
- jmp_buf setjmp_buffer;
-};
-
-static void my_error_exit(j_common_ptr cinfo)
-{
- struct my_error_mgr *myerr = (struct my_error_mgr *) cinfo->err;
- longjmp(myerr->setjmp_buffer, 1);
-}
-
raster_data read_jpeg_file(const char *file_name)
{
- struct jpeg_decompress_struct cinfo;
- struct my_error_mgr jerr;
- FILE *file;
- JSAMPARRAY buffer;
- int row_stride;
-
raster_data data = {};
+ tjhandle decompressor = NULL;
+ void *input = NULL;
+ off_t size = 0;
+ int fd = -1;
+ int error = 0;
+ int jpegSubsamp;
- file = fopen(file_name, "rb");
- if (file == NULL) {
- data.error = 1;
- return data;
+ fd = open(file_name, 0);
+ if (fd < 0) {
+ error = 1;
+ goto cleanup;
}
- cinfo.err = jpeg_std_error(&jerr.pub);
- jerr.pub.error_exit = my_error_exit;
+ if ((size = lseek(fd, 0, SEEK_END)) < 0) {
+ error = 1;
+ goto cleanup;
+ }
- if (setjmp(jerr.setjmp_buffer)) {
- jpeg_destroy_decompress(&cinfo);
- fclose(file);
+ if ((input = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0)) == NULL) {
+ error = 1;
+ goto cleanup;
+ }
- return data;
+ if ((decompressor = tjInitDecompress()) == NULL) {
+ error = 1;
+ goto cleanup;
}
- jpeg_create_decompress(&cinfo);
- jpeg_stdio_src(&cinfo, file);
- jpeg_read_header(&cinfo, TRUE);
- jpeg_start_decompress(&cinfo);
+ if ((tjDecompressHeader2(decompressor, input, size, &data.width, &data.height, &jpegSubsamp)) < 0) {
+ error = 1;
+ goto cleanup;
+ }
- data.width = cinfo.output_width;
- data.height = cinfo.output_height;
- data.pixels = malloc(cinfo.output_components * cinfo.output_width * cinfo.output_height);
+ data.pixels = malloc(data.width * data.height * sizeof(rgb_pixel));
- row_stride = cinfo.output_width * cinfo.output_components;
- buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
-
- for (size_t i = 0; cinfo.output_scanline < cinfo.output_height; ++i) {
- jpeg_read_scanlines(&cinfo, buffer, 1);
- memcpy(&data.pixels[i * cinfo.output_width], buffer[0], row_stride);
+ if ((tjDecompress2(decompressor, input, size, (uint8_t *) data.pixels, data.width, 0, data.height, TJPF_RGB, TJFLAG_FASTDCT)) < 0) {
+ error = 1;
+ goto cleanup;
}
- jpeg_finish_decompress(&cinfo);
- jpeg_destroy_decompress(&cinfo);
- fclose(file);
+cleanup:
+ if (decompressor) tjDestroy(decompressor);
+ if (input) munmap(input, size);
+ if (fd >= 0) close(fd);
+ data.error = error;
return data;
}