static void jxr_decode_block(jxr_image_t image, int mx, int my, int *data) { struct info *info = jxr_get_user_data(image); fz_context *ctx = info->ctx; unsigned char *p; int x, y, n1; mx *= 16; my *= 16; n1 = fz_colorspace_n(ctx, info->cspace) + 1; for (y = 0; y < 16; y++) { if ((my + y) >= info->height) return; p = info->samples + (my + y) * info->stride + mx * n1; for (x = 0; x < 16; x++) { if ((mx + x) < info->width) { jxr_unpack_sample(ctx, info, image, data, p); p += n1; } data += jxr_get_IMAGE_CHANNELS(image) + jxr_get_ALPHACHANNEL_FLAG(image); data += (info->format == JXRC_FMT_32bppRGBE ? 1 : 0); } } }
static inline void jxr_unpack_sample(fz_context *ctx, struct info *info, jxr_image_t image, int *sp, unsigned char *dp) { int k, bpc, comps, alpha; float v; if (info->format == JXRC_FMT_32bppRGBE) { dp[0] = sRGB_from_scRGB(ldexpf(sp[0], sp[3] - 128 - 8)) * 255 + 0.5f; dp[1] = sRGB_from_scRGB(ldexpf(sp[1], sp[3] - 128 - 8)) * 255 + 0.5f; dp[2] = sRGB_from_scRGB(ldexpf(sp[2], sp[3] - 128 - 8)) * 255 + 0.5f; return; } if (info->format == JXRC_FMT_16bppBGR565) { dp[0] = sp[0] << 3; dp[1] = sp[1] << 2; dp[2] = sp[2] << 3; return; } comps = fz_mini(fz_colorspace_n(ctx, info->cspace), jxr_get_IMAGE_CHANNELS(image)); alpha = jxr_get_ALPHACHANNEL_FLAG(image); bpc = jxr_get_CONTAINER_BPC(image); for (k = 0; k < comps + alpha; k++) { switch (bpc) { default: fz_throw(ctx, FZ_ERROR_GENERIC, "unknown sample type: %d", bpc); case JXR_BD1WHITE1: dp[k] = sp[k] ? 255 : 0; break; case JXR_BD1BLACK1: dp[k] = sp[k] ? 0 : 255; break; case JXR_BD5: dp[k] = sp[k] << 3; break; case JXR_BD8: dp[k] = sp[k]; break; case JXR_BD10: dp[k] = sp[k] >> 2; break; case JXR_BD16: dp[k] = sp[k] >> 8; break; case JXR_BD16S: v = sp[k] * (1.0f / (1 << 13)); goto decode_float32; case JXR_BD32S: v = sp[k] * (1.0f / (1 << 24)); goto decode_float32; case JXR_BD16F: v = float32_from_float16(sp[k]); goto decode_float32; case JXR_BD32F: v = float32_from_int32_bits(sp[k]); goto decode_float32; decode_float32: if (k < comps) dp[k] = sRGB_from_scRGB(fz_clamp(v, 0, 1)) * 255 + 0.5f; else dp[k] = fz_clamp(v, 0, 1) * 255 + 0.5f; break; } } }
static void xps_decode_jpegxr_block(jxr_image_t image, int mx, int my, int *data) { struct state *state = jxr_get_user_data(image); xps_context_t *ctx = state->ctx; xps_image_t *output = state->output; int depth; unsigned char *p; int x, y, k; if (!output->samples) { output->width = jxr_get_IMAGE_WIDTH(image); output->height = jxr_get_IMAGE_HEIGHT(image); output->comps = jxr_get_IMAGE_CHANNELS(image); output->hasalpha = jxr_get_ALPHACHANNEL_FLAG(image); output->bits = 8; output->stride = output->width * output->comps; output->samples = xps_alloc(ctx, output->stride * output->height); if (!output->samples) { gs_throw(gs_error_VMerror, "out of memory: output->samples.\n"); return; } switch (output->comps) { default: case 1: output->colorspace = ctx->gray; break; case 3: output->colorspace = ctx->srgb; break; case 4: output->colorspace = ctx->cmyk; break; } } depth = jxr_get_OUTPUT_BITDEPTH(image); my = my * 16; mx = mx * 16; for (y = 0; y < 16; y++) { if (my + y >= output->height) return; p = output->samples + (my + y) * output->stride + mx * output->comps; for (x = 0; x < 16; x++) { if (mx + x >= output->width) data += output->comps; else for (k = 0; k < output->comps; k++) *p++ = scale_bits(depth, *data++); } } }