This commit is contained in:
Surma
2020-08-24 12:43:12 +01:00
parent 4e090ea2f8
commit 8cd811cafd
4 changed files with 18 additions and 30 deletions

View File

@@ -15,52 +15,40 @@ thread_local const val ImageData = val::global("ImageData");
val decode(std::string image_in) {
uint8_t* image_buffer = (uint8_t*)image_in.c_str();
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
/* Initialize the JPEG decompression object with default error handling. */
jpeg_decompress_struct cinfo;
jpeg_error_mgr jerr;
// Initialize the JPEG decompression object with default error handling.
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_mem_src(&cinfo, image_buffer, image_in.length());
/* Read file header, set default decompression parameters */
// Read file header, set default decompression parameters
jpeg_read_header(&cinfo, TRUE);
// Force RGB decoding, even for grayscale images
cinfo.out_color_space = JCS_RGB;
// Force RGBA decoding, even for grayscale images
cinfo.out_color_space = JCS_EXT_RGBA;
jpeg_start_decompress(&cinfo);
// Prepare output buffer
size_t output_size = cinfo.output_width * cinfo.output_height * 4;
auto output_buffer = new uint8_t[output_size];
uint8_t* row_ptr = &output_buffer[0];
std::vector<uint8_t> output_buffer(output_size);
auto stride = cinfo.output_width * 4;
/* Process data */
// Process data
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, &row_ptr, 1);
// Turn that row from RGB into RGBA. Im starting at the end so
// I can do it in-place.
for (int32_t x = cinfo.output_width - 1; x >= 0; x--) {
// RGB channels
for (auto i = 0; i < 3; i++) {
row_ptr[x * 4 + i] = row_ptr[x * 3 + i];
}
// Alpha channel
row_ptr[x * 4 + 3] = 255;
}
row_ptr += stride;
uint8_t* ptr = &output_buffer[stride * cinfo.output_scanline];
jpeg_read_scanlines(&cinfo, &ptr, 1);
}
jpeg_finish_decompress(&cinfo);
/* Step 7: release JPEG compression object */
// Step 7: release JPEG compression object
auto data = Uint8ClampedArray.new_(typed_memory_view(output_size, output_buffer));
auto data = Uint8ClampedArray.new_(typed_memory_view(output_size, &output_buffer[0]));
auto js_result = ImageData.new_(data, cinfo.output_width, cinfo.output_height);
/* This is an important step since it will release a good deal of memory. */
// This is an important step since it will release a good deal of memory.
jpeg_destroy_decompress(&cinfo);
delete[] output_buffer;
/* And we're done! */
// And we're done!
return js_result;
}