"Fossies" - the Fresh Open Source Software Archive

Member "PDFlib-Lite-7.0.5p3/libs/pdflib/p_image.c" (6 Jun 2012, 64428 Bytes) of package /linux/misc/old/PDFlib-Lite-7.0.5p3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "p_image.c" see the Fossies "Dox" file reference documentation.

    1 /*---------------------------------------------------------------------------*
    2  |              PDFlib - A library for generating PDF on the fly             |
    3  +---------------------------------------------------------------------------+
    4  | Copyright (c) 1997-2007 Thomas Merz and PDFlib GmbH. All rights reserved. |
    5  +---------------------------------------------------------------------------+
    6  |                                                                           |
    7  |    This software is subject to the PDFlib license. It is NOT in the       |
    8  |    public domain. Extended versions and commercial licenses are           |
    9  |    available, please check http://www.pdflib.com.                         |
   10  |                                                                           |
   11  *---------------------------------------------------------------------------*/
   12 
   13 /* $Id: p_image.c,v 1.318.2.31 2009/03/03 21:25:20 kurt Exp $
   14  *
   15  * PDFlib image routines
   16  *
   17  */
   18 
   19 #define P_IMAGE_C
   20 
   21 #include "p_intern.h"
   22 #include "p_color.h"
   23 #include "p_defopt.h"
   24 #include "p_font.h"
   25 #include "p_image.h"
   26 #include "p_layer.h"
   27 #include "p_tagged.h"
   28 
   29 static void
   30 pdf_init_image_struct(PDF *p, pdf_image *image)
   31 {
   32     (void) p;
   33 
   34     /********** option variables *************/
   35     image->verbose      = p->debug[(int) 'i'];
   36     image->verbose      = pdf_get_errorpolicy(p, NULL, image->verbose);
   37     image->bitreverse   = pdc_false;
   38     image->bpc          = pdc_undef;
   39     image->components   = pdc_undef;
   40     image->height_pixel = pdc_undef;
   41     image->ignoremask   = pdc_false;
   42     image->ignoreorient = pdc_false;
   43     image->doinline     = pdc_false;
   44     image->interpolate  = pdc_false;
   45     image->invert       = pdc_false;
   46     image->jpegoptimize = pdc_true;
   47     image->passthrough  = pdc_undef;
   48     image->K            = 0;
   49     image->imagemask    = pdc_false;
   50     image->mask         = pdc_undef;
   51     image->ri           = AutoIntent;
   52     image->page         = 1;
   53     image->reference    = pdf_ref_direct;
   54     image->width_pixel  = pdc_undef;
   55     image->topdown_save = pdc_false;
   56     image->iconname     = (char *) NULL;
   57     /*****************************************/
   58 
   59     image->orientation  = 1;
   60     image->transparent  = pdc_false;
   61     image->compression  = pdf_comp_none;
   62     image->predictor    = pred_default;
   63     image->in_use       = pdc_false;
   64     image->corrupt      = pdc_false;
   65     image->fp           = (pdc_file *) NULL;
   66     image->filename = (char *) NULL;
   67     image->params   = (char *) NULL;
   68     image->dpi_x    = 0;
   69     image->dpi_y    = 0;
   70     image->strips   = 1;
   71     image->rowsperstrip = 1;
   72     image->colorspace   = pdc_undef;
   73     image->dochandle    = pdc_undef;        /* this means "not a PDI page" */
   74     image->use_raw  = pdc_false;
   75     image->pixelmode    = pdc_undef;
   76     image->type     = pdf_img_auto;
   77     image->transval[0]  = 0;
   78     image->transval[1]  = 0;
   79     image->transval[2]  = 0;
   80     image->transval[3]  = 0;
   81 
   82 
   83     /********* image-type specific stuff *****/
   84     /* This is ugly, but we must do it here since both the TIFF and JPEG
   85      * modules are affected.
   86      */
   87     image->info.jpeg.jpegifoffset = 0L;
   88 }
   89 
   90 void
   91 pdf_init_images(PDF *p)
   92 {
   93     int im;
   94 
   95     p->images_capacity = IMAGES_CHUNKSIZE;
   96 
   97     p->images = (pdf_image *)
   98         pdc_malloc(p->pdc,
   99         sizeof(pdf_image) * p->images_capacity, "pdf_init_images");
  100 
  101     for (im = 0; im < p->images_capacity; im++)
  102     pdf_init_image_struct(p, &(p->images[im]));
  103 }
  104 
  105 void
  106 pdf_grow_images(PDF *p)
  107 {
  108     int im;
  109 
  110     p->images = (pdf_image *) pdc_realloc(p->pdc, p->images,
  111     sizeof(pdf_image) * 2 * p->images_capacity, "pdf_grow_images");
  112 
  113     for (im = p->images_capacity; im < 2 * p->images_capacity; im++)
  114     pdf_init_image_struct(p, &(p->images[im]));
  115     for (im = 0; im < p->images_capacity; im++)
  116     p->images[im].src.private_data = &(p->images[im]);
  117 
  118     p->images_capacity *= 2;
  119 }
  120 
  121 void
  122 pdf_cleanup_image(PDF *p, int im)
  123 {
  124     pdf_image *image = &p->images[im];
  125 
  126     /* clean up parameter string if necessary */
  127     if (image->params)
  128     {
  129         pdc_free(p->pdc, image->params);
  130         image->params = NULL;
  131     }
  132 
  133     if (image->filename)
  134     {
  135         pdc_free(p->pdc, image->filename);
  136         image->filename = NULL;
  137     }
  138 
  139     if (image->fp)
  140     {
  141         pdc_fclose(image->fp);
  142         image->fp = NULL;
  143     }
  144 
  145     if (image->iconname)
  146     {
  147         pdc_free(p->pdc, image->iconname);
  148         image->iconname = NULL;
  149     }
  150 
  151 
  152 
  153     /* type-specific cleanups */
  154     if (image->type == pdf_img_gif)
  155     pdf_cleanup_gif(p, image);
  156 
  157     if (image->type == pdf_img_jpeg)
  158         pdf_cleanup_jpeg(p, image);
  159 
  160     /* free the image slot and prepare for next use */
  161     pdf_init_image_struct(p, image);
  162 }
  163 
  164 void
  165 pdf_cleanup_images(PDF *p)
  166 {
  167     int im;
  168 
  169     if (!p->images)
  170     return;
  171 
  172     /* Free images which the caller left open */
  173 
  174     /* When we think of inter-document survival of images,
  175     ** we MUST NOT FORGET that the current TIFF algorithm
  176     ** depends on contiguous image slots for the image strips!
  177     */
  178     for (im = 0; im < p->images_capacity; im++)
  179     {
  180         if (p->images[im].in_use)              /* found used slot */
  181         pdf_cleanup_image(p, im);   /* free image descriptor */
  182     }
  183 
  184     pdc_free(p->pdc, p->images);
  185     p->images = NULL;
  186 }
  187 
  188 void
  189 pdf_init_xobjects(PDF *p)
  190 {
  191     int idx;
  192 
  193     p->xobjects_number = 0;
  194 
  195     if (p->xobjects == (pdf_xobject *) 0)
  196     {
  197     p->xobjects_capacity = XOBJECTS_CHUNKSIZE;
  198 
  199     p->xobjects = (pdf_xobject *)
  200         pdc_malloc(p->pdc, sizeof(pdf_xobject) * p->xobjects_capacity,
  201         "pdf_init_xobjects");
  202     }
  203 
  204     for (idx = 0; idx < p->xobjects_capacity; idx++)
  205     p->xobjects[idx].flags = 0;
  206 }
  207 
  208 int
  209 pdf_new_xobject(PDF *p, pdf_xobj_type type, pdc_id obj_id)
  210 {
  211     static const char fn[] = "pdf_new_xobject";
  212     int i, slot = p->xobjects_number++;
  213 
  214     if (slot == p->xobjects_capacity)
  215     {
  216     p->xobjects = (pdf_xobject *) pdc_realloc(p->pdc, p->xobjects,
  217         sizeof(pdf_xobject) * 2 * p->xobjects_capacity, fn);
  218 
  219     for (i = p->xobjects_capacity; i < 2 * p->xobjects_capacity; i++)
  220         p->xobjects[i].flags = 0;
  221 
  222     p->xobjects_capacity *= 2;
  223     }
  224 
  225     if (obj_id == PDC_NEW_ID)
  226     obj_id = pdc_begin_obj(p->out, PDC_NEW_ID);
  227 
  228     p->xobjects[slot].obj_id = obj_id;
  229     p->xobjects[slot].type = type;
  230     p->xobjects[slot].flags = xobj_flag_used;
  231 
  232     return slot;
  233 }
  234 
  235 pdc_id
  236 pdf_get_xobject(PDF *p, int im)
  237 {
  238     if (im >= 0 && im < p->images_capacity)
  239     {
  240         pdf_image *img = &p->images[im];
  241 
  242         if (img->in_use)
  243             return p->xobjects[img->no].obj_id;
  244     }
  245     return PDC_BAD_ID;
  246 }
  247 
  248 void
  249 pdf_write_xobjects(PDF *p)
  250 {
  251     if (p->xobjects_number > 0)
  252     {
  253     pdc_bool hit = pdc_false;
  254     int i;
  255 
  256     for (i = 0; i < p->xobjects_number; ++i)
  257     {
  258         if (p->xobjects[i].flags & xobj_flag_write)
  259         {
  260         if (!hit)
  261         {
  262             pdc_puts(p->out, "/XObject");
  263             pdc_begin_dict(p->out);
  264             hit = pdc_true;
  265         }
  266 
  267         pdc_printf(p->out, "/I%d", i);
  268         pdc_objref(p->out, "", p->xobjects[i].obj_id);
  269         p->xobjects[i].flags &= ~xobj_flag_write;
  270         }
  271     }
  272 
  273     if (hit)
  274         pdc_end_dict(p->out);
  275     }
  276 }
  277 
  278 void
  279 pdf_get_page_xobjects(PDF *p, pdf_reslist *rl)
  280 {
  281     int i;
  282 
  283     for (i = 0; i < p->xobjects_number; i++) {
  284     if (p->xobjects[i].flags & xobj_flag_write) {
  285         p->xobjects[i].flags &= ~xobj_flag_write;
  286         pdf_add_reslist(p, rl, i);
  287     }
  288     }
  289 }
  290 
  291 void
  292 pdf_mark_page_xobject(PDF *p, int n)
  293 {
  294     p->xobjects[n].flags |= xobj_flag_write;
  295 }
  296 
  297 void
  298 pdf_cleanup_xobjects(PDF *p)
  299 {
  300     if (p->xobjects) {
  301     pdc_free(p->pdc, p->xobjects);
  302     p->xobjects = NULL;
  303     }
  304 }
  305 
  306 
  307 /* ---------------------------- put image ----------------------------------- */
  308 
  309 void
  310 pdf_put_inline_image(PDF *p, int im)
  311 {
  312     static const char *fn = "pdf_put_inline_image";
  313     pdf_image   *image;
  314     pdc_matrix m;
  315     PDF_data_source *src;
  316     int     i;
  317 
  318     image = &p->images[im];
  319 
  320     /* Image object */
  321 
  322     image->no = -1;
  323 
  324     pdf__save(p);
  325 
  326     pdc_scale_matrix(image->width, image->height, &m);
  327 
  328     pdf_concat_raw(p, &m);
  329 
  330     pdc_puts(p->out, "BI");
  331 
  332     pdc_printf(p->out, "/W %d", (int) image->width);
  333     pdc_printf(p->out, "/H %d", (int) image->height);
  334 
  335     /* Acrobat 7 and 8 require /BPC even for image masks */
  336     pdc_printf(p->out, "/BPC %d", image->bpc);
  337 
  338     if (image->imagemask == pdc_true) {
  339     pdc_puts(p->out, "/IM true");
  340 
  341     } else if (image->colorspace != pdc_undef) {
  342 
  343     switch (p->colorspaces[image->colorspace].type) {
  344         case DeviceGray:
  345         pdc_printf(p->out, "/CS/G");
  346         break;
  347 
  348         case DeviceRGB:
  349         pdc_printf(p->out, "/CS/RGB");
  350         break;
  351 
  352         case DeviceCMYK:
  353         pdc_printf(p->out, "/CS/CMYK");
  354         break;
  355 
  356         default:
  357         pdc_error(p->pdc, PDF_E_INT_BADCS, fn,
  358             pdc_errprintf(p->pdc, "%d", image->colorspace),
  359             pdc_errprintf(p->pdc, "%d",
  360                 (int) p->colorspaces[image->colorspace].type),
  361             0);
  362         break;
  363     }
  364     }
  365 
  366     if (image->compression != pdf_comp_none) {
  367     pdc_printf(p->out, "/F/%s",
  368             pdc_get_keyword(image->compression, pdf_shortfilter_pdfkeylist));
  369     }
  370 
  371     /* prepare precompressed (raw) image data */
  372     if (image->use_raw &&
  373         (image->params ||
  374      image->predictor != pred_default ||
  375          image->compression == pdf_comp_ccitt)) {
  376 
  377     pdc_printf(p->out, "/DP[<<");
  378 
  379         /* write EarlyChange */
  380         if (image->params)
  381             pdc_puts(p->out, image->params);
  382 
  383         if (image->compression == pdf_comp_ccitt) {
  384             if (image->K != 0)
  385                 pdc_printf(p->out, "/K %d", image->K);
  386         }
  387 
  388         if (image->compression == pdf_comp_flate ||
  389             image->compression == pdf_comp_lzw) {
  390         if (image->predictor != pred_default) {
  391         pdc_printf(p->out, "/Predictor %d", (int) image->predictor);
  392         pdc_printf(p->out, "/Columns %d", (int) image->width);
  393         if (image->bpc != 8)
  394             pdc_printf(p->out, "/BitsPerComponent %d", image->bpc);
  395 
  396         if (image->components != 1) /* 1 is default */
  397             pdc_printf(p->out, "/Colors %d", image->components);
  398         }
  399     }
  400 
  401         if (image->compression == pdf_comp_ccitt) {
  402         if ((int) image->width != 1728) /* CCITT default width */
  403         pdc_printf(p->out, "/Columns %d", (int) image->width);
  404 
  405         /* /Rows is optional, but it helps in certain cases with damaged
  406          * CCITT compressed image data
  407          */
  408         pdc_printf(p->out, "/Rows %d", (int) fabs(image->height));
  409     }
  410     pdc_puts(p->out, ">>]");        /* DecodeParms dict and array */
  411     }
  412 
  413     if (image->ri != AutoIntent) {
  414         pdc_printf(p->out, "/Intent/%s",
  415             pdc_get_keyword(image->ri, pdf_renderingintent_pdfkeylist));
  416     }
  417 
  418     if (image->interpolate) {
  419         pdc_puts(p->out, "/I true");
  420     }
  421 
  422     if (image->invert) {
  423     pdc_puts(p->out, "/D[1 0");
  424     for (i = 1; i < image->components; i++)
  425         pdc_puts(p->out, " 1 0");
  426     pdc_puts(p->out, "]ID\n");
  427 
  428     } else {
  429     pdc_puts(p->out, " ID\n");
  430     }
  431 
  432     /* Write the actual image data to the content stream */
  433 
  434     src = &image->src;
  435 
  436     /* We can't use pdf_copy_stream() here because it automatically
  437      * generates a stream object, which is not correct for inline
  438      * image data.
  439      */
  440     if (src->init)
  441     src->init(p, src);
  442 
  443     while (src->fill(p, src))
  444     pdc_write(p->out, src->next_byte, src->bytes_available);
  445 
  446     if (src->terminate)
  447     src->terminate(p, src);
  448 
  449     /* Acrobat requires whitespace between image data and "EI" */
  450     pdc_puts(p->out, "\nEI\n");
  451 
  452     pdf__restore(p);
  453 
  454     /* Do the equivalent of PDF_close_image() since the image handle
  455      * cannot be re-used anyway.
  456      */
  457     pdf_cleanup_image(p, im);
  458 }
  459 
  460 void
  461 pdf_put_image(PDF *p, int im, pdc_bool firststrip, pdc_bool checkcontentstream)
  462 {
  463     static const char *fn = "pdf_put_image";
  464     pdc_bool logg3 = pdc_logg_is_enabled(p->pdc, 3, trc_image);
  465     pdc_id  length_id;
  466     pdf_image   *image;
  467     int     i;
  468     pdf_compression compression;
  469 
  470     image = &p->images[im];
  471 
  472     if (logg3)
  473         pdc_logg(p->pdc, "\t\t\tput image %d to PDF file ...\n", im);
  474 
  475     /* Images may also be written to the output before the first page */
  476     if (checkcontentstream && PDF_GET_STATE(p) == pdf_state_page)
  477     pdf_end_contents_section(p);
  478 
  479 
  480 
  481     pdc_logg_cond(p->pdc, 2, trc_image,
  482                        "\tpdf_put_image:\n"
  483                        "\t\t\tim = %d\n"
  484                        "\t\t\timage->colorspace = %d\n",
  485                im,
  486                image->colorspace);
  487 
  488     if (image->colorspace != pdc_undef)
  489         pdc_logg_cond(p->pdc, 2, trc_image,
  490                       "\t\t\tcolor space type = %d\n",
  491               (int) p->colorspaces[image->colorspace].type);
  492 
  493     /* Image object */
  494 
  495     image->no = pdf_new_xobject(p, image_xobject, PDC_NEW_ID);
  496 
  497     pdc_begin_dict(p->out);         /* XObject */
  498 
  499     pdc_puts(p->out, "/Subtype/Image\n");
  500 
  501     pdc_printf(p->out, "/Width %d\n", (int) image->width);
  502     pdc_printf(p->out, "/Height %d\n", (int) fabs(image->height));
  503 
  504     /*
  505      * Transparency handling
  506      */
  507 
  508     /* Masking by color: single transparent color value */
  509     if (image->transparent && image->colorspace != pdc_undef) {
  510     pdf_colorspace *cs = &p->colorspaces[image->colorspace];
  511 
  512     switch (cs->type) {
  513         case Indexed:
  514         case DeviceGray:
  515         pdc_printf(p->out,"/Mask[%d %d]\n",
  516         (int) image->transval[0], (int) image->transval[0]);
  517         break;
  518 
  519 
  520         case DeviceRGB:
  521         pdc_printf(p->out,"/Mask[%d %d %d %d %d %d]\n",
  522         (int) image->transval[0], (int) image->transval[0],
  523         (int) image->transval[1], (int) image->transval[1],
  524         (int) image->transval[2], (int) image->transval[2]);
  525         break;
  526 
  527         case DeviceCMYK:
  528         pdc_printf(p->out,"/Mask[%d %d %d %d %d %d %d %d]\n",
  529         (int) image->transval[0], (int) image->transval[0],
  530         (int) image->transval[1], (int) image->transval[1],
  531         (int) image->transval[2], (int) image->transval[2],
  532         (int) image->transval[3], (int) image->transval[3]);
  533         break;
  534 
  535         default:
  536         pdc_error(p->pdc, PDF_E_INT_BADCS, fn,
  537         pdc_errprintf(p->pdc, "%d", image->colorspace),
  538         pdc_errprintf(p->pdc, "%d",
  539             (int) p->colorspaces[image->colorspace].type),
  540         0);
  541     }
  542 
  543     /* Masking by position: separate bitmap mask */
  544     } else if (image->mask != pdc_undef && p->images[image->mask].bpc > 1) {
  545         pdc_objref(p->out, "/SMask",
  546             p->xobjects[p->images[image->mask].no].obj_id);
  547 
  548     } else if (image->mask != pdc_undef) {
  549         pdc_objref(p->out, "/Mask",
  550             p->xobjects[p->images[image->mask].no].obj_id);
  551     }
  552 
  553     /*
  554      * /BitsPerComponent is optional for image masks according to the
  555      * PDF reference, but some viewers require it nevertheless.
  556      * We must therefore always write it.
  557      */
  558     if (image->type != pdf_img_jpeg2000)
  559         pdc_printf(p->out, "/BitsPerComponent %d\n", image->bpc);
  560 
  561     if (image->imagemask) {
  562     pdc_puts(p->out, "/ImageMask true\n");
  563         if (image->type == pdf_img_jpeg2000)
  564             pdc_puts(p->out, "/SMaskInData 1\n");
  565 
  566     } else if (image->colorspace != pdc_undef) {
  567 
  568     switch (p->colorspaces[image->colorspace].type) {
  569         case DeviceGray:
  570         break;
  571 
  572         case DeviceRGB:
  573         break;
  574 
  575         case DeviceCMYK:
  576         break;
  577 
  578         case Indexed:
  579         break;
  580 
  581 
  582 
  583         default:
  584         pdc_error(p->pdc, PDF_E_INT_BADCS, fn,
  585             pdc_errprintf(p->pdc, "%d", image->colorspace),
  586             pdc_errprintf(p->pdc, "%d",
  587                 (int) p->colorspaces[image->colorspace].type),
  588             0);
  589         }
  590 
  591         pdc_puts(p->out, "/ColorSpace");
  592         pdf_write_colorspace(p, image->colorspace, pdc_false);
  593         pdc_puts(p->out, "\n");
  594     }
  595 
  596     if (image->invert) {
  597         pdc_puts(p->out, "/Decode[1 0");
  598         for (i = 1; i < image->components; i++)
  599             pdc_puts(p->out, " 1 0");
  600     pdc_end_array(p->out);
  601     }
  602 
  603     if (image->ri != AutoIntent) {
  604         pdc_printf(p->out, "/Intent/%s\n",
  605             pdc_get_keyword(image->ri, pdf_renderingintent_pdfkeylist));
  606     }
  607 
  608     if (image->interpolate) {
  609         pdc_puts(p->out, "/Interpolate true\n");
  610     }
  611 
  612     /* special case: referenced image data instead of direct data */
  613     if (image->reference != pdf_ref_direct) {
  614 
  615         if (image->compression != pdf_comp_none) {
  616         pdc_printf(p->out, "/FFilter[/%s]\n",
  617                 pdc_get_keyword(image->compression, pdf_filter_pdfkeylist));
  618     }
  619 
  620         if (image->compression == pdf_comp_ccitt) {
  621         pdc_puts(p->out, "/FDecodeParms[<<");
  622 
  623         if ((int) image->width != 1728) /* CCITT default width */
  624         pdc_printf(p->out, "/Columns %d", (int) image->width);
  625 
  626         /* /Rows is optional, but it helps in certain cases with damaged
  627          * CCITT compressed image data
  628          */
  629         pdc_printf(p->out, "/Rows %d", (int) fabs(image->height));
  630 
  631             if (image->K != 0)
  632                 pdc_printf(p->out, "/K %d", image->K);
  633 
  634         pdc_puts(p->out, ">>]\n");
  635 
  636     }
  637 
  638     if (image->reference == pdf_ref_file) {
  639 
  640         /* LATER: make image file name platform-neutral:
  641          * Change : to / on the Mac
  642          * Change \ to / on Windows
  643          */
  644         pdc_puts(p->out, "/F");
  645         pdc_put_pdfstring(p->out, image->filename, 0);
  646             pdc_puts(p->out, "/Length 0");
  647 
  648     } else if (image->reference == pdf_ref_url) {
  649 
  650         pdc_puts(p->out, "/F<</FS/URL/F");
  651         pdc_put_pdfstring(p->out, image->filename, 0);
  652         pdc_puts(p->out, ">>/Length 0");
  653     }
  654 
  655     pdc_end_dict(p->out);       /* XObject */
  656 
  657     /* We must avoid pdc_begin/end_pdfstream() here in order to
  658      * generate a really empty stream.
  659      * Note: this doesn't work with AES encryption, but we don't
  660      * bother to fix it since file references are no longer
  661      * supported anyway.
  662      */
  663     pdc_puts(p->out, "stream\n");   /* dummy image stream */
  664     pdc_puts(p->out, "endstream\n");
  665 
  666         pdc_end_obj(p->out);                    /* XObject */
  667 
  668     if (PDF_GET_STATE(p) == pdf_state_page)
  669         pdf_begin_contents_section(p);
  670 
  671     return;
  672     }
  673 
  674     compression = image->compression;
  675 
  676     /*
  677      * Now the (more common) handling of actual image
  678      * data to be included in the PDF output.
  679      */
  680 
  681     /* force compression if not a recognized precompressed image format */
  682     if ((!image->use_raw || compression == pdf_comp_none) &&
  683     pdc_get_compresslevel(p->out))
  684         compression = pdf_comp_flate;
  685 
  686     if (compression != pdf_comp_none)
  687     pdc_printf(p->out, "/Filter/%s\n",
  688                    pdc_get_keyword(compression, pdf_filter_pdfkeylist));
  689 
  690     /* prepare precompressed (raw) image data; avoid empty DecodeParms */
  691     if (image->use_raw &&
  692         (image->params ||
  693      image->predictor != pred_default ||
  694          compression == pdf_comp_ccitt)) {
  695 
  696     pdc_printf(p->out, "/DecodeParms<<");
  697 
  698         /* write EarlyChange */
  699         if (image->params)
  700             pdc_puts(p->out, image->params);
  701 
  702         if (compression == pdf_comp_ccitt) {
  703             if (image->K != 0)
  704                 pdc_printf(p->out, "/K %d", image->K);
  705         }
  706 
  707         if (compression == pdf_comp_flate || compression == pdf_comp_lzw) {
  708         if (image->predictor != pred_default) {
  709         pdc_printf(p->out, "/Predictor %d", (int) image->predictor);
  710         pdc_printf(p->out, "/Columns %d", (int) image->width);
  711         if (image->bpc != 8)
  712             pdc_printf(p->out, "/BitsPerComponent %d", image->bpc);
  713 
  714         if (image->components != 1) /* 1 is default */
  715             pdc_printf(p->out, "/Colors %d", image->components);
  716         }
  717     }
  718 
  719         if (compression == pdf_comp_ccitt) {
  720         if ((int) image->width != 1728) /* CCITT default width */
  721         pdc_printf(p->out, "/Columns %d", (int) image->width);
  722 
  723         /* /Rows is optional, but it helps in certain cases with damaged
  724          * CCITT compressed image data
  725          */
  726         pdc_printf(p->out, "/Rows %d", (int) fabs(image->height));
  727     }
  728 
  729     pdc_puts(p->out, ">>\n");       /* DecodeParms dict */
  730     }
  731 
  732 
  733 
  734 
  735     /* Write the actual image data */
  736     length_id = pdc_alloc_id(p->out);
  737 
  738     pdc_objref(p->out, "/Length", length_id);
  739     pdc_end_dict(p->out);       /* XObject */
  740 
  741     /* image data */
  742 
  743     /*
  744      * We must check "image->compression" here since this describes the
  745      * actual status of the input data, as opposed to "compression"
  746      * which describes the desired status of the output data.
  747      */
  748 
  749     pdf_copy_stream(p, &image->src,
  750             !image->use_raw || image->compression == pdf_comp_none);
  751 
  752     pdc_end_obj(p->out);    /* XObject */
  753 
  754     pdc_put_pdfstreamlength(p->out, length_id);
  755 
  756     if (p->flush & pdc_flush_content)
  757     pdc_flush_stream(p->out);
  758 
  759     /*
  760      * Write colormap information for indexed color spaces
  761      */
  762     if (firststrip && image->colorspace != pdc_undef &&
  763         p->colorspaces[image->colorspace].type == Indexed) {
  764     pdf_write_colormap(p, image->colorspace);
  765     }
  766 
  767     if (checkcontentstream && PDF_GET_STATE(p) == pdf_state_page)
  768     pdf_begin_contents_section(p);
  769 
  770     if (p->flush & pdc_flush_content)
  771     pdc_flush_stream(p->out);
  772 }
  773 
  774 
  775 /* ---------------------------- fit image ----------------------------------- */
  776 
  777 void
  778 pdf__fit_image(PDF *p, int im, pdc_scalar x, pdc_scalar y, const char *optlist)
  779 {
  780     pdf_image *image;
  781     int legal_states;
  782 
  783     pdf_check_handle(p, im, pdc_imagehandle);
  784 
  785     image = &p->images[im];
  786 
  787     if (PDF_GET_STATE(p) == pdf_state_glyph && !pdf_get_t3colorized(p) &&
  788         image->imagemask == pdc_false)
  789         legal_states = pdf_state_page | pdf_state_pattern | pdf_state_template;
  790     else if (PDF_GET_STATE(p) == pdf_state_pattern &&
  791         pdf_get_shading_painttype(p) == 2 && image->imagemask == pdc_false)
  792         legal_states = pdf_state_page | pdf_state_glyph | pdf_state_template;
  793     else
  794         legal_states = pdf_state_content;
  795     PDF_CHECK_STATE(p, legal_states);
  796 
  797     if (PDF_GET_STATE(p) == pdf_state_template && im == p->templ)
  798         pdc_error(p->pdc, PDF_E_TEMPLATE_SELF,
  799             pdc_errprintf(p->pdc, "%d", im), 0, 0, 0);
  800 
  801     pdc_check_number(p->pdc, "x", x);
  802     pdc_check_number(p->pdc, "y", y);
  803 
  804     pdf_place_xobject(p, im, x, y, optlist);
  805 }
  806 
  807 void
  808 pdf_init_xobject_options(PDF *p, pdf_xobject_options *xo)
  809 {
  810     xo->adjustpage = pdc_false;
  811     xo->blind = pdc_false;
  812     xo->filename = NULL;
  813     xo->flags = 0;
  814     xo->imagewarning = p->debug[(int) 'i'];
  815     xo->ignoreorientation = pdc_false;
  816     xo->im = -1;
  817     xo->mask = 0;
  818     xo->dpi[0] = 0;
  819     xo->dpi[1] = 0;
  820     xo->page = 1;
  821     xo->scale[0] = 1;
  822     xo->scale[1] = 1;
  823 }
  824 
  825 void
  826 pdf_get_xobject_options(PDF *p, pdf_xobject_options *xo, pdc_resopt *resopts)
  827 {
  828     int inum;
  829 
  830     (void) p;
  831 
  832     if (!(xo->flags & is_block))
  833     {
  834         pdc_get_optvalues("adjustpage", resopts, &xo->adjustpage, NULL);
  835 
  836         pdc_get_optvalues("blind", resopts, &xo->blind, NULL);
  837     }
  838 
  839     if (xo->flags & is_image)
  840     {
  841         if (pdc_get_optvalues("ignoreorientation", resopts,
  842                                                 &xo->ignoreorientation, NULL))
  843             xo->mask |= (1L << xo_ignoreorientation);
  844 
  845 
  846         inum = pdc_get_optvalues("dpi", resopts, xo->dpi, NULL);
  847         if (inum)
  848         {
  849             if (inum == 1)
  850                 xo->dpi[1] = xo->dpi[0];
  851             xo->mask |= (1L << xo_dpi);
  852         }
  853     }
  854 
  855     if (xo->flags & is_block)
  856     {
  857         if (pdc_get_optvalues("imagewarning", resopts, &xo->imagewarning, NULL))
  858             xo->mask |= (1L << xo_imagewarning);
  859     }
  860 
  861     inum = pdc_get_optvalues("scale", resopts, xo->scale, NULL);
  862     if (inum)
  863     {
  864         if (inum == 1)
  865             xo->scale[1] = xo->scale[0];
  866         xo->mask |= (1L << xo_scale);
  867     }
  868 }
  869 
  870 /* definitions of fit xobject options */
  871 static const pdc_defopt pdf_fit_xobject_options[] =
  872 {
  873     PDF_XOBJECT_OPTIONS1
  874     PDF_XOBJECT_OPTIONS2
  875     PDF_XOBJECT_OPTIONS3
  876     PDF_FIT_OPTIONS1
  877     PDF_FIT_OPTIONS2
  878     PDC_OPT_TERMINATE
  879 };
  880 
  881 pdc_resopt *
  882 pdf_parse_fitxobject_optlist(PDF *p, int im, pdf_xobject_options *xo,
  883                              pdf_fit_options *fit, const char *optlist)
  884 {
  885     pdc_resopt *resopts = NULL;
  886     pdf_image *image = &p->images[im];
  887 
  888     /* initialize */
  889     pdf_init_xobject_options(p, xo);
  890     xo->im = im;
  891     if (p->xobjects[image->no].type == image_xobject)
  892     {
  893         xo->flags |= is_image;
  894         xo->dpi[0] = dpi_internal;
  895         xo->dpi[1] = dpi_internal;
  896         xo->ignoreorientation = image->ignoreorient;
  897     }
  898     pdf_init_fit_options(p, pdc_false, fit);
  899     fit->flags |= is_image;
  900 
  901     /* parsing option list */
  902     if (optlist && strlen(optlist))
  903     {
  904         pdc_clientdata data;
  905 
  906         pdf_set_clientdata(p, &data);
  907         resopts = pdc_parse_optionlist(p->pdc, optlist,
  908                       pdf_fit_xobject_options, &data, pdc_true);
  909 
  910         pdf_get_xobject_options(p, xo, resopts);
  911         pdf_get_fit_options(p, pdc_false, fit, resopts);
  912     }
  913 
  914     return resopts;
  915 }
  916 
  917 void
  918 pdf_place_xobject(PDF *p, int im, pdc_scalar x, pdc_scalar y,
  919                   const char *optlist)
  920 {
  921     pdf_xobject_options xo;
  922     pdf_fit_options fit;
  923 
  924     /* initialize */
  925     pdf_parse_fitxobject_optlist(p, im, &xo, &fit, optlist);
  926     fit.refpoint[0] = x;
  927     fit.refpoint[1] = y;
  928 
  929     /* put out xobject */
  930     if (!xo.blind)
  931     {
  932         pdf_end_text(p);
  933         pdf_begin_contents_section(p);
  934 
  935 
  936 
  937         pdf__save(p);
  938     }
  939 
  940     pdf_fit_xobject_internal(p, &xo, &fit, NULL);
  941 
  942     if (!xo.blind)
  943         pdf__restore(p);
  944 }
  945 
  946 void
  947 pdf_fit_xobject_internal(PDF *p, pdf_xobject_options *xo, pdf_fit_options *fit,
  948                          pdc_matrix *immatrix)
  949 {
  950     pdc_bool logg3 = pdc_logg_is_enabled(p->pdc, 3, trc_image);
  951     pdf_image *image = &p->images[xo->im];
  952     pdf_xobject_options xo_save;
  953     pdc_rectangle matchrect;
  954     pdf_fit_options fit_save;
  955     pdc_matrix m, mm, sm, ctm_clip, ctm_save;
  956     pdc_vector tmpscale, elemscale, fitscale, purescale;
  957     pdc_vector elemsize, mirror, shift, relpos;
  958     pdc_vector polyline[5];
  959     pdc_box fitbox, clipbox, elembox, redbox;
  960     pdc_scalar x, y, ss;
  961     pdc_scalar rowsize = 1, lastratio = 1;
  962     pdc_scalar dpi_x, dpi_y, tx = 0, ty = 0, boxwidth, boxheight;
  963     pdc_bool kclip = pdc_false, kcliptiff = pdc_false;
  964     int indangle, indmirror;
  965     int is, ip, islast;
  966     int imageno;
  967 
  968     /* initialize */
  969     tmpscale.x = 1;
  970     tmpscale.y = 1;
  971     if (image->mask != pdc_undef)
  972     {
  973         ctm_save = p->curr_ppt->gstate[p->curr_ppt->sl].ctm;
  974         xo_save = *xo;
  975         fit_save = *fit;
  976     }
  977     else
  978     {
  979         pdc_identity_matrix(&ctm_save);
  980     }
  981 
  982     /* box size */
  983     boxwidth = fit->boxsize[0];
  984     boxheight = fit->boxsize[1];
  985 
  986     /* element size */
  987     elemsize.x = fabs(image->width);
  988     elemsize.y = fabs(image->height);
  989 
  990     if (logg3)
  991         pdc_logg(p->pdc,
  992                  "\t\t\tfitbox size:  width=%g, height=%g\n"
  993                  "\t\t\telement size: width=%g, height=%g\n",
  994                  boxwidth, boxheight, elemsize.x, elemsize.y);
  995 
  996     /* clipping */
  997     if (!kclip)
  998     {
  999         kclip = pdf_get_mbox_clipping(p, fit->matchbox, elemsize.x, elemsize.y,
 1000                                       &clipbox);
 1001     }
 1002 
 1003     if (logg3 && kclip)
 1004         pdc_logg(p->pdc,
 1005                  "\t\t\tclip box: llx=%g, lly=%g, urx=%g, ury=%g\n",
 1006                  clipbox.ll.x, clipbox.ll.y, clipbox.ur.x, clipbox.ur.y);
 1007 
 1008     /* TIFF image orientation */
 1009     if (image->orientation != 1 && !xo->ignoreorientation)
 1010     {
 1011         /* Tag Orientation     =  1,   2,   3,   4,   5,   6,   7,   8  */
 1012         const int addangle[8]  = {0,   0, 180, 180,  90, 270, 270,  90};
 1013         const int rowmirror[8] = {1,  -1,   1,  -1,  -1,   1,  -1,   1};
 1014 
 1015         if (logg3)
 1016             pdc_logg(p->pdc, "\t\t\torientation tag: %d\n", image->orientation);
 1017 
 1018         is = image->orientation - 1;
 1019 
 1020     fit->orientate += addangle[is];
 1021     if (fit->orientate >= 360)
 1022         fit->orientate -= 360;
 1023         tmpscale.x = rowmirror[is];
 1024 
 1025         if (kclip)
 1026         {
 1027             switch (addangle[is])
 1028             {
 1029                 default:
 1030                 elembox = clipbox;
 1031                 break;
 1032 
 1033                 case 90:
 1034                 elembox.ll.x = clipbox.ll.y;
 1035                 elembox.ll.y = elemsize.x - clipbox.ur.x;
 1036                 elembox.ur.x = clipbox.ur.y;
 1037                 elembox.ur.y = elemsize.x - clipbox.ll.x;
 1038                 break;
 1039 
 1040                 case 180:
 1041                 elembox.ll.x = elemsize.x - clipbox.ur.x;
 1042                 elembox.ll.y = elemsize.y - clipbox.ur.y;
 1043                 elembox.ur.x = elemsize.x - clipbox.ll.x;
 1044                 elembox.ur.y = elemsize.y - clipbox.ll.y;
 1045                 break;
 1046 
 1047                 case 270:
 1048                 elembox.ll.x = elemsize.y - clipbox.ur.y;
 1049                 elembox.ll.y = clipbox.ll.x;
 1050                 elembox.ur.x = elemsize.y - clipbox.ll.y;
 1051                 elembox.ur.y = clipbox.ur.x;
 1052                 break;
 1053             }
 1054             clipbox = elembox;
 1055 
 1056             if (tmpscale.x == -1)
 1057             {
 1058                 clipbox.ll.x = elemsize.x - elembox.ur.x;
 1059                 clipbox.ur.x = elemsize.x - elembox.ll.x;
 1060             }
 1061         }
 1062     }
 1063 
 1064     /* Compensate inverted direction handling in TIFFReadRGBAImageOriented() */
 1065     if (!image->use_raw && image->pixelmode == pdc_true)
 1066     {
 1067         tmpscale.y = -1;
 1068         elembox = clipbox;
 1069         clipbox.ll.y = elemsize.y - elembox.ur.y;
 1070         clipbox.ur.y = elemsize.y - elembox.ll.y;
 1071     }
 1072 
 1073     if (logg3 && kclip)
 1074         pdc_logg(p->pdc,
 1075                  "\t\t\tclip box: llx=%g, lly=%g, urx=%g, ury=%g  "
 1076                  "(corrected)\n",
 1077                  clipbox.ll.x, clipbox.ll.y, clipbox.ur.x, clipbox.ur.y);
 1078 
 1079     /* image scale */
 1080     elemscale.x = tmpscale.x * xo->scale[0];
 1081     elemscale.y = tmpscale.y * xo->scale[1];
 1082 
 1083     if (logg3)
 1084         pdc_logg(p->pdc,
 1085                  "\t\t\telement scaling: sx=%g, sy=%g  "
 1086                  "(user, correction mirroring)\n",
 1087                  elemscale.x, elemscale.y);
 1088 
 1089     /* element size */
 1090     elemsize.x = fabs(clipbox.ur.x - clipbox.ll.x);
 1091     elemsize.y = fabs(clipbox.ur.y - clipbox.ll.y);
 1092 
 1093     /* calculation of image scale and size */
 1094     if (xo->flags & is_image)
 1095     {
 1096         tmpscale.x = 1.0;
 1097         tmpscale.y = 1.0;
 1098         if (xo->dpi[0] == dpi_internal)
 1099         {
 1100             dpi_x = image->dpi_x;
 1101             dpi_y = image->dpi_y;
 1102             if (dpi_x > 0 && dpi_y > 0)
 1103             {
 1104                 tmpscale.x = 72.0 / dpi_x;
 1105                 tmpscale.y = 72.0 / dpi_y;
 1106             }
 1107             else if (dpi_x < 0 && dpi_y < 0)
 1108             {
 1109                 tmpscale.y = dpi_y / dpi_x;
 1110             }
 1111         }
 1112         else if (xo->dpi[0] > 0)
 1113         {
 1114             tmpscale.x = 72.0 / xo->dpi[0];
 1115             tmpscale.y = 72.0 / xo->dpi[1];
 1116         }
 1117 
 1118         elemscale.x *= tmpscale.x;
 1119         elemscale.y *= tmpscale.y;
 1120         rowsize = elemscale.y * image->rowsperstrip;
 1121 
 1122         if (logg3)
 1123             pdc_logg(p->pdc,
 1124                "\t\t\telement scaling: sx=%g, sy=%g  "
 1125                "(relating to 72dpi)\n",
 1126                tmpscale.x, tmpscale.y);
 1127     }
 1128 
 1129     /* pure scaling without mirroring */
 1130     purescale.x = fabs(elemscale.x);
 1131     purescale.y = fabs(elemscale.y);
 1132 
 1133     /* element size */
 1134     elemsize.x *= purescale.x;
 1135     elemsize.y *= purescale.y;
 1136 
 1137     if (logg3)
 1138         pdc_logg(p->pdc,
 1139                  "\t\t\telement size: width=%g, height=%g  (scaled)\n",
 1140                  elemsize.x, elemsize.y);
 1141 
 1142     if (xo->flags & is_image)
 1143     {
 1144         elemscale.x *= image->width;
 1145         elemscale.y *= image->height;
 1146         lastratio = (elemscale.y / rowsize) - (image->strips - 1);
 1147     }
 1148 
 1149     /* mirroring */
 1150     indmirror = 0;
 1151     if (elemscale.x < 0 && elemscale.y < 0)
 1152         indmirror = 2;
 1153     else if (elemscale.x < 0)
 1154         indmirror = 1;
 1155     else if (elemscale.y < 0)
 1156         indmirror = 3;
 1157 
 1158     /* orientation */
 1159     indangle = fit->orientate / 90;
 1160     if (indangle % 2)
 1161     {
 1162         ss = elemsize.x;
 1163         elemsize.x = elemsize.y;
 1164         elemsize.y = ss;
 1165     }
 1166 
 1167     /* box for fitting */
 1168     fitbox.ll.x = 0;
 1169     fitbox.ll.y = 0;
 1170     fitbox.ur.x = boxwidth;
 1171     fitbox.ur.y = boxheight;
 1172 
 1173     /* relative position */
 1174     relpos.x = fit->position[0] / 100.0;
 1175     relpos.y = fit->position[1] / 100.0;
 1176 
 1177     /* calculate image box */
 1178     if (fit->fitmethod == pdc_tauto)
 1179         fit->fitmethod = pdc_meet;
 1180     pdc_place_element(fit->fitmethod, 1.0, &fitbox, &relpos,
 1181                       &elemsize, &relpos, &elembox, &fitscale);
 1182 
 1183     if (logg3)
 1184         pdc_logg(p->pdc,
 1185                  "\t\t\telement scaling: sx=%g, sy=%g  "
 1186                  "(relating to fitbox)\n",
 1187                  fitscale.x, fitscale.y);
 1188 
 1189     /* reference point */
 1190     x = fit->refpoint[0];
 1191     y = fit->refpoint[1];
 1192 
 1193 
 1194     /* adjust page size */
 1195     if (!xo->blind && xo->adjustpage && PDF_GET_STATE(p) == pdf_state_page)
 1196     {
 1197     pdc_scalar urx, ury, width, height, theight;
 1198 
 1199         urx = 2 * x + elembox.ur.x;
 1200         ury = 2 * y + elembox.ur.y;
 1201     pdc_transform_point(&p->curr_ppt->gstate[p->curr_ppt->sl].ctm,
 1202                 urx, ury, &width, &theight);
 1203     height = (p->ydirection > 0) ? theight
 1204             : pdf_get_pageheight(p) - p->ydirection * theight;
 1205 
 1206     if (height < p->ydirection * theight / 2.0)
 1207         pdc_error(p->pdc, PDF_E_IMAGE_NOADJUST, 0, 0, 0, 0);
 1208 
 1209         width = fabs(width);
 1210         height = fabs(height);
 1211 
 1212     if ((width < PDF_ACRO_MINPAGE || width > PDF_ACRO_MAXPAGE ||
 1213          height < PDF_ACRO_MINPAGE || height > PDF_ACRO_MAXPAGE))
 1214         pdc_warning(p->pdc, PDF_E_PAGE_SIZE_ACRO, 0, 0, 0, 0);
 1215 
 1216     pdf_set_pagebox(p, pdf_mediabox, 0, 0, width, height);
 1217         pdf_set_pagebox(p, pdf_artbox, 0, 0, 0, 0);
 1218         pdf_set_pagebox(p, pdf_bleedbox, 0, 0, 0, 0);
 1219         pdf_set_pagebox(p, pdf_cropbox, 0, 0, 0, 0);
 1220         pdf_set_pagebox(p, pdf_trimbox, 0, 0, 0, 0);
 1221     }
 1222 
 1223     /* reference point */
 1224     pdc_translation_matrix(x, y, &m);
 1225 
 1226     /* optional rotation */
 1227     if (fabs(fit->rotate) > PDC_FLOAT_PREC)
 1228     {
 1229         pdc_rotation_matrix(p->ydirection * fit->rotate, &mm);
 1230         pdc_multiply_matrix(&mm, &m);
 1231     }
 1232 
 1233     /* output after translation and rotation */
 1234     if (!xo->blind)
 1235     {
 1236         /* new CTM */
 1237         if (fit->showborder ||
 1238             fit->fitmethod == pdc_clip || fit->fitmethod == pdc_slice)
 1239         {
 1240             pdf_concat_raw(p, &m);
 1241             pdc_identity_matrix(&m);
 1242         }
 1243 
 1244         /* show border */
 1245         if (fit->showborder)
 1246         {
 1247             pdf__rect(p, 0, 0, boxwidth, boxheight);
 1248             pdf__stroke(p);
 1249         }
 1250 
 1251         /* clipping */
 1252         if (fit->fitmethod == pdc_clip || fit->fitmethod == pdc_slice)
 1253         {
 1254             if (boxwidth < PDC_FLOAT_PREC)
 1255                 boxwidth = PDF_ACRO_MAXPAGE;
 1256             if (boxheight < PDC_FLOAT_PREC)
 1257                 boxheight = PDF_ACRO_MAXPAGE;
 1258             pdf__rect(p, 0, 0, boxwidth, boxheight);
 1259             pdf__clip(p);
 1260 
 1261             ctm_clip = p->curr_ppt->gstate[p->curr_ppt->sl].ctm;
 1262             redbox.ll.x = 0;
 1263             redbox.ll.y = 0;
 1264             redbox.ur.x = boxwidth;
 1265             redbox.ur.y = p->ydirection * boxheight;
 1266         }
 1267     }
 1268 
 1269     /* translation of element box */
 1270     elembox.ll.y *= p->ydirection;
 1271     elembox.ur.y *= p->ydirection;
 1272     pdc_box2polyline(NULL, &elembox, polyline);
 1273     ip = indangle + indmirror;
 1274     if (ip >= 4) ip -= 4;
 1275     tx = polyline[ip].x;
 1276     ty = polyline[ip].y;
 1277     pdc_translation_matrix(tx, ty, &mm);
 1278     pdc_multiply_matrix(&mm, &m);
 1279     boxwidth = elembox.ur.x - elembox.ll.x;
 1280     boxheight = elembox.ur.y - elembox.ll.y;
 1281 
 1282     /* orientation of image */
 1283     if (fit->orientate != 0)
 1284     {
 1285         pdc_rotation_matrix(p->ydirection * fit->orientate, &mm);
 1286         pdc_multiply_matrix(&mm, &m);
 1287         if (indangle % 2)
 1288         {
 1289             ss = fitscale.x;
 1290             fitscale.x = fitscale.y;
 1291             fitscale.y = ss;
 1292 
 1293             ss = boxwidth;
 1294             boxwidth = p->ydirection * boxheight;
 1295             boxheight = p->ydirection * ss;
 1296         }
 1297     }
 1298 
 1299     /* mirroring of image */
 1300     mirror.x = elemscale.x * fitscale.x;
 1301     elemscale.x = fabs(mirror.x);
 1302     mirror.x /= elemscale.x;
 1303     if (image->strips == 1)
 1304         mirror.y = p->ydirection * elemscale.y * fitscale.y;
 1305     else
 1306         mirror.y = p->ydirection * rowsize * fitscale.y;
 1307     elemscale.y = fabs(mirror.y);
 1308     mirror.y /= elemscale.y;
 1309     pdc_scale_matrix(mirror.x, mirror.y, &mm);
 1310     pdc_multiply_matrix(&mm, &m);
 1311 
 1312     if (logg3)
 1313         pdc_logg(p->pdc,
 1314                  "\t\t\tcumulative mirroring: mx=%g, my=%g\n",
 1315                  mirror.x, mirror.y);
 1316 
 1317     /* matchbox or clip path */
 1318     if (!xo->blind && (fit->matchbox || kclip || kcliptiff))
 1319     {
 1320         pdf_concat_raw(p, &m);
 1321         pdc_identity_matrix(&m);
 1322 
 1323         if (fit->matchbox)
 1324         {
 1325             matchrect.llx = 0;
 1326             matchrect.lly = 0;
 1327             matchrect.urx = boxwidth;
 1328             matchrect.ury = p->ydirection * boxheight;
 1329 
 1330             if (fit->fitmethod == pdc_clip || fit->fitmethod == pdc_slice)
 1331             {
 1332                 pdc_rectangle cliprect;
 1333                 pdc_matrix ctm_inv;
 1334 
 1335                 pdc_invert_matrix(p->pdc, &ctm_inv,
 1336                               &p->curr_ppt->gstate[p->curr_ppt->sl].ctm);
 1337                 pdc_multiply_matrix(&ctm_clip, &ctm_inv);
 1338                 pdc_box2polyline(&ctm_inv, &redbox, polyline);
 1339                 pdc_polyline2rect(polyline, 4, &cliprect);
 1340 
 1341                 pdc_rect_intersect(&matchrect, &matchrect, &cliprect);
 1342             }
 1343 
 1344             pdf_set_mbox_rectangle(p, fit->matchbox, &matchrect, 0);
 1345             pdf_draw_mbox_rectangle(p, fit->matchbox, mbox_area | mbox_border);
 1346 
 1347             pdf_add_page_mbox(p, fit->matchbox);
 1348         }
 1349 
 1350         /* displacement of image because of clipping */
 1351         shift = clipbox.ll;
 1352         purescale.x *= fitscale.x;
 1353         purescale.y *= fitscale.y;
 1354         if (kclip)
 1355         {
 1356             shift.x *= -purescale.x;
 1357             shift.y *= -purescale.y;
 1358         }
 1359 
 1360         if (kclip)
 1361         {
 1362             /* user clipping path */
 1363             pdf__rect(p, 0, 0, boxwidth, boxheight);
 1364             pdf__clip(p);
 1365         }
 1366 
 1367         if (kclip)
 1368         {
 1369             pdc_translation_matrix(shift.x, shift.y, &mm);
 1370             pdc_multiply_matrix(&mm, &m);
 1371         }
 1372     }
 1373 
 1374     /* scaling of image */
 1375     pdc_scale_matrix(elemscale.x, elemscale.y, &mm);
 1376     pdc_multiply_matrix(&mm, &m);
 1377 
 1378     /* ctm */
 1379     if (xo->blind)
 1380     {
 1381         if (immatrix == NULL)
 1382             mm = p->curr_ppt->gstate[p->curr_ppt->sl].ctm;
 1383         else
 1384             mm = *immatrix;
 1385         pdc_multiply_matrix(&m, &mm);
 1386     }
 1387     else
 1388     {
 1389         pdf_concat_raw(p, &m);
 1390         mm = p->curr_ppt->gstate[p->curr_ppt->sl].ctm;
 1391     }
 1392 
 1393     pdc_logg_cond(p->pdc, 5, trc_image,
 1394                        "\t\t\tCTM components of image %s\"%s\":\n"
 1395                        "\t\t\ta = %f\n"
 1396                        "\t\t\tb = %f\n"
 1397                        "\t\t\tc = %f\n"
 1398                        "\t\t\td = %f\n"
 1399                        "\t\t\te = %f\n"
 1400                        "\t\t\tf = %f\n",
 1401                        image->imagemask ? "mask " : "",
 1402                        image->filename, mm.a, mm.b, mm.c, mm.d, mm.e, mm.f);
 1403 
 1404     if (!xo->blind)
 1405         pdf_cleanup_fit_options(p, fit);
 1406 
 1407     /* check image orientation */
 1408     if (immatrix != NULL)
 1409     {
 1410         *immatrix = mm;
 1411         return;
 1412     }
 1413     if (image->mask != pdc_undef)
 1414     {
 1415         sm = ctm_save;
 1416         xo_save.im = image->mask;
 1417         xo_save.blind = pdc_true;
 1418         pdf_fit_xobject_internal(p, &xo_save, &fit_save, &sm);
 1419 
 1420         if ((sm.a * mm.a < 0) || (sm.b * mm.b < 0) ||
 1421             (sm.c * mm.c < 0) || (sm.d * mm.d < 0))
 1422         {
 1423             pdc_error(p->pdc, PDF_E_IMAGE_NOMATCH,
 1424                       p->images[image->mask].filename, image->filename, 0, 0);
 1425         }
 1426     }
 1427 
 1428     if (!(xo->flags & is_image) && !xo->blind)
 1429     {
 1430         pdf_reset_gstate(p);
 1431         pdf_reset_tstate(p);
 1432     }
 1433 
 1434 
 1435     if (!xo->blind)
 1436     {
 1437         /* last strip first */
 1438         if (image->strips > 1 && lastratio != 1.0)
 1439         {
 1440             pdc_scale_matrix(1, lastratio, &m);
 1441             pdf_concat_raw(p, &m);
 1442         }
 1443 
 1444         /* put out image strips separately if available */
 1445         islast = image->strips - 1;
 1446         imageno = image->no + islast;
 1447         for (is = islast; is >= 0; is--)
 1448         {
 1449             pdc_printf(p->out, "/I%d Do\n", imageno);
 1450             p->xobjects[imageno].flags |= xobj_flag_write;
 1451             if (image->strips > 1 && is > 0)
 1452             {
 1453                 pdc_translation_matrix(0, 1, &m);
 1454                 if (is == islast && lastratio != 1.0)
 1455         {
 1456             pdc_scale_matrix(1, (1.0 / lastratio), &sm);
 1457                     pdc_multiply_matrix(&sm, &m);
 1458         }
 1459                 pdf_concat_raw(p, &m);
 1460                 imageno--;
 1461             }
 1462         }
 1463         if (image->mask != pdc_undef)
 1464         {
 1465             p->xobjects[p->images[image->mask].no].flags |= xobj_flag_write;
 1466 
 1467             if (p->images[image->mask].bpc > 1)
 1468                  pdf_set_autotgroup(p, pdc_true);
 1469         }
 1470     }
 1471 }
 1472 
 1473 
 1474 /* ---------------------------- info image --------------------------------- */
 1475 
 1476 void
 1477 pdf_get_image_size(PDF *p, int im, pdc_scalar *width, pdc_scalar *height)
 1478 {
 1479     pdf_image *image;
 1480 
 1481     pdf_check_handle(p, im, pdc_imagehandle);
 1482     image = &p->images[im];
 1483 
 1484     if (image->orientation < 5 || image->ignoreorient)
 1485     {
 1486         if (width)
 1487             *width = image->width;
 1488         if (height)
 1489             *height = fabs(image->height);
 1490     }
 1491     else
 1492     {
 1493         if (width)
 1494             *width = fabs(image->height);
 1495         if (height)
 1496             *height = image->width;
 1497     }
 1498 }
 1499 
 1500 void
 1501 pdf_get_image_resolution(PDF *p, int im, pdc_scalar *dpi_x, pdc_scalar *dpi_y)
 1502 {
 1503     pdf_image *image;
 1504 
 1505     pdf_check_handle(p, im, pdc_imagehandle);
 1506     image = &p->images[im];
 1507 
 1508     if (image->orientation < 5 || image->ignoreorient)
 1509     {
 1510         if (dpi_x)
 1511             *dpi_x = image->dpi_x;
 1512         if (dpi_y)
 1513             *dpi_y = image->dpi_y;
 1514     }
 1515     else
 1516     {
 1517         if (dpi_x)
 1518             *dpi_x = image->dpi_y;
 1519         if (dpi_y)
 1520             *dpi_y = image->dpi_x;
 1521     }
 1522 }
 1523 
 1524 int
 1525 pdf_get_image_colorspace(PDF *p, int im)
 1526 {
 1527     pdf_image *image;
 1528 
 1529     pdf_check_handle(p, im, pdc_imagehandle);
 1530     image = &p->images[im];
 1531 
 1532     if (image->colorspace != pdc_undef)
 1533         return  (int) p->colorspaces[image->colorspace].type;
 1534 
 1535     return (int) NoColor;
 1536 }
 1537 
 1538 
 1539 const char *
 1540 pdf_get_image_filename(PDF *p, pdf_image *image)
 1541 {
 1542     return pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, image->filename);
 1543 }
 1544 
 1545 
 1546 /* ---------------------------- load image --------------------------------- */
 1547 
 1548 static const pdc_keyconn pdf_extension_names[] =
 1549 {
 1550     {".bmp",   pdf_img_bmp},
 1551     {".ccitt", pdf_img_ccitt},
 1552     {".g3",    pdf_img_ccitt},
 1553     {".g4",    pdf_img_ccitt},
 1554     {".fax",   pdf_img_ccitt},
 1555     {".gif",   pdf_img_gif},
 1556     {".jpg",   pdf_img_jpeg},
 1557     {".jpeg",  pdf_img_jpeg},
 1558     {".jpx",   pdf_img_jpeg2000},
 1559     {".jp2",   pdf_img_jpeg2000},
 1560     {".jpf",   pdf_img_jpeg2000},
 1561     {".jpm",   pdf_img_jpeg2000},
 1562     {".j2k",   pdf_img_jpeg2000},
 1563     {".png",   pdf_img_png},
 1564     {".raw",   pdf_img_raw},
 1565     {".tif",   pdf_img_tiff},
 1566     {".tiff",  pdf_img_tiff},
 1567     {NULL, 0}
 1568 };
 1569 
 1570 /* allowed values for options 'bpc' */
 1571 static const pdc_keyconn pdf_bpcvalues[] =
 1572 {
 1573     {"1", 1}, {"2", 2}, {"4", 4}, {"8", 8}, {"16", 16}, {NULL, 0}
 1574 };
 1575 
 1576 /* allowed values for options 'components' */
 1577 static const pdc_keyconn pdf_compvalues[] =
 1578 {
 1579     {"1", 1}, {"3", 3}, {"4", 4}, {NULL, 0}
 1580 };
 1581 
 1582 #define PDF_OPIOPT_FLAG PDC_OPT_UNSUPP
 1583 #define PDF_ICCOPT_FLAG PDC_OPT_UNSUPP
 1584 #define PDF_CLIPPATH_FLAG PDC_OPT_UNSUPP
 1585 
 1586 #define PDF_METADATA_FLAG  PDC_OPT_UNSUPP
 1587 
 1588 #define PDF_LAYER_FLAG PDC_OPT_UNSUPP
 1589 
 1590 /* definitions of open image options */
 1591 static const pdc_defopt pdf_open_image_options[] =
 1592 {
 1593     {"hypertextencoding", pdc_stringlist,  PDC_OPT_NONE, 1, 1,
 1594       0.0, PDF_MAX_NAMESTRING, NULL},
 1595 
 1596     {"bitreverse", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 1597 
 1598     {"bpc", pdc_integerlist, PDC_OPT_INTLIST, 1, 1, 1.0, 16.0, pdf_bpcvalues},
 1599 
 1600     {"components", pdc_integerlist, PDC_OPT_INTLIST, 1, 1, 1.0, 4.0,
 1601       pdf_compvalues},
 1602 
 1603     {"height", pdc_integerlist, 0, 1, 1, 1.0, PDC_INT_MAX,  NULL},
 1604 
 1605     {"width", pdc_integerlist, 0, 1, 1, 1.0, PDC_INT_MAX, NULL},
 1606 
 1607     {"honoriccprofile", pdc_booleanlist, PDF_ICCOPT_FLAG, 1, 1, 0.0, 0.0, NULL},
 1608 
 1609     /* ordering of the next three options is significant */
 1610 
 1611     {"iccprofile", pdc_iccprofilehandle, PDF_ICCOPT_FLAG, 1, 1, 1.0, 0.0, NULL},
 1612 
 1613     {"colorize", pdc_colorhandle, PDC_OPT_IGNOREIF1, 1, 1, 0.0, 0.0, NULL},
 1614 
 1615     {"mask", pdc_booleanlist, PDC_OPT_IGNOREIF2, 1, 1, 0.0, 0.0, NULL},
 1616 
 1617     {"honorclippingpath", pdc_booleanlist, PDF_CLIPPATH_FLAG, 1, 1,
 1618      0.0, 0.0, NULL},
 1619 
 1620     {"clippingpathname", pdc_stringlist, PDF_CLIPPATH_FLAG, 1, 1,
 1621       1.0, 255.0, NULL},
 1622 
 1623     {"ignoremask", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 1624 
 1625     {"ignoreorientation", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 1626 
 1627     /* deprecated */
 1628     {"imagewarning", pdc_booleanlist, PDC_OPT_PDFLIB_7, 1, 1, 0.0, 0.0, NULL},
 1629 
 1630     {"inline", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 1631 
 1632     {"interpolate", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 1633 
 1634     {"invert", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 1635 
 1636     {"jpegoptimize", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 1637 
 1638     {"passthrough", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 1639 
 1640     {"K", pdc_integerlist, 0, 1, 1, -1.0, 1.0, NULL},
 1641 
 1642     {"masked", pdc_imagehandle, 0, 1, 1, 0.0, 0.0, NULL},
 1643 
 1644     {"page", pdc_integerlist, 0, 1, 1, 1.0, PDC_INT_MAX, NULL},
 1645 
 1646     {"renderingintent", pdc_keywordlist, 0, 1, 1, 0.0, 0.0,
 1647       pdf_renderingintent_pdfkeylist},
 1648 
 1649     {"reftype", pdc_keywordlist, 0, 1, 1, 0.0, 0.0, pdf_reftype_keys},
 1650 
 1651     {"template", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 1652 
 1653     {"iconname", pdc_stringlist, 0, 1, 1,
 1654       1.0, PDF_MAX_NAMESTRING, NULL},
 1655 
 1656     {"OPI-1.3", pdc_stringlist, PDF_OPIOPT_FLAG, 1, 1,
 1657       0.0, PDC_INT_MAX, NULL},
 1658 
 1659     {"OPI-2.0", pdc_stringlist, PDF_OPIOPT_FLAG | PDC_OPT_IGNOREIF1, 1, 1,
 1660       0.0, PDC_INT_MAX, NULL},
 1661 
 1662     {"metadata", pdc_stringlist, PDF_METADATA_FLAG, 1, 1,
 1663       0.0, PDC_INT_MAX, NULL},
 1664 
 1665     {"layer", pdc_layerhandle, PDF_LAYER_FLAG, 1, 1,
 1666       0.0, 0.0, NULL},
 1667 
 1668     PDF_ERRORPOLICY_OPTION
 1669 
 1670     PDC_OPT_TERMINATE
 1671 };
 1672 
 1673 int
 1674 pdf__load_image(
 1675     PDF *p,
 1676     const char *type,
 1677     const char *filename,
 1678     const char *optlist)
 1679 {
 1680     const char *keyword = NULL, *stemp1 = NULL, *stemp2 = NULL, *stemp3 = NULL;
 1681     char qualname[32], uptype[16], testfilename[PDC_FILENAMELEN + 1];
 1682     pdc_clientdata data;
 1683     pdc_resopt *resopts;
 1684     pdc_encoding htenc;
 1685     int htcp;
 1686     pdf_image_type imgtype;
 1687     pdc_file *fp = NULL;
 1688     int colorize = pdc_undef;
 1689     pdf_image *image;
 1690     pdc_bool indjpeg = pdc_false;
 1691     pdc_bool templ = pdc_false;
 1692     pdc_bool verbose = p->debug[(int) 'i'];
 1693     int legal_states = 0;
 1694     int i, k, inum, imageslot, retval = -1, errcode = 0;
 1695 
 1696     if (type == NULL || *type == '\0')
 1697         pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "type", 0, 0, 0);
 1698 
 1699     /* parsing image type */
 1700     k = pdc_get_keycode_ci(type, pdf_image_keylist);
 1701     if (k == PDC_KEY_NOTFOUND)
 1702         pdc_error(p->pdc, PDC_E_ILLARG_STRING, "type", type, 0, 0);
 1703     imgtype = (pdf_image_type) k;
 1704     type = pdc_get_keyword(imgtype, pdf_image_keylist);
 1705 
 1706     /* parsing option list */
 1707     pdf_set_clientdata(p, &data);
 1708     resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_open_image_options,
 1709                                    &data, pdc_true);
 1710 
 1711     keyword = "imagewarning";
 1712     pdc_get_optvalues(keyword, resopts, &verbose, NULL);
 1713     verbose = pdf_get_errorpolicy(p, resopts, verbose);
 1714 
 1715     /* filename must be already converted to UTF-8 */
 1716     pdc_logg_cond(p->pdc, 1, trc_image, "\tImage file: \"%s\"\n", filename);
 1717 
 1718     /* search for image file */
 1719     fp = pdc_fsearch_fopen(p->pdc, filename, NULL, "image ", PDC_FILE_BINARY);
 1720 
 1721     /* automatic check */
 1722     if (imgtype == pdf_img_auto)
 1723     {
 1724         pdf_tiff_info tiff_info;
 1725 
 1726         /* search for files with other extensions */
 1727         if (fp == NULL)
 1728         {
 1729             pdc_logg_cond(p->pdc, 1, trc_image,
 1730                 "\tImage file not found; searching for files "
 1731                 "with alternative extensions\n");
 1732 
 1733             for (i = 0; i < 2; i++)
 1734             {
 1735                 for (k = 0; k < 100; k++)
 1736                 {
 1737                     const char *extension = pdf_extension_names[k].word;
 1738                     if (extension)
 1739                     {
 1740                         strcpy(testfilename, filename);
 1741                         strcpy(uptype, extension);
 1742                         if (i)
 1743                             pdc_strtoupper(uptype);
 1744                         strcat(testfilename, uptype);
 1745 
 1746                         fp = pdc_fsearch_fopen(p->pdc, testfilename, NULL,
 1747                                                "image ", PDC_FILE_BINARY);
 1748                         if (fp != NULL)
 1749                             break;
 1750                     }
 1751                     else
 1752                     {
 1753                         break;
 1754                     }
 1755                 }
 1756                 if (fp != NULL)
 1757                     break;
 1758             }
 1759 
 1760             if (fp != NULL)
 1761             {
 1762                 filename = (const char *) testfilename;
 1763                 pdc_logg_cond(p->pdc, 1, trc_image,
 1764                                   "\tImage file \"%s\" found\n", filename);
 1765             }
 1766             else
 1767             {
 1768                 fp = pdc_fsearch_fopen(p->pdc, filename, NULL, "image ",
 1769                                        PDC_FILE_BINARY);
 1770             }
 1771         }
 1772 
 1773         /* automatic type check */
 1774         if (fp != NULL)
 1775         {
 1776             if (pdf_is_BMP_file(p, fp))
 1777                 imgtype = pdf_img_bmp;
 1778             else if (pdf_is_GIF_file(p, fp))
 1779                 imgtype = pdf_img_gif;
 1780             else if (pdf_is_PNG_file(p, fp))
 1781                 imgtype = pdf_img_png;
 1782             else if (pdf_is_TIFF_file(p, fp, &tiff_info, pdc_true))
 1783                 imgtype = pdf_img_tiff;
 1784             else if (pdf_is_JPEG_file(p, fp))
 1785                 imgtype = pdf_img_jpeg;
 1786             else if (pdf_is_JPX_file(p, fp))
 1787                 imgtype = pdf_img_jpeg2000;
 1788             else
 1789             {
 1790                 pdc_fclose(fp);
 1791 
 1792                 pdc_set_errmsg(p->pdc, PDF_E_IMAGE_UNKNOWN, filename, 0, 0, 0);
 1793 
 1794                 if (verbose)
 1795                     PDC_RETHROW(p->pdc);
 1796 
 1797                 return -1;
 1798             }
 1799             type = pdc_get_keyword(imgtype, pdf_image_keylist);
 1800         }
 1801     }
 1802 
 1803     if (fp == NULL)
 1804     {
 1805         if (verbose)
 1806             PDC_RETHROW(p->pdc);
 1807 
 1808         return -1;
 1809     }
 1810     pdc_fclose(fp);
 1811 
 1812     strcpy(uptype, type);
 1813     pdc_strtoupper(uptype);
 1814     pdc_logg_cond(p->pdc, 1, trc_image,
 1815         "\tImage type \"%s\" detected\n", uptype);
 1816 
 1817     if (imgtype == pdf_img_jpeg2000)
 1818     {
 1819         pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_JPEG2000, 0, 0, 0, 0);
 1820 
 1821         if (verbose)
 1822             PDC_RETHROW(p->pdc);
 1823 
 1824         return -1;
 1825     }
 1826 
 1827     /* find free slot */
 1828     for (imageslot = 0; imageslot < p->images_capacity; imageslot++)
 1829         if (!p->images[imageslot].in_use)
 1830             break;
 1831 
 1832     if (imageslot == p->images_capacity)
 1833         pdf_grow_images(p);
 1834     image = &p->images[imageslot];
 1835 
 1836     /* copy filename */
 1837     image->filename = pdc_strdup(p->pdc, filename);
 1838 
 1839     /* inherit global flags */
 1840     image->verbose = verbose;
 1841     image->ri = p->rendintent;
 1842 
 1843     /* parsing optlist */
 1844     if (optlist && strlen(optlist))
 1845     {
 1846         keyword = "reftype";
 1847         if (pdc_get_optvalues(keyword, resopts, &inum, NULL))
 1848         {
 1849             image->reference = (pdf_ref_type) inum;
 1850             if (image->reference != pdf_ref_direct &&
 1851                 imgtype != pdf_img_ccitt &&
 1852                 imgtype != pdf_img_jpeg &&
 1853                 imgtype != pdf_img_raw)
 1854             {
 1855                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNSUPP, keyword, uptype,
 1856                             0, 0);
 1857                 image->reference = pdf_ref_direct;
 1858             }
 1859         }
 1860         indjpeg = (imgtype == pdf_img_jpeg &&
 1861                    image->reference != pdf_ref_direct) ? pdc_true : pdc_false;
 1862 
 1863         keyword = "bpc";
 1864         if (pdc_get_optvalues(keyword, resopts, &image->bpc, NULL))
 1865         {
 1866             if (imgtype != pdf_img_raw && !indjpeg)
 1867                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 1868                             0, 0);
 1869             if (image->bpc == 16)
 1870             {
 1871                 if (p->compatibility < PDC_1_5)
 1872                 {
 1873                     errcode = PDC_E_OPT_VERSION;
 1874                     stemp1 = "bpc=16";
 1875                     stemp2 = pdc_get_pdfversion(p->pdc, p->compatibility);
 1876                     goto PDF_IMAGE_ERROR;
 1877                 }
 1878             }
 1879         }
 1880 
 1881         keyword = "components";
 1882         if (pdc_get_optvalues(keyword, resopts, &image->components, NULL))
 1883         {
 1884             if (imgtype != pdf_img_raw && !indjpeg)
 1885                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 1886                             0, 0);
 1887         }
 1888 
 1889         keyword = "height";
 1890         if (pdc_get_optvalues(keyword, resopts, &image->height_pixel, NULL))
 1891         {
 1892             if (imgtype != pdf_img_ccitt &&
 1893                 imgtype != pdf_img_raw && !indjpeg)
 1894                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 1895                             0, 0);
 1896         }
 1897 
 1898         keyword = "width";
 1899         if (pdc_get_optvalues(keyword, resopts, &image->width_pixel, NULL))
 1900         {
 1901             if (imgtype != pdf_img_raw &&
 1902                 imgtype != pdf_img_ccitt && !indjpeg)
 1903                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 1904                             0, 0);
 1905         }
 1906 
 1907         keyword = "bitreverse";
 1908         if (pdc_get_optvalues(keyword, resopts, &image->bitreverse, NULL))
 1909         {
 1910             if (image->bitreverse &&
 1911                (imgtype != pdf_img_ccitt || image->reference != pdf_ref_direct))
 1912                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 1913                             0, 0);
 1914         }
 1915 
 1916         keyword = "colorize";
 1917         if (pdc_get_optvalues(keyword, resopts, &colorize, NULL))
 1918         {
 1919             if (imgtype == pdf_img_jpeg2000)
 1920                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 1921                             0, 0);
 1922         }
 1923 
 1924 
 1925         keyword = "ignoremask";
 1926         if (pdc_get_optvalues(keyword, resopts, &image->ignoremask, NULL))
 1927         {
 1928             if (imgtype == pdf_img_bmp ||
 1929                 imgtype == pdf_img_ccitt ||
 1930                 imgtype == pdf_img_raw)
 1931                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNSUPP, keyword, uptype,
 1932                             0, 0);
 1933         }
 1934 
 1935         keyword = "ignoreorientation";
 1936         if (pdc_get_optvalues(keyword, resopts, &image->ignoreorient, NULL))
 1937         {
 1938             if (imgtype == pdf_img_tiff)
 1939                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNSUPP, keyword, uptype,
 1940                             0, 0);
 1941         }
 1942 
 1943         keyword = "inline";
 1944         if (pdc_get_optvalues(keyword, resopts,
 1945                               &image->doinline, NULL) && image->doinline)
 1946         {
 1947             if (imgtype != pdf_img_ccitt &&
 1948                 imgtype != pdf_img_jpeg &&
 1949                 imgtype != pdf_img_raw)
 1950             {
 1951                 pdc_warning(p->pdc,
 1952                     PDF_E_IMAGE_OPTUNSUPP, keyword, uptype, 0, 0);
 1953                 image->doinline = pdc_false;
 1954             }
 1955             else if (image->reference != pdf_ref_direct)
 1956             {
 1957                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 1958                             0, 0);
 1959                 image->doinline = pdc_false;
 1960             }
 1961         }
 1962 
 1963         keyword = "interpolate";
 1964         pdc_get_optvalues(keyword, resopts, &image->interpolate, NULL);
 1965 
 1966 
 1967         keyword = "invert";
 1968         if (pdc_get_optvalues(keyword, resopts, &image->invert, NULL))
 1969         {
 1970             if (imgtype == pdf_img_jpeg2000)
 1971                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 1972                             0, 0);
 1973         }
 1974 
 1975         keyword = "jpegoptimize";
 1976         pdc_get_optvalues(keyword, resopts, &image->jpegoptimize, NULL);
 1977 
 1978         keyword = "passthrough";
 1979         pdc_get_optvalues(keyword, resopts, &image->passthrough, NULL);
 1980 
 1981         keyword = "K";
 1982         if (pdc_get_optvalues(keyword, resopts, &image->K, NULL))
 1983         {
 1984             if (imgtype != pdf_img_ccitt)
 1985                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 1986                             0, 0);
 1987         }
 1988 
 1989         keyword = "mask";
 1990         pdc_get_optvalues(keyword, resopts, &image->imagemask, NULL);
 1991 
 1992 
 1993         keyword = "masked";
 1994         if (pdc_get_optvalues(keyword, resopts, &image->mask, NULL))
 1995         {
 1996 
 1997 
 1998             if (!p->images[image->mask].in_use ||
 1999                  p->images[image->mask].strips != 1 ||
 2000                 (p->compatibility <= PDC_1_3 &&
 2001                 (p->images[image->mask].imagemask != pdc_true ||
 2002                  p->images[image->mask].bpc != 1)))
 2003             {
 2004                 errcode = PDF_E_IMAGE_OPTBADMASK;
 2005                 stemp1 = keyword;
 2006                 stemp2 = pdc_errprintf(p->pdc, "%d", image->mask);
 2007                 goto PDF_IMAGE_ERROR;
 2008             }
 2009 
 2010         if (p->colorspaces[p->images[image->mask].colorspace].type !=
 2011         DeviceGray)
 2012             {
 2013                 errcode = PDF_E_IMAGE_BADMASK;
 2014                 stemp1 = pdc_errprintf(p->pdc, "%s",
 2015             p->images[image->mask].filename);
 2016                 goto PDF_IMAGE_ERROR;
 2017             }
 2018         }
 2019 
 2020         keyword = "renderingintent";
 2021         if (pdc_get_optvalues(keyword, resopts, &inum, NULL))
 2022             image->ri = (pdf_renderingintent) inum;
 2023 
 2024         keyword = "page";
 2025         if (pdc_get_optvalues(keyword, resopts, &image->page, NULL))
 2026         {
 2027             if (imgtype != pdf_img_tiff)
 2028             {
 2029                 if (image->page == 1)
 2030                 {
 2031                     pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNSUPP, keyword,
 2032                                 uptype, 0, 0);
 2033                 }
 2034                 else
 2035                 {
 2036                     errcode = PDF_E_IMAGE_NOPAGE;
 2037                     stemp1 = pdc_errprintf(p->pdc, "%d", image->page);
 2038                     stemp2 = uptype;
 2039                     stemp3 = pdc_errprintf(p->pdc, "%s", image->filename);
 2040                     goto PDF_IMAGE_ERROR;
 2041                 }
 2042             }
 2043         }
 2044 
 2045         keyword = "template";
 2046         if (pdc_get_optvalues(keyword, resopts, &templ, NULL))
 2047         {
 2048             if (templ && image->doinline)
 2049             {
 2050                 pdc_warning(p->pdc, PDC_E_OPT_IGNORE, keyword, "inline",
 2051                             0, 0);
 2052                 templ = pdc_false;
 2053             }
 2054         }
 2055 
 2056         htenc =
 2057             pdf_get_hypertextencoding_opt(p, resopts, &htcp, pdc_true);
 2058         keyword = "iconname";
 2059         if (pdf_get_opt_textlist(p, keyword, resopts, htenc, htcp, pdc_true,
 2060                                  NULL, &image->iconname, NULL))
 2061         {
 2062             if (image->doinline)
 2063             {
 2064                 image->iconname = NULL;
 2065                 pdc_warning(p->pdc, PDC_E_OPT_IGNORE, keyword, "inline",
 2066                             0, 0);
 2067             }
 2068             else
 2069             {
 2070                 pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM);
 2071                 templ = pdc_true;
 2072             }
 2073         }
 2074 
 2075 
 2076 
 2077     }
 2078 
 2079     /* precise scope diagnosis */
 2080     if (image->doinline)
 2081         legal_states = pdf_state_content;
 2082     else if (templ)
 2083         legal_states = pdf_state_document;
 2084     else
 2085         legal_states = pdf_state_document | pdf_state_page | pdf_state_font;
 2086     PDF_CHECK_STATE(p, legal_states);
 2087 
 2088     /* required options */
 2089     if (imgtype == pdf_img_raw || imgtype == pdf_img_ccitt || indjpeg)
 2090     {
 2091         keyword = "";
 2092         if (image->height_pixel == pdc_undef)
 2093             keyword = "height";
 2094         else if (image->width_pixel == pdc_undef)
 2095             keyword = "width";
 2096         else
 2097         {
 2098             image->width = image->width_pixel;
 2099             image->height = image->height_pixel;
 2100         }
 2101 
 2102         if (imgtype == pdf_img_ccitt)
 2103         {
 2104             image->components = 1;
 2105             image->bpc = 1;
 2106         }
 2107         if (image->bpc == pdc_undef)
 2108             keyword = "bpc";
 2109         else if (image->components == pdc_undef)
 2110             keyword = "components";
 2111 
 2112         if (*keyword)
 2113         {
 2114             errcode = PDC_E_OPT_NOTFOUND;
 2115             stemp1 = keyword;
 2116             goto PDF_IMAGE_ERROR;
 2117         }
 2118     }
 2119 
 2120 
 2121 
 2122     /* set colorspace */
 2123     if (colorize != pdc_undef)
 2124     {
 2125         image->colorspace = colorize;
 2126     }
 2127     else if (image->imagemask == pdc_true)
 2128     {
 2129         image->colorspace = (int) DeviceGray;
 2130     }
 2131     else
 2132     {
 2133         switch(image->components)
 2134         {
 2135             case 1:
 2136             image->colorspace = DeviceGray;
 2137             break;
 2138 
 2139             case 3:
 2140             image->colorspace = DeviceRGB;
 2141             break;
 2142 
 2143             case 4:
 2144             image->colorspace = DeviceCMYK;
 2145             break;
 2146 
 2147             default:
 2148             break;
 2149         }
 2150     }
 2151 
 2152     /* try to open image file */
 2153     if (image->reference == pdf_ref_direct)
 2154     {
 2155     strcpy(qualname, uptype);
 2156     strcat(qualname, " ");
 2157         image->fp = pdc_fsearch_fopen(p->pdc, image->filename, NULL, qualname,
 2158                                       PDC_FILE_BINARY);
 2159         if (image->fp == NULL)
 2160             goto PDF_IMAGE_ERROR;
 2161     }
 2162 
 2163 
 2164     /* set image type */
 2165     image->type = imgtype;
 2166 
 2167     /* call working function */
 2168     switch (imgtype)
 2169     {
 2170         case pdf_img_bmp:
 2171         retval = pdf_process_BMP_data(p, imageslot);
 2172         break;
 2173 
 2174         case pdf_img_ccitt:
 2175         retval = pdf_process_CCITT_data(p, imageslot);
 2176         break;
 2177 
 2178         case pdf_img_gif:
 2179         retval = pdf_process_GIF_data(p, imageslot);
 2180         break;
 2181 
 2182         case pdf_img_jpeg:
 2183         if (image->passthrough == pdc_undef)
 2184             image->passthrough = pdc_false;
 2185         retval = pdf_process_JPEG_data(p, imageslot);
 2186         break;
 2187 
 2188         case pdf_img_jpeg2000:
 2189         retval = pdf_process_JPX_data(p, imageslot);
 2190         break;
 2191 
 2192         case pdf_img_png:
 2193         retval = pdf_process_PNG_data(p, imageslot);
 2194         break;
 2195 
 2196         default:
 2197         case pdf_img_raw:
 2198         retval = pdf_process_RAW_data(p, imageslot);
 2199         break;
 2200 
 2201         case pdf_img_tiff:
 2202         if (image->passthrough == pdc_undef)
 2203             image->passthrough = pdc_true;
 2204         retval = pdf_process_TIFF_data(p, imageslot);
 2205         break;
 2206     }
 2207 
 2208     /* cleanup */
 2209     if (retval == -1)
 2210     {
 2211         pdf_cleanup_image(p, imageslot);
 2212 
 2213         if (verbose)
 2214             PDC_RETHROW(p->pdc);
 2215     }
 2216     else
 2217     {
 2218         if (image->fp)
 2219             pdc_fclose(image->fp);
 2220         image->fp = NULL;
 2221 
 2222         /* logging protocol */
 2223         if (image->in_use && pdc_logg_is_enabled(p->pdc, 1, trc_image))
 2224         {
 2225             pdc_scalar width, height, dpi_x, dpi_y;
 2226 
 2227             pdf_get_image_size(p, imageslot, &width, &height);
 2228             pdf_get_image_resolution(p, imageslot, &dpi_x, &dpi_y);
 2229 
 2230             pdc_logg(p->pdc, "\tImage width: %g pixel\n"
 2231                               "\tImage height: %g pixel\n"
 2232                               "\tImage x resolution: %g dpi\n"
 2233                               "\tImage y resolution: %g dpi\n",
 2234                               width, height, dpi_x, dpi_y);
 2235 
 2236             if (imgtype == pdf_img_tiff)
 2237                 pdc_logg(p->pdc, "\tOrientation tag: %d\n",
 2238                                   image->orientation);
 2239 
 2240         }
 2241 
 2242         if (templ)
 2243         {
 2244             retval = pdf_embed_image(p, imageslot);
 2245             pdf_cleanup_image(p, imageslot);
 2246         }
 2247     }
 2248 
 2249     return retval;
 2250 
 2251     PDF_IMAGE_ERROR:
 2252 
 2253     pdf_cleanup_image(p, imageslot);
 2254 
 2255     if (errcode)
 2256         pdc_set_errmsg(p->pdc, errcode, stemp1, stemp2, stemp3, 0);
 2257     if (verbose)
 2258         PDC_RETHROW(p->pdc);
 2259 
 2260     return retval;
 2261 }
 2262 
 2263 void
 2264 pdf__close_image(PDF *p, int image)
 2265 {
 2266     pdf_check_handle(p, image, pdc_imagehandle);
 2267     pdf_cleanup_image(p, image);
 2268 }
 2269 
 2270 
 2271 #define MAX_THUMBNAIL_SIZE      106
 2272 
 2273 void
 2274 pdf__add_thumbnail(PDF *p, int im)
 2275 {
 2276     pdf_image *image;
 2277 
 2278     pdf_check_handle(p, im, pdc_imagehandle);
 2279 
 2280     if (pdf_get_thumb_id(p) != PDC_BAD_ID)
 2281         pdc_error(p->pdc, PDF_E_IMAGE_THUMB, 0, 0, 0, 0);
 2282 
 2283     image = &p->images[im];
 2284 
 2285     if (image->strips > 1)
 2286         pdc_error(p->pdc, PDF_E_IMAGE_THUMB_MULTISTRIP,
 2287             pdc_errprintf(p->pdc, "%d", im), 0, 0, 0);
 2288 
 2289     if (image->width > MAX_THUMBNAIL_SIZE || image->height > MAX_THUMBNAIL_SIZE)
 2290         pdc_error(p->pdc, PDF_E_IMAGE_THUMB_SIZE,
 2291             pdc_errprintf(p->pdc, "%d", im),
 2292             pdc_errprintf(p->pdc, "%d", MAX_THUMBNAIL_SIZE), 0, 0);
 2293 
 2294     if (image->colorspace != (int) DeviceGray &&
 2295         image->colorspace != (int) DeviceRGB &&
 2296         image->colorspace != (int) Indexed)
 2297         pdc_error(p->pdc, PDF_E_IMAGE_THUMB_CS,
 2298             pdc_errprintf(p->pdc, "%d", im), 0, 0, 0);
 2299 
 2300     /* Add the image to the thumbnail key of the current page.  */
 2301     pdf_set_thumb_id(p, p->xobjects[image->no].obj_id);
 2302 }