load-jxr.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. // Copyright (C) 2004-2021 Artifex Software, Inc.
  2. //
  3. // This file is part of MuPDF.
  4. //
  5. // MuPDF is free software: you can redistribute it and/or modify it under the
  6. // terms of the GNU Affero General Public License as published by the Free
  7. // Software Foundation, either version 3 of the License, or (at your option)
  8. // any later version.
  9. //
  10. // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
  11. // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. // details.
  14. //
  15. // You should have received a copy of the GNU Affero General Public License
  16. // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
  17. //
  18. // Alternative licensing terms are available from the licensor.
  19. // For commercial licensing, see <https://www.artifex.com/> or contact
  20. // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  21. // CA 94129, USA, for further information.
  22. #include "mupdf/fitz.h"
  23. #include "pixmap-imp.h"
  24. #ifdef HAVE_JPEGXR
  25. #include <math.h>
  26. #include <string.h>
  27. #include <jpegxr.h>
  28. struct info
  29. {
  30. fz_context *ctx;
  31. float xres, yres;
  32. int width, height;
  33. int format;
  34. int has_alpha;
  35. int has_premul;
  36. int comps, stride;
  37. unsigned char *samples;
  38. fz_colorspace *cspace;
  39. };
  40. static const char *
  41. jxr_error_string(int rc)
  42. {
  43. switch (rc)
  44. {
  45. case JXR_EC_OK: return "No error";
  46. default:
  47. case JXR_EC_ERROR: return "Unspecified error";
  48. case JXR_EC_BADMAGIC: return "Stream lacks proper magic number";
  49. case JXR_EC_FEATURE_NOT_IMPLEMENTED: return "Feature not implemented";
  50. case JXR_EC_IO: return "Error reading/writing data";
  51. case JXR_EC_BADFORMAT: return "Bad file format";
  52. }
  53. }
  54. struct {
  55. jxrc_t_pixelFormat format;
  56. int comps;
  57. } pixelformats[] = {
  58. {JXRC_FMT_BlackWhite, 1},
  59. {JXRC_FMT_8bppGray, 1},
  60. {JXRC_FMT_16bppGray, 1},
  61. {JXRC_FMT_16bppGrayFixedPoint, 1},
  62. {JXRC_FMT_16bppGrayHalf, 1},
  63. {JXRC_FMT_32bppGrayFixedPoint, 1},
  64. {JXRC_FMT_32bppGrayFloat, 1},
  65. {JXRC_FMT_16bppBGR555, 3},
  66. {JXRC_FMT_16bppBGR565, 3},
  67. {JXRC_FMT_24bppBGR, 3},
  68. {JXRC_FMT_24bppRGB, 3},
  69. {JXRC_FMT_32bppBGR101010, 3},
  70. {JXRC_FMT_32bppBGRA, 3},
  71. {JXRC_FMT_32bppBGR, 3},
  72. {JXRC_FMT_32bppPBGRA, 3},
  73. {JXRC_FMT_48bppRGBFixedPoint, 3},
  74. {JXRC_FMT_48bppRGBHalf, 3},
  75. {JXRC_FMT_48bppRGB, 3},
  76. {JXRC_FMT_64bppPRGBA, 3},
  77. {JXRC_FMT_64bppRGBAFixedPoint, 3},
  78. {JXRC_FMT_64bppRGBAHalf, 3},
  79. {JXRC_FMT_64bppRGBA, 3},
  80. {JXRC_FMT_64bppRGBFixedPoint, 3},
  81. {JXRC_FMT_64bppRGBHalf, 3},
  82. {JXRC_FMT_96bppRGBFixedPoint, 3},
  83. {JXRC_FMT_128bppPRGBAFloat, 3},
  84. {JXRC_FMT_128bppRGBAFixedPoint, 3},
  85. {JXRC_FMT_128bppRGBAFloat, 3},
  86. {JXRC_FMT_128bppRGBFixedPoint, 3},
  87. {JXRC_FMT_128bppRGBFloat, 3},
  88. {JXRC_FMT_32bppRGBE, 3},
  89. {JXRC_FMT_32bppCMYK, 4},
  90. {JXRC_FMT_40bppCMYKAlpha, 4},
  91. {JXRC_FMT_64bppCMYK, 4},
  92. {JXRC_FMT_80bppCMYKAlpha, 4},
  93. {JXRC_FMT_24bpp3Channels, 3},
  94. {JXRC_FMT_32bpp3ChannelsAlpha, 3},
  95. {JXRC_FMT_32bpp4Channels, 4},
  96. {JXRC_FMT_40bpp4ChannelsAlpha, 4},
  97. {JXRC_FMT_40bpp5Channels, 5},
  98. {JXRC_FMT_48bpp3Channels, 3},
  99. {JXRC_FMT_48bpp5ChannelsAlpha, 5},
  100. {JXRC_FMT_48bpp6Channels, 6},
  101. {JXRC_FMT_56bpp6ChannelsAlpha, 6},
  102. {JXRC_FMT_56bpp7Channels, 7},
  103. {JXRC_FMT_64bpp3ChannelsAlpha, 3},
  104. {JXRC_FMT_64bpp4Channels, 4},
  105. {JXRC_FMT_64bpp7ChannelsAlpha, 7},
  106. {JXRC_FMT_64bpp8Channels, 8},
  107. {JXRC_FMT_72bpp8ChannelsAlpha, 8},
  108. {JXRC_FMT_80bpp4ChannelsAlpha, 4},
  109. {JXRC_FMT_80bpp5Channels, 5},
  110. {JXRC_FMT_96bpp5ChannelsAlpha, 5},
  111. {JXRC_FMT_96bpp6Channels, 6},
  112. {JXRC_FMT_112bpp6ChannelsAlpha, 6},
  113. {JXRC_FMT_112bpp7Channels, 7},
  114. {JXRC_FMT_128bpp7ChannelsAlpha, 7},
  115. {JXRC_FMT_128bpp8Channels, 8},
  116. {JXRC_FMT_144bpp8ChannelsAlpha, 8},
  117. };
  118. static inline float
  119. float32_from_int32_bits(int v)
  120. {
  121. return *((float*) &v);
  122. }
  123. static inline float
  124. float32_from_float16(int v)
  125. {
  126. int s = (v >> 15) & 0x1;
  127. int e = (v >> 10) & 0x1f;
  128. int m = (v >> 0) & 0x3ff;
  129. int i = (s << 31) | ((e - 15 + 127) << 23) | (m << 13);
  130. return float32_from_int32_bits(i);
  131. }
  132. static inline float
  133. sRGB_from_scRGB(float v)
  134. {
  135. if (v <= 0.0031308f)
  136. return v * 12.92f;
  137. return 1.055f * powf(v, 1.0f / 2.4f) - 0.055f;
  138. }
  139. static inline void
  140. jxr_unpack_sample(fz_context *ctx, struct info *info, jxr_image_t image, int *sp, unsigned char *dp)
  141. {
  142. int k, bpc, comps, alpha;
  143. float v;
  144. if (info->format == JXRC_FMT_32bppRGBE)
  145. {
  146. dp[0] = sRGB_from_scRGB(ldexpf(sp[0], sp[3] - 128 - 8)) * 255 + 0.5f;
  147. dp[1] = sRGB_from_scRGB(ldexpf(sp[1], sp[3] - 128 - 8)) * 255 + 0.5f;
  148. dp[2] = sRGB_from_scRGB(ldexpf(sp[2], sp[3] - 128 - 8)) * 255 + 0.5f;
  149. return;
  150. }
  151. if (info->format == JXRC_FMT_16bppBGR565)
  152. {
  153. dp[0] = sp[0] << 3;
  154. dp[1] = sp[1] << 2;
  155. dp[2] = sp[2] << 3;
  156. return;
  157. }
  158. comps = fz_mini(fz_colorspace_n(ctx, info->cspace), jxr_get_IMAGE_CHANNELS(image));
  159. alpha = jxr_get_ALPHACHANNEL_FLAG(image);
  160. bpc = jxr_get_CONTAINER_BPC(image);
  161. for (k = 0; k < comps + alpha; k++)
  162. {
  163. switch (bpc)
  164. {
  165. default: fz_throw(ctx, FZ_ERROR_FORMAT, "unknown sample type: %d", bpc);
  166. case JXR_BD1WHITE1: dp[k] = sp[k] ? 255 : 0; break;
  167. case JXR_BD1BLACK1: dp[k] = sp[k] ? 0 : 255; break;
  168. case JXR_BD5: dp[k] = sp[k] << 3; break;
  169. case JXR_BD8: dp[k] = sp[k]; break;
  170. case JXR_BD10: dp[k] = sp[k] >> 2; break;
  171. case JXR_BD16: dp[k] = sp[k] >> 8; break;
  172. case JXR_BD16S:
  173. v = sp[k] * (1.0f / (1 << 13));
  174. goto decode_float32;
  175. case JXR_BD32S:
  176. v = sp[k] * (1.0f / (1 << 24));
  177. goto decode_float32;
  178. case JXR_BD16F:
  179. v = float32_from_float16(sp[k]);
  180. goto decode_float32;
  181. case JXR_BD32F:
  182. v = float32_from_int32_bits(sp[k]);
  183. goto decode_float32;
  184. decode_float32:
  185. if (k < comps)
  186. dp[k] = sRGB_from_scRGB(fz_clamp(v, 0, 1)) * 255 + 0.5f;
  187. else
  188. dp[k] = fz_clamp(v, 0, 1) * 255 + 0.5f;
  189. break;
  190. }
  191. }
  192. }
  193. static inline void
  194. jxr_unpack_alpha_sample(fz_context *ctx, struct info *info, jxr_image_t image, int *sp, unsigned char *dp)
  195. {
  196. int bpc = jxr_get_CONTAINER_BPC(image);
  197. switch (bpc)
  198. {
  199. default: fz_throw(ctx, FZ_ERROR_FORMAT, "unknown alpha sample type: %d", bpc);
  200. case JXR_BD8: dp[0] = sp[0]; break;
  201. case JXR_BD10: dp[0] = sp[0] >> 2; break;
  202. case JXR_BD16: dp[0] = sp[0] >> 8; break;
  203. case JXR_BD16S:
  204. dp[0] = fz_clamp(sp[0] * (1.0f / (1 << 13)), 0, 1) * 255 + 0.5f;
  205. break;
  206. case JXR_BD32S:
  207. dp[0] = fz_clamp(sp[0] * (1.0f / (1 << 24)), 0, 1) * 255 + 0.5f;
  208. break;
  209. case JXR_BD16F:
  210. dp[0] = fz_clamp(float32_from_float16(sp[0]), 0, 1) * 255 + 0.5f;
  211. break;
  212. case JXR_BD32F:
  213. dp[0] = fz_clamp(float32_from_int32_bits(sp[0]), 0, 1) * 255 + 0.5f;
  214. break;
  215. }
  216. }
  217. static void
  218. jxr_decode_block(jxr_image_t image, int mx, int my, int *data)
  219. {
  220. struct info *info = jxr_get_user_data(image);
  221. fz_context *ctx = info->ctx;
  222. unsigned char *p;
  223. int x, y, n1;
  224. mx *= 16;
  225. my *= 16;
  226. n1 = fz_colorspace_n(ctx, info->cspace) + 1;
  227. for (y = 0; y < 16; y++)
  228. {
  229. if ((my + y) >= info->height)
  230. return;
  231. p = info->samples + (my + y) * info->stride + mx * n1;
  232. for (x = 0; x < 16; x++)
  233. {
  234. if ((mx + x) < info->width)
  235. {
  236. jxr_unpack_sample(ctx, info, image, data, p);
  237. p += n1;
  238. }
  239. data += jxr_get_IMAGE_CHANNELS(image) + jxr_get_ALPHACHANNEL_FLAG(image);
  240. data += (info->format == JXRC_FMT_32bppRGBE ? 1 : 0);
  241. }
  242. }
  243. }
  244. static void
  245. jxr_decode_block_alpha(jxr_image_t image, int mx, int my, int *data)
  246. {
  247. struct info *info = jxr_get_user_data(image);
  248. fz_context *ctx = info->ctx;
  249. unsigned char *p;
  250. int x, y, n;
  251. mx *= 16;
  252. my *= 16;
  253. n = fz_colorspace_n(ctx, info->cspace);
  254. for (y = 0; y < 16; y++)
  255. {
  256. if ((my + y) >= info->height)
  257. return;
  258. p = info->samples + (my + y) * info->stride + mx * (n + 1);
  259. for (x = 0; x < 16; x++)
  260. {
  261. if ((mx + x) < info->width)
  262. {
  263. jxr_unpack_alpha_sample(ctx, info, image, data, p + n);
  264. p += n + 1;
  265. }
  266. data++;
  267. }
  268. }
  269. }
  270. static void
  271. jxr_read_image(fz_context *ctx, const unsigned char *data, int size, struct info *info, int only_metadata)
  272. {
  273. jxr_container_t container;
  274. jxr_image_t image = NULL;
  275. jxr_image_t alpha = NULL;
  276. size_t i;
  277. int rc;
  278. fz_var(image);
  279. fz_var(alpha);
  280. fz_try(ctx)
  281. {
  282. container = jxr_create_container();
  283. rc = jxr_read_image_container_memory(container, (unsigned char *)data, size);
  284. if (rc < 0)
  285. fz_throw(ctx, FZ_ERROR_LIBRARY, "cannot read jxr image container: %s", jxr_error_string(rc));
  286. info->xres = jxrc_width_resolution(container, 0);
  287. info->yres = jxrc_height_resolution(container, 0);
  288. info->width = jxrc_image_width(container, 0);
  289. info->height = jxrc_image_height(container, 0);
  290. info->format = (int) jxrc_image_pixelformat(container, 0);
  291. for (i = 0; i < nelem(pixelformats); i++)
  292. if ((int) pixelformats[i].format == info->format)
  293. {
  294. info->comps = pixelformats[i].comps;
  295. break;
  296. }
  297. if (i == nelem(pixelformats))
  298. fz_throw(ctx, FZ_ERROR_FORMAT, "unsupported pixel format: %u", info->format);
  299. if (info->comps == 1)
  300. info->cspace = fz_device_gray(ctx);
  301. else if (info->comps == 3)
  302. info->cspace = fz_device_rgb(ctx);
  303. else if (info->comps >= 4)
  304. info->cspace = fz_device_cmyk(ctx);
  305. info->stride = info->width * (fz_colorspace_n(ctx, info->cspace) + 1);
  306. if (!only_metadata)
  307. {
  308. unsigned long image_offset;
  309. unsigned char image_band;
  310. unsigned long alpha_offset;
  311. unsigned char alpha_band;
  312. info->ctx = ctx;
  313. info->samples = Memento_label(fz_malloc(ctx, info->stride * info->height), "jxr_samples");
  314. memset(info->samples, 0xff, info->stride * info->height);
  315. image_offset = jxrc_image_offset(container, 0);
  316. image_band = jxrc_image_band_presence(container, 0);
  317. alpha_offset = jxrc_alpha_offset(container, 0);
  318. alpha_band = jxrc_alpha_band_presence(container, 0);
  319. image = jxr_create_input();
  320. jxr_set_PROFILE_IDC(image, 111);
  321. jxr_set_LEVEL_IDC(image, 255);
  322. jxr_set_pixel_format(image, info->format);
  323. jxr_set_container_parameters(image, info->format,
  324. info->width, info->height, alpha_offset,
  325. image_band, alpha_band, 0);
  326. jxr_set_user_data(image, info);
  327. jxr_set_block_output(image, jxr_decode_block);
  328. rc = jxr_read_image_bitstream_memory(image, (unsigned char *)data + image_offset, size - image_offset);
  329. if (rc < 0)
  330. fz_throw(ctx, FZ_ERROR_LIBRARY, "cannot read jxr image: %s", jxr_error_string(rc));
  331. if (info->format == JXRC_FMT_32bppPBGRA ||
  332. info->format == JXRC_FMT_64bppPRGBA ||
  333. info->format == JXRC_FMT_128bppPRGBAFloat)
  334. info->has_premul = 1;
  335. if (jxr_get_ALPHACHANNEL_FLAG(image))
  336. info->has_alpha = 1;
  337. if (alpha_offset > 0)
  338. {
  339. info->has_alpha = 1;
  340. alpha = jxr_create_input();
  341. jxr_set_PROFILE_IDC(alpha, 111);
  342. jxr_set_LEVEL_IDC(alpha, 255);
  343. jxr_set_pixel_format(alpha, info->format);
  344. jxr_set_container_parameters(alpha, info->format,
  345. info->width, info->height, alpha_offset,
  346. image_band, alpha_band, 1);
  347. jxr_set_user_data(alpha, info);
  348. jxr_set_block_output(alpha, jxr_decode_block_alpha);
  349. rc = jxr_read_image_bitstream_memory(alpha, (unsigned char *)data + alpha_offset, size - alpha_offset);
  350. if (rc < 0)
  351. fz_throw(ctx, FZ_ERROR_LIBRARY, "cannot read jxr image: %s", jxr_error_string(rc));
  352. }
  353. }
  354. }
  355. fz_always(ctx)
  356. {
  357. if (alpha)
  358. jxr_destroy(alpha);
  359. if (image)
  360. jxr_destroy(image);
  361. jxr_destroy_container(container);
  362. }
  363. fz_catch(ctx)
  364. {
  365. fz_rethrow(ctx);
  366. }
  367. }
  368. fz_pixmap *
  369. fz_load_jxr(fz_context *ctx, const unsigned char *data, size_t size)
  370. {
  371. struct info info = { 0 };
  372. fz_pixmap *image = NULL;
  373. fz_var(image);
  374. fz_try(ctx)
  375. {
  376. jxr_read_image(ctx, data, size, &info, 0);
  377. image = fz_new_pixmap(ctx, info.cspace, info.width, info.height, NULL, 1);
  378. image->xres = info.xres;
  379. image->yres = info.yres;
  380. fz_unpack_tile(ctx, image, info.samples, fz_colorspace_n(ctx, info.cspace) + 1, 8, info.stride, 0);
  381. if (info.has_alpha && !info.has_premul)
  382. fz_premultiply_pixmap(ctx, image);
  383. }
  384. fz_always(ctx)
  385. {
  386. fz_free(ctx, info.samples);
  387. }
  388. fz_catch(ctx)
  389. {
  390. fz_drop_pixmap(ctx, image);
  391. fz_rethrow(ctx);
  392. }
  393. return image;
  394. }
  395. void
  396. fz_load_jxr_info(fz_context *ctx, const unsigned char *data, size_t size, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep)
  397. {
  398. struct info info = { 0 };
  399. jxr_read_image(ctx, data, size, &info, 1);
  400. *cspacep = fz_keep_colorspace(ctx, info.cspace); /* info.cspace is a borrowed device colorspace */
  401. *wp = info.width;
  402. *hp = info.height;
  403. *xresp = info.xres;
  404. *yresp = info.yres;
  405. }
  406. #else /* HAVE_JPEGXR */
  407. fz_pixmap *
  408. fz_load_jxr(fz_context *ctx, const unsigned char *data, size_t size)
  409. {
  410. fz_throw(ctx, FZ_ERROR_UNSUPPORTED, "JPEG-XR codec is not available");
  411. }
  412. void
  413. fz_load_jxr_info(fz_context *ctx, const unsigned char *data, size_t size, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep)
  414. {
  415. fz_throw(ctx, FZ_ERROR_UNSUPPORTED, "JPEG-XR codec is not available");
  416. }
  417. #endif /* HAVE_JPEGXR */