%% options copyright owner = Dirk Krause copyright year = 2017-xxxx SPDX-License-Identifier: BSD-3-Clause %% module #include "dk4conf.h" #if DK4_HAVE_MATH_H #ifndef MATH_H_INCLUDED #if DK4_ON_WINDOWS #ifndef _USE_MATH_DEFINES #define _USE_MATH_DEFINES 1 #endif #endif #include #define MATH_H_INCLUDED 1 #endif #endif #ifndef DK4MEM_H_INCLUDED #include "dk4mem.h" #endif #ifndef DK4GRA_H_INCLUDED #include "dk4gra.h" #endif #ifndef GRA_H_INCLUDED #include "gra.h" #endif #ifndef DK4BIF_H_INCLUDED #include "dk4bif.h" #endif #ifndef BIF_H_INCLUDED #include "bif.h" #endif #ifndef DK4BIFA_H_INCLUDED #include "dk4bifa.h" #endif #ifndef DK4UFI_H_INCLUDED #include "dk4ufi.h" #endif #ifndef DK4MAO8D_H_INCLUDED #include "dk4mao8d.h" #endif #ifndef DK4STRD_H_INCLUDED #include "dk4strd.h" #endif #ifndef DK4FOPD_H_INCLUDED #include "dk4fopd.h" #endif #ifndef DK4STRM_H_INCLUDED #include "dk4strm.h" #endif #ifndef DK4STRMCO_H_INCLUDED #include "dk4strmco.h" #endif #ifndef DK4BITSH_H_INCLUDED #include "dk4bitsh.h" #endif #ifndef DK4EDSTM_H_INCLUDED #include "dk4edstm.h" #endif #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif $!trace-include /** Text fragments to write background color. */ static const char * const dk4gra_pdfi_kw[] = { $!string-table # # 0 Space # # # 1-3 gray, rgb, cmyk # g rg k # # 4 Code for filled rectangle (0,0)--(0,1)--(1,1)--(1,0)--closepath # 0 0 m 0 1 l 1 1 l 1 0 l h f\n $!end }; /** Write instruction to fill rectangle (0,0)--(0,1)--(1,1)--(1,0)--closepath. @param os Output stream (memory buffer stream). @param colval Color components array. @param ncolval Number of color components. @param fii Fill color instruction index. @param backptr Address of success variable to reset on error. @param erp Error report, may be NULL. */ static void dk4gra_pdf_fill_rectangle( dk4_stream_t *os, double *colval, size_t ncolval, size_t fii, int *backptr, dk4_er_t *erp ) { size_t i; for (i = 0; i < ncolval; i++) { dk4gratool_stream_double(os, colval[i], backptr, erp); dk4gratool_stream_string(os, dk4gra_pdfi_kw[0], backptr, erp); } dk4gratool_stream_string(os, dk4gra_pdfi_kw[fii], backptr, erp); dk4gratool_stream_string(os, dk4gra_pdfi_kw[4], backptr, erp); } /** Setup text XObject for a given image. Note: No dynamic memory is used here, a pointer to the original fn is stored in the XObject. @param xo XObject to fill with data. @param gra Graphics output structure. @param bif Bitmap image file. @param fn Bitmap image file name. @param fno Frame number in bitmap image file. @param ipol Flag: Allow interpolation. @param ajpg Flag: Allow direct re-use of DCT encoded data from JPEG. @param ijpg Flag: Allow interpolation for DCT encoded data. @param anb Flag: Analyze bit depth. @param anc Flag: Analyze colors. @param ana Flag: Analyze alpha channel use. @param erp Error report, may be NULL. */ static void dk4gra_pdf_xo_setup( dk4_gra_pdf_img_xo_t *xo, dk4_gra_t *gra, dk4_bif_t *bif, const dkChar *fn, size_t fno, int ipol, int ajpg, int ijpg, int acol, int anb, int anc, int ana, dk4_er_t *erp ) { dk4_bif_jpeg_per_frame_t *pjpgf; $? "+ dk4gra_pdf_xo_setup" dk4mem_reset(xo, sizeof(dk4_gra_pdf_img_xo_t), NULL); xo->fn = NULL; xo->i_mb = NULL; xo->m_mb = NULL; xo->fno = 0; xo->objno = 0; xo->mobjno = 0; xo->unxon = 0; xo->width = 0; xo->height = 0; xo->dct = 0; xo->ipol = 0; xo->cs = 0; $? ". xo cs = 0" xo->hufi = 0; xo->deci = 0; xo->bpc = 0; xo->fn = fn; if (NULL == fn) { xo->unxon = gra->out.pdf.unxo; gra->out.pdf.unxo = gra->out.pdf.unxo + 1; } xo->fno = fno; xo->objno = gra->out.pdf.nextobj; xo->width = dk4bif_get_width(bif); xo->height = dk4bif_get_height(bif); if ((DK4_BIF_TYPE_JPEG == bif->imgtype) && (0 != ajpg)) { $? ". can use JPEG directly" xo->dct = 1; xo->ipol = (((0 != ipol) && (0 != ijpg)) ? (1) : (0)); xo->cs = dk4bif_get_color_space(bif); xo->bpc = dk4bif_get_original_bit_depth(bif); pjpgf = (dk4_bif_jpeg_per_frame_t *)(bif->cf->tsdata); if (NULL != pjpgf) { if ((DK4_CS_CMYK == xo->cs) && (0 != pjpgf->is_adobe)) { xo->deci = 1; } } $? ". xo cs = %d", xo->cs $? ". xo bpc = %u", (unsigned)(xo->bpc) } else { $? ". must decode JPEG" xo->ipol = ipol; if (0 == dk4bif_analyze( &(xo->cs), &(xo->bpc), bif, anb, anc, ana, erp ) ) { $? "! image analysis failed" xo->cs = dk4bif_get_color_space(bif); xo->bpc = dk4bif_get_original_bit_depth(bif); } $? ". after analysis" $? ". xo cs = %d", xo->cs $? ". xo bpc = %u", (unsigned)(xo->bpc) if (0 == acol) { switch (xo->cs) { case DK4_CS_RGB : case DK4_CS_CMYK : { xo->cs = DK4_CS_GRAY; $? ". switching to gray" } break; case DK4_CS_RGB_ALPHA : { xo->cs = DK4_CS_GRAY_ALPHA; $? ". switching to gray+a" } break; } } $? ". after correction for acol" $? ". xo cs = %d", xo->cs $? ". xo bpc = %u", (unsigned)(xo->bpc) } if (8 < xo->bpc) { xo->bpc = 8; $? ". bpc = %u", (unsigned)(xo->bpc) } if (NULL != fn) { xo->hufi = dk4ufi_get(&(xo->ufi), fn, erp); #if TRACE_DEBUG if (0 != xo->hufi) { $? ". dev = %llu", (unsigned long long)(xo->ufi.dev) $? ". ino = %llu", (unsigned long long)(xo->ufi.ino) } #endif } $? ". xo file name = \"%!ds\"", TR_STR(xo->fn) $? ". xo frame no = %lu", (unsigned long)(xo->fno) $? ". xo object no = %lu", (unsigned long)(xo->objno) $? ". xo mask no = %lu", (unsigned long)(xo->mobjno) $? ". xo width = %lu", (unsigned long)(xo->width) $? ". xo height = %lu", (unsigned long)(xo->height) $? ". xo dct = %d", xo->dct $? ". xo ipol = %d", xo->ipol $? ". xo cs = %d", xo->cs $? ". xo have ufi = %d", xo->hufi $? ". xo bpc = %u", (unsigned)(xo->bpc) $? "- dk4gra_pdf_xo_setup" } /** Add image data to i_mb component of xo, directly transfer DCT encoded data from JPEG file. @param xo XObject to fill with data. @param gra Graphics output structure. @param curpg Current page. @param bif Bitmap image file. @param fn Bitmap image file name. @param fno Frame number in bitmap image file. @param ipol Flag: Allow interpolation. @param ajpg Flag: Allow direct re-use of DCT encoded data from JPEG. @param ijpg Flag: Allow interpolation for DCT encoded data. @param anb Flag: Analyze bit depth. @param anc Flag: Analyze colors. @param ana Flag: Analyze alpha channel use. @param erp Error report, may be NULL. @return 1 on success, 0 on error. */ static int dk4gra_pdf_add_jpeg_data( dk4_gra_pdf_img_xo_t *xo, dk4_er_t *erp ) { char mybuf[128]; FILE *fipo = NULL; char *bptr = mybuf; char *aptr = NULL; size_t szbptr = sizeof(mybuf); size_t rdb; int fotest = DK4_FOPEN_SC_IS_REGULAR; int back = 0; int cc = 0; $? "+ dk4gra_pdf_add_jpeg_data" /* Attempt to allocate a larger buffer dynamically */ aptr = (char *)calloc(4096,1); if (NULL != aptr) { bptr = aptr; szbptr = 4096; } fipo = dk4fopen(xo->fn, dkT("rb"), fotest, erp); if (NULL == fipo) { $? "! failed to open file for reading" goto finished; } do { cc = 0; rdb = fread(bptr, 1, szbptr, fipo); $? ". %u bytes read", (unsigned)rdb if (0 < rdb) { cc = 1; if (1 != dk4membuf_store(xo->i_mb, bptr, rdb, erp)) { $? "! failed to add bytes to memory buffer" cc = -1; } } } while (1 == cc); if (0 == cc) { back = 1; } #if TRACE_DEBUG #if 0 if (0 != dk4membuf_size(&rdb, curpg->membuf, NULL)) { $? ". bytes in memory buffer: %lu", (unsigned long)rdb } else { $? "! failed to obtain memory buffer size" } #endif #endif finished: if (NULL != aptr) { dk4mem_free(aptr); } if (NULL != fipo) { fclose(fipo); } $? "- dk4gra_pdf_add_jpeg_data %d", back return back; } /** Add image data to i_mb component of xo, use dk4_bif_t methods to access pixel data. @param xo XObject to fill with data. @param gra Graphics output structure. @param bptr Current page. @param bif Bitmap image file. @param fn Bitmap image file name. @param fno Frame number in bitmap image file. @param ipol Flag: Allow interpolation. @param ajpg Flag: Allow direct re-use of DCT encoded data from JPEG. @param ijpg Flag: Allow interpolation for DCT encoded data. @param anb Flag: Analyze bit depth. @param anc Flag: Analyze colors. @param ana Flag: Analyze alpha channel use. @param erp Error report, may be NULL. @return 1 on success, 0 on error. */ static int dk4gra_pdf_add_bif_data( dk4_gra_pdf_img_xo_t *xo, dk4_bif_t *bif, dk4_er_t *erp ) { dk4_px_t pix[8]; dk4_bit_shift_t bs; dk4_stream_t *mbstrm = NULL; dk4_stream_t *costrm = NULL; size_t nco = 1; size_t y = 0; size_t x = 0; size_t i = 0; int back = 0; unsigned char uc = 0; $? "+ dk4gra_pdf_add_bif_data" /* Open streams to write compressed data to memory buffer */ mbstrm = dk4stream_open_membuf_writer(xo->i_mb, erp); if (NULL == mbstrm) { $? "! mb stream" goto finished; } costrm = dk4strmco_open( mbstrm, DK4_STRMCO_PP_NONE, DK4_STRMCO_CO_FLATE, DK4_STRMCO_OE_NONE, 0, erp ); if (NULL == costrm) { $? "! co stream" goto finished; } /* Find color space size */ $? ". xo cs = %d", xo->cs nco = dk4cs_color_space_size(xo->cs); $? ". nco = %u", (unsigned)nco if ((DK4_CS_GRAY_ALPHA == xo->cs) || (DK4_CS_RGB_ALPHA == xo->cs)) { nco--; } $? ". nco = %u", (unsigned)nco back = 1; dk4bif_set_output_bit_depth(bif, xo->bpc); if (8 == xo->bpc) { for (y = 0; y < (size_t)(xo->height); y++) { for (x = 0; x < (size_t)(xo->width); x++) { if ( 0 == dk4bif_get_pixel( pix, 8, bif, (dk4_bif_dim_t)y, (dk4_bif_dim_t)x, xo->cs ) ) { back = 0; $? "! dk4bif_get_pixel" } for (i = 0; i < nco; i++) { if (0 == dk4stream_write_byte(costrm,(char)(pix[i]),erp)) { back = 0; $? "! dk4stream_write_byte" } } } } } else { for (y = 0; y < (size_t)(xo->height); y++) { dk4bit_shift_init(&bs, erp); for (x = 0; x < (size_t)(xo->width); x++) { if ( 0 == dk4bif_get_pixel( pix, 8, bif, (dk4_bif_dim_t)y, (dk4_bif_dim_t)x, xo->cs ) ) { back = 0; $? "! dk4bif_get_pixel" } for (i = 0; i < nco; i++) { dk4gratool_put_pixel_value( costrm, &bs, pix[i], xo->bpc, &back, erp ); } } switch (dk4bit_shift_finish(&bs, erp)) { case DK4_EDSTM_FINISHED : { uc = dk4bit_shift_output(&bs, erp); if (0 == dk4stream_write_byte(costrm, (char)uc, erp)) { back = 0; $? "! dk4stream_write_byte" } } break; case DK4_EDSTM_ERROR : { back = 0; } break; } } } /* Cleanup */ finished: if (NULL != costrm) { if (0 == dk4stream_close(costrm, erp)) { $? "! close co stream" back = 0; } } if (NULL != mbstrm) { if (0 == dk4stream_close(mbstrm, erp)) { $? "! close mb stream" back = 0; } } $? "- dk4gra_pdf_add_bif_data %d", back return back; } /** Add image data to xo. to obtain image data. @param xo XObject to fill with data. @param gra Graphics output structure. @param bptr Current page. @param bif Bitmap image file. @param fn Bitmap image file name. @param fno Frame number in bitmap image file. @param ipol Flag: Allow interpolation. @param ajpg Flag: Allow direct re-use of DCT encoded data from JPEG. @param ijpg Flag: Allow interpolation for DCT encoded data. @param anb Flag: Analyze bit depth. @param anc Flag: Analyze colors. @param ana Flag: Analyze alpha channel use. @param erp Error report, may be NULL. @return 1 on success, 0 on error. */ static int dk4gra_pdf_add_image_data( dk4_gra_pdf_img_xo_t *xo, dk4_bif_t *bif, int ajpg, dk4_er_t *erp ) { int back = 0; $? "+ dk4gra_pdf_add_image_data" if ((DK4_BIF_TYPE_JPEG == bif->imgtype) && (0 != ajpg)) { $? ". DCT data" back = dk4gra_pdf_add_jpeg_data(xo, erp); } else { $? ". normal data" back = dk4gra_pdf_add_bif_data(xo, bif, erp); } $? "- dk4gra_pdf_add_image_data %d", back return back; } /** Add image mask data to m_mb component of xo. @param xo XObject to fill with data. @param gra Graphics output structure. @param bptr Current page. @param bif Bitmap image file. @param fn Bitmap image file name. @param fno Frame number in bitmap image file. @param ipol Flag: Allow interpolation. @param ajpg Flag: Allow direct re-use of DCT encoded data from JPEG. @param ijpg Flag: Allow interpolation for DCT encoded data. @param anb Flag: Analyze bit depth. @param anc Flag: Analyze colors. @param erp Error report, may be NULL. @return 1 on success, 0 on error. */ static int dk4gra_pdf_add_image_mask( dk4_gra_pdf_img_xo_t *xo, dk4_bif_t *bif, dk4_er_t *erp ) { dk4_px_t pix[8]; dk4_bit_shift_t bs; dk4_stream_t *mbstrm = NULL; dk4_stream_t *costrm = NULL; size_t y; size_t x; size_t numco; int back = 0; unsigned char uc; $? "+ dk4gra_pdf_add_image_mask" /* Open streams to write compressed data to memory buffer */ mbstrm = dk4stream_open_membuf_writer(xo->m_mb, erp); if (NULL == mbstrm) { $? "! failed to open mb stream" goto finished; } costrm = dk4strmco_open( mbstrm, DK4_STRMCO_PP_NONE, DK4_STRMCO_CO_FLATE, DK4_STRMCO_OE_NONE, 0, erp ); if (NULL == costrm) { $? "! failed to open co stream" goto finished; } /* Success so far */ back = 1; numco = dk4cs_color_space_size(xo->cs); numco--; if (8 == xo->bpc) { for (y = 0; y < (size_t)(xo->height); y++) { for (x = 0; x < (size_t)(xo->width); x++) { if ( 0 == dk4bif_get_pixel( pix, 8, bif, (dk4_bif_dim_t)y, (dk4_bif_dim_t)x, xo->cs ) ) { back = 0; $? "! dk4bif_get_pixel" } uc = (unsigned char)(pix[numco]); if (0 == dk4stream_write_byte(costrm, (char)uc, erp)) { back = 0; $? "! dk4stream_write_byte" } } } } else { for (y = 0; y < (size_t)(xo->height); y++) { dk4bit_shift_init(&bs, erp); for (x = 0; x < (size_t)(xo->width); x++) { if ( 0 == dk4bif_get_pixel( pix, 8, bif, (dk4_bif_dim_t)y, (dk4_bif_dim_t)x, xo->cs ) ) { back = 0; $? "! dk4bif_get_pixel" } dk4gratool_put_pixel_value( costrm, &bs, pix[numco], xo->bpc, &back, erp ); } switch (dk4bit_shift_finish(&bs, erp)) { case DK4_EDSTM_FINISHED : { uc = dk4bit_shift_output(&bs, erp); if (0 == dk4stream_write_byte(costrm, (char)uc, erp)) { back = 0; $? "! dk4stream_write_byte" } } break; case DK4_EDSTM_ERROR : { back = 0; } break; } } } /* Clean up before returning */ finished: if (NULL != costrm) { if (0 == dk4stream_close(costrm, erp)) { $? "! close co stream" back = 0; } } if (NULL != mbstrm) { if (0 == dk4stream_close(mbstrm, erp)) { $? "! close mb stream" back = 0; } } $? "- dk4gra_pdf_add_image_mask %d", back return back; } /** create a new object. @param xo Source XObject. @param gra Graphics output structure. @param bptr Current page. @param bif Bitmap image file. @param fn Bitmap image file name. @param fno Frame number in bitmap image file. @param ipol Flag: Allow interpolation. @param ajpg Flag: Allow direct re-use of DCT encoded data from JPEG. @param ijpg Flag: Allow interpolation for DCT encoded data. @param anb Flag: Analyze bit depth. @param anc Flag: Analyze colors. @param ana Flag: Analyze alpha channel use. @param erp Error report, may be NULL. @return Valid pointer to new XObject, NULL on error. */ static dk4_gra_pdf_img_xo_t * dk4gra_pdf_xo_create( dk4_gra_pdf_img_xo_t *xo, dk4_gra_t *gra, dk4_bif_t *bif, int ajpg, dk4_er_t *erp ) { dk4_gra_pdf_img_xo_t *back = NULL; int ok = 0; $? "+ dk4gra_pdf_xo_create %lu", (unsigned long)(xo->objno) /* Allocate memory */ back = dk4mem_new(dk4_gra_pdf_img_xo_t,1,erp); if (NULL == back) { $? "! failed to allocate memory" goto finished; } /* Copy existing information */ dk4mem_cpy(back, xo, sizeof(dk4_gra_pdf_img_xo_t), NULL); /* Create own copy of file name */ if (NULL != xo->fn) { back->fn = dk4str_dup(xo->fn, erp); if (NULL == back->fn) { $? "! failed to duplicate file name" goto finished; } } else { back->fn = NULL; } /* Open memory buffers */ $? ". xo cs = %d", xo->cs back->i_mb = dk4membuf_open(erp); if (NULL == back->i_mb) { $? "! failed to open image mem buf" goto finished; } if ((DK4_CS_GRAY_ALPHA == xo->cs) || (DK4_CS_RGB_ALPHA == xo->cs)) { back->m_mb = dk4membuf_open(erp); if (NULL == back->m_mb) { $? "! failed to open mask mem buf" goto finished; } } ok = dk4gra_pdf_add_image_data( back, bif, ajpg, erp ); if (0 != ok) { $? ". image data added" if ((DK4_CS_GRAY_ALPHA == xo->cs) || (DK4_CS_RGB_ALPHA == xo->cs)) { ok = dk4gra_pdf_add_image_mask(back,bif,erp); #if TRACE_DEBUG if (0 == ok) { $? "! failed to add mask data" } #endif } } if (0 != ok) { if (0 == dk4sto_add(gra->out.pdf.s_images, back, erp)) { ok = 0; $? "! failed to add to storage" } else { if (0 == dk4sto_add(gra->out.pdf.s_imagno, back, erp)) { ok = 0; $? "! failed to add to storage" } } } #if TRACE_DEBUG else { $? "! failed to add image data" } #endif finished: /* Clean up and return NULL on errors */ if ((NULL != back) && (0 == ok)) { /* Delete XObject */ dk4gra_pdf_xo_delete(back); back = NULL; } /* If we have a new object, correct next object number in gra */ if (NULL != back) { gra->out.pdf.nextobj += 1; if (NULL != back->m_mb) { back->mobjno = gra->out.pdf.nextobj; gra->out.pdf.nextobj += 1; } } $? "- dk4gra_pdf_xo_create %d", TR_IPTR(back) return back; } /** Find object or create a new one. @param xo XObject to fill with data. @param gra Graphics output structure. @param bptr Current page. @param bif Bitmap image file. @param fn Bitmap image file name. @param fno Frame number in bitmap image file. @param ipol Flag: Allow interpolation. @param ajpg Flag: Allow direct re-use of DCT encoded data from JPEG. @param ijpg Flag: Allow interpolation for DCT encoded data. @param anb Flag: Analyze bit depth. @param anc Flag: Analyze colors. @param ana Flag: Analyze alpha channel use. @param erp Error report, may be NULL. @return Valid pointer to found or new XObject, NULL on error. */ static dk4_gra_pdf_img_xo_t * dk4gra_pdf_find_or_create( dk4_gra_pdf_img_xo_t *xo, dk4_gra_t *gra, dk4_bif_t *bif, int ajpg, dk4_er_t *erp ) { dk4_gra_pdf_img_xo_t *back = NULL; $? "+ dk4gra_pdf_find_or_create" back = (dk4_gra_pdf_img_xo_t *)dk4sto_it_find_like( gra->out.pdf.i_images, xo, 0 ); if (NULL == back) { $? ". must create new xo" back = dk4gra_pdf_xo_create(xo, gra, bif, ajpg, erp); } #if TRACE_DEBUG else { $? ". found existing xo" } #endif $? "- dk4gra_pdf_find_or_create %d", TR_IPTR(back) return back; } /** Register XObject for use on page (add to the pages container of used XObjects if not yet present). @param bptr Current page. @param xo XObject to use on page. @param erp Error report, may be NULL. @return 1 on success, 0 on error. */ static int dk4gra_pdf_register_xo_for_page( dk4_gra_pdf_page_t *bptr, dk4_gra_pdf_img_xo_t *xo, dk4_er_t *erp ) { int back = 0; $? "+ dk4gra_pdf_register_xo_for_page %lu", (unsigned long)(xo->objno) if (NULL == bptr->s_uxo) { bptr->s_uxo = dk4sto_open(erp); if (NULL == bptr->s_uxo) { $? "! failed to create storage" goto finished; } dk4sto_set_comp(bptr->s_uxo, dk4gra_pdf_compare_used_xo, 0); } if (NULL == bptr->i_uxo) { bptr->i_uxo = dk4sto_it_open(bptr->s_uxo, erp); if (NULL == bptr->i_uxo) { $? "! failed to create iterator" goto finished; } } if (NULL != dk4sto_it_find_like(bptr->i_uxo, xo, 0)) { back = 1; $? ". found existing object" } else { if (0 != dk4sto_add(bptr->s_uxo, xo, erp)) { back = 1; $? ". added new object" } #if TRACE_DEBUG else { $? "! failed to add object" } #endif } finished: $? "- dk4gra_pdf_register_xo_for_page %d", back return back; } int dk4gra_pdf_bif_fig_image( dk4_gra_t *gra, double *cotra, dk4_bif_t *bif, const dkChar *fn, size_t fno, int ifl, dk4_er_t *erp ) { dk4_gra_pdf_img_xo_t testxo; dk4_gra_pdf_img_xo_t *xo; dk4_gra_pdf_page_t *bptr; double cm[6]; dk4_px_t gbg[4]; double cosphi; double sinphi; size_t i; int back = 0; $? "+ dk4gra_pdf_bif_fig_image \"%!ds\"", TR_STR(fn) #if DK4_USE_ASSERT assert(NULL != gra); assert(NULL != cotra); assert(NULL != bif); assert(NULL != fn); #endif $? ". fno = %u", (unsigned)fno $? ". ipol = %d", (DK4_GRA_IMG_FLAG_INTERPOLATION & ifl) $? ". ajpg = %d", (DK4_GRA_IMG_FLAG_DCT & ifl) $? ". ijpg = %d", (DK4_GRA_IMG_FLAG_DCT_INTERPOLATION & ifl) $? ". acol = %d", (DK4_GRA_IMG_FLAG_COLOR & ifl) $? ". anb = %d", (DK4_GRA_IMG_FLAG_ANALYZE_BPC & ifl) $? ". anc = %d", (DK4_GRA_IMG_FLAG_ANALYZE_COLOR & ifl) $? ". ana = %d", (DK4_GRA_IMG_FLAG_ANALYZE_ALPHA & ifl) $? ". fbgf = %d", (DK4_GRA_IMG_FLAG_FILL_BACKGROUND & ifl) bptr = (dk4_gra_pdf_page_t *)(gra->curpg); if (NULL == bptr->outstrm) { $? "! not output stream for page" dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (0 == (DK4_GRA_IMG_FLAG_COLOR & ifl)) { $? ". no color" if (DK4_CS_GRAY != dk4bif_get_color_space(bif)) { $? ". not gray" if (DK4_CS_GRAY_ALPHA != dk4bif_get_color_space(bif)) { ifl &= (~(DK4_GRA_IMG_FLAG_DCT)); $? ". ajpg = 0" } } } $? ". set up xo" dk4gra_pdf_xo_setup( &testxo, gra, bif, fn, fno, ((0 != (DK4_GRA_IMG_FLAG_INTERPOLATION & ifl)) ? (1) : (0)), ((0 != (DK4_GRA_IMG_FLAG_DCT & ifl)) ? (1) : (0)), ((0 != (DK4_GRA_IMG_FLAG_DCT_INTERPOLATION & ifl)) ? (1) : (0)), ((0 != (DK4_GRA_IMG_FLAG_COLOR & ifl)) ? (1) : (0)), ((0 != (DK4_GRA_IMG_FLAG_ANALYZE_BPC & ifl)) ? (1) : (0)), ((0 != (DK4_GRA_IMG_FLAG_ANALYZE_COLOR & ifl)) ? (1) : (0)), ((0 != (DK4_GRA_IMG_FLAG_ANALYZE_ALPHA & ifl)) ? (1) : (0)), erp ); xo = dk4gra_pdf_find_or_create( &testxo, gra, bif, ((0 != (DK4_GRA_IMG_FLAG_DCT & ifl)) ? (1) : (0)), erp ); if (NULL != xo) { $? ". xo found" if (0 != dk4gra_pdf_register_xo_for_page(bptr, xo, erp)) { $? ". xo registered" back = 1; dk4gra_pdf_save_attributes(gra); dk4gra_i_gsave(gra, &back, erp); #if 1 /* One CTM for combined translate, rotate and scale */ for (i = 0; i < sizeof(cm)/sizeof(double); i++) { cm[i] = 0.0; } cosphi = cos((M_PI * cotra[2]) / 180.0); sinphi = sin((M_PI * cotra[2]) / 180.0); cm[0] = cotra[3] * cosphi; cm[1] = cotra[3] * sinphi; cm[2] = 0.0 - cotra[4] * sinphi; cm[3] = cotra[4] * cosphi; if ( (DK4_GRA_EPSILON_COORDINATES < fabs(cotra[0])) || (DK4_GRA_EPSILON_COORDINATES < fabs(cotra[1])) ) { cm[4] = cotra[0]; cm[5] = cotra[1]; } dk4gra_pdf_i_values_and_kw(bptr->outstrm, cm, 6, 70, &back, erp); #else /* Old code - no longer used - performing multiple CTM changes for a sequence of translate, rotate, and scale operations */ $? ". multiple CTMS for translate rotate scale" /* translate */ if ( (DK4_GRA_EPSILON_COORDINATES < fabs(cotra[0])) || (DK4_GRA_EPSILON_COORDINATES < fabs(cotra[1])) ) { for (i = 0; i < sizeof(cm)/sizeof(double); i++) { cm[i] = 0.0; } cm[0] = 1.0; cm[3] = 1.0; cm[4] = cotra[0]; cm[5] = cotra[1]; dk4gra_pdf_i_values_and_kw(bptr->outstrm,cm,6,70,&back,erp); } /* rotate */ if (DK4_GRA_EPSILON_COORDINATES < fabs(cotra[2])) { for (i = 0; i < sizeof(cm)/sizeof(double); i++) { cm[i] = 0.0; } cm[0] = cosphi; cm[1] = sinphi; cm[2] = 0.0 - sinphi; cm[3] = cosphi; dk4gra_pdf_i_values_and_kw(bptr->outstrm,cm,6,70,&back, erp); } /* scale */ for (i = 0; i < sizeof(cm)/sizeof(double); i++) { cm[i] = 0.0; } cm[0] = cotra[3]; cm[3] = cotra[4]; dk4gra_pdf_i_values_and_kw(bptr->outstrm, cm, 6, 70, &back, erp); #endif /* Fill image background with background color if required */ if (0 != (DK4_GRA_IMG_FLAG_FILL_BACKGROUND & ifl)) { $? ". fill background first before applying image" switch (bif->cf->l_cs) { case DK4_CS_RGB_ALPHA : { if (0 != (DK4_GRA_IMG_FLAG_COLOR & ifl)) { $? ". fill rgb" for (i = 0; i < 3; i++) { cm[i] = ((double)(bif->cf->bglbd[i])) / ((double)dk4pxbit_get_max(bif->cf->l_bdepth)); if (0.0 > cm[i]) { cm[i] = 0.0; } if (1.0 < cm[i]) { cm[i] = 1.0; } } dk4gra_pdf_fill_rectangle( bptr->outstrm, cm, 3, 2, &back, erp ); } else { dk4cs_px_convert( gbg, DK4_CS_GRAY, DK4_SIZEOF(gbg,dk4_px_t), &(bif->cf->bglbd[0]), DK4_CS_RGB, 3, NULL, 0, dk4pxbit_get_max(bif->cf->l_bdepth), &(bif->cs_ctx), erp ); for (i = 0; i < 1; i++) { cm[i] = ((double)(gbg[i])) / ((double)dk4pxbit_get_max(bif->cf->l_bdepth)); if (0.0 > cm[i]) { cm[i] = 0.0; } if (1.0 < cm[i]) { cm[i] = 1.0; } } dk4gra_pdf_fill_rectangle( bptr->outstrm, cm, 1, 1, &back, erp ); } } break; case DK4_CS_GRAY_ALPHA : { $? ". fill gray" for (i = 0; i < 1; i++) { cm[i] = ((double)(bif->cf->bglbd[i])) / ((double)dk4pxbit_get_max(bif->cf->l_bdepth)); if (0.0 > cm[i]) { cm[i] = 0.0; } if (1.0 < cm[i]) { cm[i] = 1.0; } } dk4gra_pdf_fill_rectangle( bptr->outstrm, cm, 1, 1, &back, erp ); } break; } } /* Write Do operator to stream */ /* /X */ dk4gra_pdf_i_outstream_kw(bptr->outstrm, 71, &back, erp); /* number */ dk4gratool_stream_uint(bptr->outstrm, xo->objno, 0, &back, erp); /* space and Do */ dk4gra_pdf_i_outstream_kw(bptr->outstrm, 72, &back, erp); dk4gra_i_grestore(gra, 0, &back, erp); dk4gra_pdf_restore_attributes(gra); } #if TRACE_DEBUG else { $? "! failed to register xo" } #endif } #if TRACE_DEBUG else { $? "! no xo found" } #endif finished: $? "- dk4gra_pdf_bif_fig_image %d", back return back; } /* vim: set ai sw=4 ts=4 : */