Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "fitz.h"
  2. #include "muxps.h"
  3.  
  4. static int
  5. xps_decode_image(fz_pixmap **imagep, byte *buf, int len)
  6. {
  7.         int error;
  8.  
  9.         if (len < 8)
  10.                 return fz_throw("unknown image file format");
  11.  
  12.         if (buf[0] == 0xff && buf[1] == 0xd8)
  13.         {
  14.                 error = xps_decode_jpeg(imagep, buf, len);
  15.                 if (error)
  16.                         return fz_rethrow(error, "cannot decode jpeg image");
  17.         }
  18.         else if (memcmp(buf, "\211PNG\r\n\032\n", 8) == 0)
  19.         {
  20.                 error = xps_decode_png(imagep, buf, len);
  21.                 if (error)
  22.                         return fz_rethrow(error, "cannot decode png image");
  23.         }
  24.         else if (memcmp(buf, "II", 2) == 0 && buf[2] == 0xBC)
  25.         {
  26.                 return fz_throw("JPEG-XR codec is not available");
  27.         }
  28.         else if (memcmp(buf, "MM", 2) == 0 || memcmp(buf, "II", 2) == 0)
  29.         {
  30.                 error = xps_decode_tiff(imagep, buf, len);
  31.                 if (error)
  32.                         return fz_rethrow(error, "cannot decode TIFF image");
  33.         }
  34.         else
  35.                 return fz_throw("unknown image file format");
  36.  
  37.         return fz_okay;
  38. }
  39.  
  40. static void
  41. xps_paint_image_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict,
  42.         xml_element *root, void *vimage)
  43. {
  44.         fz_pixmap *pixmap = vimage;
  45.         float xs = pixmap->w * 96 / pixmap->xres;
  46.         float ys = pixmap->h * 96 / pixmap->yres;
  47.         fz_matrix im = fz_scale(xs, -ys);
  48.         im.f = ys;
  49.         ctm = fz_concat(im, ctm);
  50.         fz_fill_image(ctx->dev, pixmap, ctm, ctx->opacity[ctx->opacity_top]);
  51. }
  52.  
  53. static xps_part *
  54. xps_find_image_brush_source_part(xps_context *ctx, char *base_uri, xml_element *root)
  55. {
  56.         char *image_source_att;
  57.         char buf[1024];
  58.         char partname[1024];
  59.         char *image_name;
  60.         char *profile_name;
  61.         char *p;
  62.  
  63.         image_source_att = xml_att(root, "ImageSource");
  64.         if (!image_source_att)
  65.                 return NULL;
  66.  
  67.         /* "{ColorConvertedBitmap /Resources/Image.tiff /Resources/Profile.icc}" */
  68.         if (strstr(image_source_att, "{ColorConvertedBitmap") == image_source_att)
  69.         {
  70.                 image_name = NULL;
  71.                 profile_name = NULL;
  72.  
  73.                 fz_strlcpy(buf, image_source_att, sizeof buf);
  74.                 p = strchr(buf, ' ');
  75.                 if (p)
  76.                 {
  77.                         image_name = p + 1;
  78.                         p = strchr(p + 1, ' ');
  79.                         if (p)
  80.                         {
  81.                                 *p = 0;
  82.                                 profile_name = p + 1;
  83.                                 p = strchr(p + 1, '}');
  84.                                 if (p)
  85.                                         *p = 0;
  86.                         }
  87.                 }
  88.         }
  89.         else
  90.         {
  91.                 image_name = image_source_att;
  92.                 profile_name = NULL;
  93.         }
  94.  
  95.         if (!image_name)
  96.                 return NULL;
  97.  
  98.         xps_absolute_path(partname, base_uri, image_name, sizeof partname);
  99.  
  100.         return xps_read_part(ctx, partname);
  101. }
  102.  
  103. void
  104. xps_parse_image_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
  105.         char *base_uri, xps_resource *dict, xml_element *root)
  106. {
  107.         xps_part *part;
  108.         fz_pixmap *image;
  109.         int code;
  110.  
  111.         part = xps_find_image_brush_source_part(ctx, base_uri, root);
  112.         if (!part) {
  113.                 fz_warn("cannot find image source");
  114.                 return;
  115.         }
  116.  
  117.         code = xps_decode_image(&image, part->data, part->size);
  118.         if (code < 0) {
  119.                 xps_free_part(ctx, part);
  120.                 fz_catch(-1, "cannot decode image resource");
  121.                 return;
  122.         }
  123.  
  124.         xps_parse_tiling_brush(ctx, ctm, area, base_uri, dict, root, xps_paint_image_brush, image);
  125.  
  126.         fz_drop_pixmap(image);
  127.         xps_free_part(ctx, part);
  128. }
  129.