- shared_ptr<dcp::OpenJPEGImage> decompressed = dcp::decompress_j2k (const_cast<uint8_t*> (_data.data().get()), _data.size (), reduce);
-
- /* When scaling JPEG2000 images (using AV_PIX_FMT_XYZ12LE) ffmpeg will call xyz12ToRgb48 which reads data
- from the whole of the image stride. If we are cropping, Image::crop_scale_window munges the
- start addresses of each image row (to do the crop) but keeps the stride the same. This means
- that under crop we will read over the end of the image by the amount of the crop. To allow this
- to happen without invalid memory access we need to overallocate by one whole stride's worth of pixels.
- */
- _image.reset (new Image (_pixel_format, decompressed->size(), true, decompressed->size().width));
-
- int const shift = 16 - decompressed->precision (0);
-
- /* Copy data in whatever format (sRGB or XYZ) into our Image; I'm assuming
- the data is 12-bit either way.
- */
-
- int const width = decompressed->size().width;
-
- int p = 0;
- int* decomp_0 = decompressed->data (0);
- int* decomp_1 = decompressed->data (1);
- int* decomp_2 = decompressed->data (2);
- for (int y = 0; y < decompressed->size().height; ++y) {
- uint16_t* q = (uint16_t *) (_image->data()[0] + y * _image->stride()[0]);
- for (int x = 0; x < width; ++x) {
- *q++ = decomp_0[p] << shift;
- *q++ = decomp_1[p] << shift;
- *q++ = decomp_2[p] << shift;
- ++p;
+ try {
+ /* XXX: should check that potentially trashing _data here doesn't matter */
+ auto decompressed = dcp::decompress_j2k (const_cast<uint8_t*>(_data->data()), _data->size(), reduce);
+ _image = make_shared<Image>(_pixel_format, decompressed->size(), alignment);
+
+ int const shift = 16 - decompressed->precision (0);
+
+ /* Copy data in whatever format (sRGB or XYZ) into our Image; I'm assuming
+ the data is 12-bit either way.
+ */
+
+ int const width = decompressed->size().width;
+
+ int p = 0;
+ int* decomp_0 = decompressed->data (0);
+ int* decomp_1 = decompressed->data (1);
+ int* decomp_2 = decompressed->data (2);
+ for (int y = 0; y < decompressed->size().height; ++y) {
+ auto q = reinterpret_cast<uint16_t *>(_image->data()[0] + y * _image->stride()[0]);
+ for (int x = 0; x < width; ++x) {
+ *q++ = decomp_0[p] << shift;
+ *q++ = decomp_1[p] << shift;
+ *q++ = decomp_2[p] << shift;
+ ++p;
+ }