| 4156 | } |
| 4157 | |
| 4158 | int PSL_setimage (struct PSL_CTRL *PSL, int image_no, char *imagefile, unsigned char *image, int image_dpi, unsigned int dim[], double f_rgb[], double b_rgb[]) { |
| 4159 | /* Set up image pattern fill |
| 4160 | * image_no: Number of the standard PSL fill pattern (use negative when file name used instead) |
| 4161 | * imagefile: Name of image file (not used if image_no = [1,90]) |
| 4162 | * image: The bytestream making up the image (not used if image_no = [1,90]) |
| 4163 | * image_dpi: Resolution of image on the page |
| 4164 | * dim: Image number of columns, rows, and bit depth (not used if image_no = [1,90]) |
| 4165 | * f_rgb: Foreground color used for set bits (1) (1-bit only) |
| 4166 | * b_rgb: Background color used for unset bits (0) (1-bit only) |
| 4167 | * Returns image number |
| 4168 | */ |
| 4169 | |
| 4170 | int mask, id, inv, k; |
| 4171 | uint64_t nx, ny; |
| 4172 | const char *colorspace[3] = {"Gray", "RGB", "CMYK"}; /* What kind of image we are writing */ |
| 4173 | const char *decode[3] = {"0 1", "0 1 0 1 0 1", "0 1 0 1 0 1 0 1"}; /* What kind of color decoding */ |
| 4174 | const char *kind_mask[2] = {"image", "imagemask"}; |
| 4175 | |
| 4176 | /* Determine if image was used before */ |
| 4177 | |
| 4178 | if ((image_no > 0 && image_no <= PSL_N_PATTERNS) && !PSL->internal.pattern[image_no-1].status) { /* Unused predefined */ |
| 4179 | if ((image_no = psl_pattern_init (PSL, image_no, NULL, NULL, 64, 64, 1)) < 0) return -1; /* Error in psl_pattern_init */ |
| 4180 | } |
| 4181 | else if (image_no < 0) { /* User image, check if already used */ |
| 4182 | int i = psl_search_userimages (PSL, imagefile); /* i = 0 is the first user image */ |
| 4183 | if (i == -1) /* Not found or no previous user images loaded */ |
| 4184 | image_no = psl_pattern_init (PSL, -1, imagefile, image, dim[0], dim[1], dim[2]); |
| 4185 | else |
| 4186 | image_no = PSL_N_PATTERNS + i + 1; |
| 4187 | if (image_no < 0) return -1; /* Error in psl_pattern_init */ |
| 4188 | } |
| 4189 | k = image_no - 1; /* Image array index */ |
| 4190 | nx = PSL->internal.pattern[k].nx; |
| 4191 | ny = PSL->internal.pattern[k].ny; |
| 4192 | |
| 4193 | id = (PSL->internal.color_mode == PSL_CMYK) ? 2 : 1; |
| 4194 | mask = (PSL->internal.pattern[k].depth == 1 && (f_rgb[0] < 0.0 || b_rgb[0] < 0.0)); |
| 4195 | |
| 4196 | /* When DPI or colors have changed, the /pattern procedure needs to be rewritten */ |
| 4197 | |
| 4198 | if (PSL->internal.pattern[k].dpi != image_dpi || |
| 4199 | !PSL_same_rgb(PSL->internal.pattern[k].f_rgb,f_rgb) || |
| 4200 | !PSL_same_rgb(PSL->internal.pattern[k].b_rgb,b_rgb)) { |
| 4201 | |
| 4202 | PSL_comment (PSL, "Setup %s fill using pattern %d\n", kind_mask[mask], image_no); |
| 4203 | if (image_dpi) { /* Use given DPI */ |
| 4204 | nx = lrint (nx * PSL->internal.dpu / image_dpi); |
| 4205 | ny = lrint (ny * PSL->internal.dpu / image_dpi); |
| 4206 | } |
| 4207 | PSL_command (PSL, "/pattern%d {V %" PRIu64 " %" PRIu64 " scale", image_no, nx, ny); |
| 4208 | PSL_command (PSL, "\n<< /PaintType 1 /PatternType 1 /TilingType 1 /BBox [0 0 1 1] /XStep 1 /YStep 1 /PaintProc\n {begin"); |
| 4209 | |
| 4210 | if (PSL->internal.pattern[k].depth == 1) { /* 1-bit bitmap basis */ |
| 4211 | inv = psl_bitimage_cmap (PSL, f_rgb, b_rgb) % 2; |
| 4212 | PSL_command (PSL, "\n<< /ImageType 1 /Decode [%d %d]", inv, 1-inv); |
| 4213 | } |
| 4214 | else |
| 4215 | PSL_command (PSL, " /Device%s setcolorspace\n<< /ImageType 1 /Decode [%s]", colorspace[id], decode[id]); |
no test coverage detected