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; }