1 /*
2 * Author: William Chia-Wei Cheng (bill.cheng@acm.org)
3 *
4 * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5 *
6 * This file may be distributed under the terms of the Q Public License
7 * as defined by Trolltech AS of Norway and appearing in the file
8 * LICENSE.QPL included in the packaging of this file.
9 *
10 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * @(#)$Header: /mm2/home/cvs/bc-src/tgif/xpixmap.c,v 1.89 2011/05/16 16:22:00 william Exp $
19 */
20
21 #define _INCLUDE_FROM_XPIXMAP_C_
22
23 #include "tgifdefs.h"
24
25 #include "attr.e"
26 #include "auxtext.e"
27 #include "choice.e"
28 #include "cmd.e"
29 #include "color.e"
30 #include "cursor.e"
31 #include "cutpaste.e"
32 #include "dialog.e"
33 #include "drawing.e"
34 #include "dup.e"
35 #include "file.e"
36 #include "font.e"
37 #include "grid.e"
38 #include "hash.e"
39 #include "http.e"
40 #include "imgproc.e"
41 #include "import.e"
42 #include "mainloop.e"
43 #include "mainmenu.e"
44 #include "mark.e"
45 #include "move.e"
46 #include "msg.e"
47 #include "names.e"
48 #include "obj.e"
49 #include "page.e"
50 #include "pattern.e"
51 #include "pngtrans.e"
52 #include "ps.e"
53 #include "raster.e"
54 #include "rect.e"
55 #include "select.e"
56 #include "setup.e"
57 #include "stretch.e"
58 #include "strtbl.e"
59 #include "util.e"
60 #include "xbitmap.e"
61 #include "xpixmap.e"
62 #include "z_intrf.e"
63
64 struct BucketRec {
65 int pixel, index, color_index;
66 char s[40];
67 };
68
69 #define XPM_BUCKETS 67
70 #define XPM_BUCKET_INC 10
71
72 #define TYPE_PPM3 3
73 #define TYPE_PPM5 5
74 #define TYPE_PPM6 6
75
76 GC xpmGC=NULL;
77
78 int newColormapUsed=FALSE;
79 int allocColorFailed=FALSE;
80 int myReadTransparentPixmap=FALSE;
81
82 int xpmIsArray=FALSE;
83 long xpmArraySeek=(-1L);
84
85 int xpmHasTooManyColorsForPrinting=FALSE;
86
87 int hasReadHexString=FALSE;
88
89 PngHeaderInfo gPngHeaderInfo;
90
91 double rotatedSine[4]={ 0.0, 1.0, 0.0, -1.0 };
92 double rotatedCosine[4]={ 1.0, 0.0, -1.0, 0.0 };
93
94 static Pixmap dummyPixmap=None;
95
96 /* do not translate -- program constants */
97 static char hexValue[]="0123456789abcdef";
98
99 static int askForXPmSpec=FALSE;
100 static int guessXPmBgColor=FALSE;
101 static int littleEndianPpm6=FALSE;
102
103 static struct BucketRec **xpmBucket=NULL;
104 static int *xpmBucketSize=NULL;
105 static int *xpmBucketMaxSize=NULL;
106
107 static int shownXPmErrorMessage=FALSE;
108
109 static TgHash gColorsHashForPrinting;
110 static int gnColorsHashForPrintingValid=FALSE;
111
ResetXPmErrorMessage()112 void ResetXPmErrorMessage()
113 {
114 shownXPmErrorMessage = FALSE;
115 }
116
InitXPm()117 void InitXPm()
118 {
119 register int i;
120 XGCValues values;
121 char *c_ptr;
122
123 dummyPixmap = XCreatePixmap(mainDisplay, mainWindow, 1, 1, mainDepth);
124
125 values.foreground = myFgPixel;
126 values.background = myBgPixel;
127 values.function = GXcopy;
128 values.fill_style = FillSolid;
129 xpmGC = XCreateGC(mainDisplay, dummyPixmap,
130 GCForeground | GCBackground | GCFunction | GCFillStyle, &values);
131
132 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"AskForXPmSpec")) != NULL) {
133 if (UtilStrICmp(c_ptr, "true") == 0) {
134 askForXPmSpec = TRUE;
135 } else {
136 askForXPmSpec = FALSE;
137 }
138 }
139 guessXPmBgColor = FALSE;
140 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"GuessXPmBgColor"))!=NULL) {
141 if (UtilStrICmp(c_ptr, "true") == 0) {
142 guessXPmBgColor = TRUE;
143 }
144 }
145 littleEndianPpm6 = FALSE;
146 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"LittleEndianPpm6"))!=NULL) {
147 if (UtilStrICmp(c_ptr, "true") == 0) {
148 littleEndianPpm6 = TRUE;
149 }
150 }
151 newColormapUsed = FALSE;
152
153 xpmBucket =
154 (struct BucketRec **)malloc(XPM_BUCKETS*sizeof(struct BucketRec *));
155 xpmBucketSize = (int*)malloc((XPM_BUCKETS+1)*sizeof(int));
156 xpmBucketMaxSize = (int*)malloc(XPM_BUCKETS*sizeof(int));
157 if (xpmBucket == NULL || xpmBucketSize == NULL || xpmBucketMaxSize == NULL) {
158 FailAllocMessage();
159 }
160 for (i=0; i < XPM_BUCKETS; i++) {
161 xpmBucket[i] =
162 (struct BucketRec *)malloc(XPM_BUCKET_INC*sizeof(struct BucketRec));
163 if (xpmBucket[i] == NULL) FailAllocMessage();
164 xpmBucketSize[i] = 0;
165 xpmBucketMaxSize[i] = XPM_BUCKET_INC;
166 }
167 xpmBucketSize[XPM_BUCKETS] = INVALID;
168
169 memset(&gPngHeaderInfo, 0, sizeof(PngHeaderInfo));
170 }
171
CleanUpXPm()172 void CleanUpXPm()
173 {
174 register int i;
175
176 if (xpmGC != NULL) XFreeGC(mainDisplay, xpmGC);
177 XFreePixmap(mainDisplay, dummyPixmap);
178
179 askForXPmSpec = FALSE;
180 for (i = 0; i < XPM_BUCKETS; i++) free(xpmBucket[i]);
181 free(xpmBucket);
182 free(xpmBucketSize);
183 free(xpmBucketMaxSize);
184 xpmBucket = NULL;
185 xpmBucketSize = xpmBucketMaxSize = NULL;
186 }
187
IsLinkedJpegObj(obj_ptr)188 int IsLinkedJpegObj(obj_ptr)
189 struct ObjRec *obj_ptr;
190 {
191 struct XPmRec *xpm_ptr=obj_ptr->detail.xpm;
192 int real_type=xpm_ptr->real_type, linked_jpeg=xpm_ptr->linked_jpeg;
193 char *jpeg_filename=xpm_ptr->filename;
194
195 /* if the object is a linked JPEG file, will not perform imageproc */
196 return (real_type == XPM_JPEG && linked_jpeg && jpeg_filename != NULL);
197 }
198
IsPpmTrueObj(real_type,ppm_data_compress,ppm_data)199 int IsPpmTrueObj(real_type, ppm_data_compress, ppm_data)
200 int real_type, ppm_data_compress;
201 char *ppm_data;
202 {
203 return (real_type == PPM_TRUE &&
204 (ppm_data_compress == PPM_JPEG_COMPRESS ||
205 ppm_data_compress == PPM_DATA_DEFLATED) && ppm_data != NULL);
206 }
207
ObjHasIndexedTransPixel(obj_ptr,pn_index)208 int ObjHasIndexedTransPixel(obj_ptr, pn_index)
209 struct ObjRec *obj_ptr;
210 int *pn_index;
211 {
212 struct XPmRec *xpm_ptr=obj_ptr->detail.xpm;
213 int i=0, ncolors=xpm_ptr->ncolors, *pixels=xpm_ptr->pixels;
214
215 switch (xpm_ptr->real_type) {
216 case XPM_XPM:
217 for (i=0; i < ncolors; i++) {
218 if (pixels[i] == (-1)) {
219 if (pn_index != NULL) *pn_index = i;
220 return TRUE;
221 }
222 }
223 break;
224 case XPM_JPEG: break;
225 case PPM_TRUE: break;
226 }
227 return FALSE;
228 }
229
ObjHasTrueColorTransPixel(obj_ptr,puch_trans_color_r,puch_trans_color_g,puch_trans_color_b)230 int ObjHasTrueColorTransPixel(obj_ptr, puch_trans_color_r, puch_trans_color_g,
231 puch_trans_color_b)
232 struct ObjRec *obj_ptr;
233 unsigned char *puch_trans_color_r, *puch_trans_color_g, *puch_trans_color_b;
234 {
235 struct XPmRec *xpm_ptr=obj_ptr->detail.xpm;
236
237 switch (xpm_ptr->real_type) {
238 case XPM_XPM: break;
239 case XPM_JPEG: break;
240 case PPM_TRUE:
241 if (((PRTGIF && !cmdLineOpenDisplay) || fullTrueColorMode) && xpm_ptr->has_transparent_color) {
242 if (puch_trans_color_r != NULL) *puch_trans_color_r = xpm_ptr->transparent_color[0];
243 if (puch_trans_color_g != NULL) *puch_trans_color_g = xpm_ptr->transparent_color[1];
244 if (puch_trans_color_b != NULL) *puch_trans_color_b = xpm_ptr->transparent_color[2];
245 return TRUE;
246 }
247 break;
248 }
249 return FALSE;
250 }
251
ObjHasTransPixel(obj_ptr)252 int ObjHasTransPixel(obj_ptr)
253 struct ObjRec *obj_ptr;
254 {
255 struct XPmRec *xpm_ptr=obj_ptr->detail.xpm;
256
257 switch (xpm_ptr->real_type) {
258 case XPM_XPM: return ObjHasIndexedTransPixel(obj_ptr, NULL);
259 case XPM_JPEG: break;
260 case PPM_TRUE: return ObjHasTrueColorTransPixel(obj_ptr, NULL, NULL, NULL);
261 }
262 return FALSE;
263 }
264
265 #define xpmpixelhash(X) (((X)==(-1)) ? (XPM_BUCKETS-1) : ((X)%XPM_BUCKETS))
266
267 static
xpmcharhash(chars_per_pixel,color_char)268 int xpmcharhash(chars_per_pixel, color_char)
269 int chars_per_pixel;
270 char *color_char;
271 {
272 register int i, val=0;
273
274 for (i = 0; i < chars_per_pixel; i++) val = (val<<1)+(int)(color_char[i]);
275 return (xpmpixelhash(val));
276 }
277
BuildXPmBuckets(ncolors,pixels,dump_index_to_color_index,chars_per_pixel,color_char,pxtii)278 int BuildXPmBuckets(ncolors, pixels, dump_index_to_color_index, chars_per_pixel,
279 color_char, pxtii)
280 int ncolors, *pixels, *dump_index_to_color_index, chars_per_pixel;
281 char *color_char;
282 XpmTransIndexInfo *pxtii;
283 {
284 register int *ptr=NULL, i;
285 int bucket=0;
286
287 if (xpmBucketSize == NULL) {
288 xpmBucket =
289 (struct BucketRec **)malloc(XPM_BUCKETS*sizeof(struct BucketRec *));
290 xpmBucketSize = (int*)malloc((XPM_BUCKETS+1)*sizeof(int));
291 xpmBucketMaxSize = (int*)malloc(XPM_BUCKETS*sizeof(int));
292 if (xpmBucket==NULL || xpmBucketSize==NULL || xpmBucketMaxSize==NULL) {
293 FailAllocMessage();
294 }
295 for (i=0; i < XPM_BUCKETS; i++) {
296 xpmBucket[i] = (struct BucketRec *)malloc(
297 XPM_BUCKET_INC*sizeof(struct BucketRec));
298 if (xpmBucket[i] == NULL) FailAllocMessage();
299 xpmBucketSize[i] = 0;
300 xpmBucketMaxSize[i] = XPM_BUCKET_INC;
301 }
302 xpmBucketSize[XPM_BUCKETS] = INVALID;
303 }
304
305 for (ptr = xpmBucketSize; *ptr != INVALID; ptr++) *ptr = 0;
306
307 if (chars_per_pixel == INVALID) {
308 /* build the hash table according to the pixels */
309 for (i=0; i < ncolors; i++) {
310 if (pxtii != NULL) {
311 if (pxtii->has_transparent_pixel && pixels[i] == INVALID) {
312 #ifdef _TGIF_DBG /* debug, do not translate */
313 TgAssert(pxtii->found_transparent_pixel == FALSE ||
314 pxtii->transparent_pixel_index == i,
315 "more than one transparent pixel in BuildXPmBuckets()",
316 NULL);
317 #endif /* _TGIF_DBG */
318 pxtii->found_transparent_pixel = TRUE;
319 pxtii->transparent_pixel_index = i;
320 if (pxtii->dump_index_to_color_index != NULL) {
321 pxtii->dump_index_to_color_index[i] = INVALID;
322 }
323 } else if (pxtii->dump_index_to_color_index != NULL) {
324 int pixel=pixels[i], found_index=INVALID;
325
326 if (HashLookUpInt(&gColorsHashForPrinting,
327 (char*)(&pixel), sizeof(int), &found_index)) {
328 pxtii->dump_index_to_color_index[i] = found_index;
329 } else {
330 pxtii->dump_index_to_color_index[i] = INVALID;
331 #ifdef _TGIF_DBG /* debug, do not translate */
332 TgAssert(FALSE,
333 "invalid found_index in BuildXPmBuckets()", NULL);
334 #endif /* _TGIF_DBG */
335 }
336 }
337 }
338 bucket = xpmpixelhash(pixels[i]);
339 if (xpmBucketSize[bucket] == xpmBucketMaxSize[bucket]) {
340 xpmBucket[bucket] = (struct BucketRec *)realloc(xpmBucket[bucket],
341 (xpmBucketMaxSize[bucket]+XPM_BUCKET_INC) *
342 sizeof(struct BucketRec));
343 xpmBucketMaxSize[bucket] += XPM_BUCKET_INC;
344 }
345 xpmBucket[bucket][xpmBucketSize[bucket]].index = i;
346 xpmBucket[bucket][xpmBucketSize[bucket]].pixel = pixels[i];
347 if (dump_index_to_color_index == NULL) {
348 xpmBucket[bucket][xpmBucketSize[bucket]].color_index = BAD;
349 } else {
350 xpmBucket[bucket][xpmBucketSize[bucket]].color_index =
351 dump_index_to_color_index[i];
352 }
353 (xpmBucketSize[bucket])++;
354 }
355 } else {
356 /* build the hash table according to the color_char */
357 if (chars_per_pixel >= 9) {
358 sprintf(gszMsgBox, TgLoadString(STID_INVALID_CH_PER_PIX_IN_FUNC),
359 chars_per_pixel, "BuildXPmBuckets()");
360 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
361 return FALSE;
362 }
363 for (i=0; i < ncolors; i++) {
364 bucket = xpmcharhash(chars_per_pixel, &color_char[i*chars_per_pixel]);
365 if (xpmBucketSize[bucket] == xpmBucketMaxSize[bucket]) {
366 xpmBucket[bucket] = (struct BucketRec *)realloc(xpmBucket[bucket],
367 (xpmBucketMaxSize[bucket]+XPM_BUCKET_INC) *
368 sizeof(struct BucketRec));
369 xpmBucketMaxSize[bucket] += XPM_BUCKET_INC;
370 }
371 xpmBucket[bucket][xpmBucketSize[bucket]].index = i;
372 strncpy(xpmBucket[bucket][xpmBucketSize[bucket]].s,
373 &color_char[i*chars_per_pixel], chars_per_pixel);
374 (xpmBucketSize[bucket])++;
375 }
376 }
377 return TRUE;
378 }
379
XPmLookUp(pixel,chars_per_pixel,color_char,pn_color_index_return)380 int XPmLookUp(pixel, chars_per_pixel, color_char, pn_color_index_return)
381 int pixel, chars_per_pixel, *pn_color_index_return;
382 char *color_char;
383 {
384 register int i;
385 register struct BucketRec *ptr;
386 int size, bucket;
387
388 if (chars_per_pixel == INVALID) {
389 /* hash according to the pixels */
390 bucket = xpmpixelhash(pixel);
391 size = xpmBucketSize[bucket];
392 for (i = 0, ptr = xpmBucket[bucket]; i < size; i++, ptr++) {
393 if (ptr->pixel == pixel) {
394 if (pn_color_index_return != NULL) {
395 *pn_color_index_return = ptr->color_index;
396 }
397 return (ptr->index);
398 }
399 }
400 } else {
401 /* hash according to the color_char */
402 bucket = xpmcharhash(chars_per_pixel, color_char);
403
404 size = xpmBucketSize[bucket];
405 for (i=0, ptr=xpmBucket[bucket]; i < size; i++, ptr++) {
406 if (strncmp(color_char, ptr->s, chars_per_pixel) == 0) {
407 if (pn_color_index_return != NULL) {
408 *pn_color_index_return = ptr->color_index;
409 }
410 return (ptr->index);
411 }
412 }
413 }
414 return INVALID;
415 }
416
MakeCachedPixmap(ObjPtr)417 void MakeCachedPixmap(ObjPtr)
418 struct ObjRec *ObjPtr;
419 {
420 register int c, r;
421 int w, h, flip, target_percent;
422 int num_cols, num_rows, image_w, image_h, watch_cursor;
423 int start_col, start_row, do_msg;
424 struct XPmRec *xpm_ptr=ObjPtr->detail.xpm;
425 struct MtrxRec mtrx;
426 Pixmap dest_pixmap=None, dest_bitmap=None;
427 XImage *src_image=NULL, *src_bitmap_image=NULL;
428 XImage *dest_image=NULL, *dest_bitmap_image=NULL;
429
430 w = ObjPtr->obbox.rbx - ObjPtr->obbox.ltx;
431 h = ObjPtr->obbox.rby - ObjPtr->obbox.lty;
432 num_cols = (zoomedIn) ? (w<<zoomScale) : (w>>zoomScale);
433 num_rows = (zoomedIn) ? (h<<zoomScale) : (h>>zoomScale);
434
435 if (ObjPtr->ctm==NULL && xpm_ptr->cached_pixmap!=None &&
436 xpm_ptr->cached_color!=(-1) && xpm_ptr->cached_color==ObjPtr->color &&
437 xpm_ptr->cached_zoomed==zoomedIn && xpm_ptr->cached_zoom==zoomScale &&
438 xpm_ptr->cached_w==num_cols && xpm_ptr->cached_h==num_rows &&
439 xpm_ptr->cached_flip==xpm_ptr->flip)
440 return;
441
442 if ((w>>zoomScale)==0 || (h>>zoomScale)==0) {
443 if (xpm_ptr->cached_pixmap != None) {
444 XFreePixmap(mainDisplay, xpm_ptr->cached_pixmap);
445 }
446 if (xpm_ptr->cached_bitmap != None) {
447 XFreePixmap(mainDisplay, xpm_ptr->cached_bitmap);
448 }
449 xpm_ptr->cached_pixmap = None;
450 xpm_ptr->cached_bitmap = None;
451 xpm_ptr->cached_color = (-1);
452 return;
453 }
454 watch_cursor = watchCursorOnMainWindow;
455 if (!watch_cursor && !RedrawDuringScrolling()) {
456 SetWatchCursor(drawWindow);
457 SetWatchCursor(mainWindow);
458 } else {
459 CheckInterrupt(TRUE);
460 }
461 src_image = xpm_ptr->image;
462 src_bitmap_image = xpm_ptr->bitmap_image;
463 flip = xpm_ptr->flip;
464 image_w = xpm_ptr->image_w;
465 image_h = xpm_ptr->image_h;
466 if (xpm_ptr->cached_pixmap != None) {
467 XFreePixmap(mainDisplay, xpm_ptr->cached_pixmap);
468 }
469 xpm_ptr->cached_pixmap = None;
470 if (xpm_ptr->cached_bitmap != None) {
471 XFreePixmap(mainDisplay, xpm_ptr->cached_bitmap);
472 }
473 xpm_ptr->cached_bitmap = None;
474 xpm_ptr->cached_color = (-1);
475 if (xpm_ptr->clip_mask != None) {
476 XFreePixmap(mainDisplay, xpm_ptr->clip_mask);
477 }
478 xpm_ptr->clip_mask = None;
479
480 if (src_image == NULL) {
481 src_image = xpm_ptr->image = XGetImage(mainDisplay, xpm_ptr->pixmap,
482 0, 0, image_w, image_h, AllPlanes, ZPixmap);
483 }
484 if (src_bitmap_image == NULL) {
485 src_bitmap_image = xpm_ptr->bitmap_image = XGetImage(mainDisplay,
486 xpm_ptr->bitmap, 0, 0, image_w, image_h, 1, ZPixmap);
487 }
488 do_msg = (((num_rows*num_cols)>=0x4000) && !RedrawDuringScrolling());
489 if (do_msg) {
490 SaveStatusStrings();
491 SetStringStatus(TgLoadCachedString(CSTID_CACHING_PIXMAP));
492 XSync(mainDisplay, False);
493 }
494 dest_pixmap = XCreatePixmap(mainDisplay, dummyPixmap, num_cols, num_rows,
495 mainDepth);
496 dest_bitmap = XCreatePixmap(mainDisplay, dummyBitmap, num_cols, num_rows,
497 1);
498 XFillRectangle(mainDisplay,dest_pixmap,xpmGC,0,0,num_cols,num_rows);
499 XSetForeground(mainDisplay,xbmGC,1);
500 XFillRectangle(mainDisplay,dest_bitmap,xbmGC,0,0,num_cols,num_rows);
501 XSetForeground(mainDisplay,xbmGC,0);
502 dest_image = XGetImage(mainDisplay, dest_pixmap, 0, 0, num_cols, num_rows,
503 AllPlanes, ZPixmap);
504 dest_bitmap_image = XGetImage(mainDisplay, dest_bitmap, 0, 0,
505 num_cols, num_rows, 1, ZPixmap);
506
507 if (ObjPtr->ctm == NULL) {
508 mtrx.image_w = (float)image_w; mtrx.image_h = (float)image_h;
509 mtrx.w = (float)num_cols; mtrx.h = (float)num_rows;
510 mtrx.rotate = ROTATE0; mtrx.flip = flip;
511
512 CalcTransform(&mtrx);
513
514 start_col = (mtrx.transformed_w >= 0.0) ? 0 : (-num_cols)+1;
515 start_row = (mtrx.transformed_h >= 0.0) ? 0 : (-num_rows)+1;
516
517 target_percent = 5;
518 for (r=0; r < num_rows; r++) {
519 double part_x, part_y;
520
521 if (do_msg && ((r & 0xf) == 0)) {
522 int percent=(r*10000/num_rows)/100;
523
524 if (percent >= target_percent) {
525 sprintf(gszMsgBox, TgLoadCachedString(CSTID_PROGRESS_PERCENT),
526 percent);
527 SetStringStatus(gszMsgBox);
528 XSync(mainDisplay, False);
529 while (target_percent <= percent) target_percent += 5;
530 }
531 }
532 part_x = ((double)(r+start_row)+0.5)*(mtrx.rev_m[1][0]);
533 part_y = ((double)(r+start_row)+0.5)*(mtrx.rev_m[1][1]);
534 for (c=0; c < num_cols; c++) {
535 double x, y;
536
537 x = part_x+((double)(c+start_col)+0.5)*(mtrx.rev_m[0][0]);
538 y = part_y+((double)(c+start_col)+0.5)*(mtrx.rev_m[0][1]);
539 if (x >= ((double)0) && x < ((double)image_w) &&
540 y >= ((double)0) && y < ((double)image_h)) {
541 int new_x=(int)x, new_y=(int)y;
542
543 if (XGetPixel(src_bitmap_image,new_x,new_y) != 0) {
544 XPutPixel(dest_image, c, r, XGetPixel(src_image,new_x,new_y));
545 } else {
546 XPutPixel(dest_bitmap_image, c, r, 0);
547 XPutPixel(dest_image, c, r, colorPixels[ObjPtr->color]);
548 }
549 }
550 }
551 }
552 } else {
553 Pixmap clip_mask;
554 XImage *clip_mask_image;
555 int bg_pixel=GetDrawingBgPixel(INVALID, INVALID);
556 int abs_offset_x=ObjPtr->obbox.ltx-ObjPtr->x;
557 int abs_offset_y=ObjPtr->obbox.lty-ObjPtr->y;
558
559 clip_mask = XCreatePixmap(mainDisplay,dummyBitmap,num_cols,num_rows,1);
560 XSetForeground(mainDisplay, xbmGC, 1);
561 XFillRectangle(mainDisplay, clip_mask, xbmGC, 0, 0, num_cols, num_rows);
562 XSetForeground(mainDisplay, xbmGC, 0);
563 clip_mask_image = XGetImage(mainDisplay, clip_mask, 0, 0,
564 num_cols, num_rows, 1, ZPixmap);
565
566 target_percent = 5;
567 for (r=0; r < num_rows; r++) {
568 int y=abs_offset_y+ABS_SIZE(r);
569 double dy=((double)y)+0.5;
570
571 if (do_msg && ((r & 0xf) == 0)) {
572 int percent=(r*10000/num_rows)/100;
573
574 if (percent >= target_percent) {
575 sprintf(gszMsgBox, TgLoadCachedString(CSTID_PROGRESS_PERCENT),
576 percent);
577 SetStringStatus(gszMsgBox);
578 XSync(mainDisplay, False);
579 while (target_percent <= percent) target_percent += 5;
580 }
581 }
582 for (c=0; c < num_cols; c++) {
583 int x=abs_offset_x+ABS_SIZE(c);
584 double dx=((double)x)+0.5;
585 double new_dx=(double)0, new_dy=(double)0;
586
587 ReverseTransformDoublePointThroughCTM(dx, dy, ObjPtr->ctm,
588 &new_dx, &new_dy);
589 new_dx += (double)(ObjPtr->x-ObjPtr->orig_obbox.ltx);
590 new_dy += (double)(ObjPtr->y-ObjPtr->orig_obbox.lty);
591 if (new_dx >= ((double)0) && new_dx < ((double)image_w) &&
592 new_dy >= ((double)0) && new_dy < ((double)image_h)) {
593 int new_x=(int)new_dx, new_y=(int)new_dy;
594
595 if (new_x < 0) new_x = 0;
596 if (new_x >= image_w) new_x = image_w-1;
597 if (new_y < 0) new_y = 0;
598 if (new_y >= image_h) new_y = image_h-1;
599 if (XGetPixel(src_bitmap_image,new_x,new_y) != 0) {
600 XPutPixel(dest_image, c, r, XGetPixel(src_image,new_x,new_y));
601 } else {
602 XPutPixel(clip_mask_image, c, r, 0);
603 XPutPixel(dest_image, c, r, bg_pixel);
604 }
605 } else {
606 XPutPixel(clip_mask_image, c, r, 0);
607 }
608 }
609 }
610 XPutImage(mainDisplay, clip_mask, xbmGC, clip_mask_image, 0, 0, 0, 0,
611 num_cols, num_rows);
612 xpm_ptr->clip_mask = clip_mask;
613 XDestroyImage(clip_mask_image);
614 memcpy(&xpm_ptr->cached_ctm, ObjPtr->ctm, sizeof(struct XfrmMtrxRec));
615 }
616 if (do_msg) {
617 SetStringStatus(TgLoadCachedString(CSTID_FINISHED_CACHEING_PIXMAP));
618 XSync(mainDisplay, False);
619 }
620 XPutImage(mainDisplay, dest_pixmap, xpmGC, dest_image, 0, 0, 0, 0,
621 num_cols, num_rows);
622 XPutImage(mainDisplay, dest_bitmap, xbmGC, dest_bitmap_image, 0, 0, 0, 0,
623 num_cols, num_rows);
624 if (do_msg) RestoreStatusStrings();
625
626 xpm_ptr->cached_pixmap = dest_pixmap;
627 xpm_ptr->cached_bitmap = dest_bitmap;
628 xpm_ptr->cached_zoomed = zoomedIn;
629 xpm_ptr->cached_zoom = zoomScale;
630 xpm_ptr->cached_flip = xpm_ptr->flip;
631 xpm_ptr->cached_w = num_cols;
632 xpm_ptr->cached_h = num_rows;
633 xpm_ptr->cached_color = ObjPtr->color;
634
635 if (dest_image != NULL) XDestroyImage(dest_image);
636 if (dest_bitmap_image != NULL) XDestroyImage(dest_bitmap_image);
637
638 if (!watch_cursor && !RedrawDuringScrolling()) {
639 SetDefaultCursor(mainWindow);
640 ShowCursor();
641 } else {
642 CheckInterrupt(TRUE);
643 }
644 }
645
ExtractPixmap(orig_pixmap,orig_image,orig_bitmap,orig_bitmap_image,x,y,w,h,pixmap,image,bitmap,bitmap_image)646 int ExtractPixmap(orig_pixmap, orig_image, orig_bitmap, orig_bitmap_image,
647 x, y, w, h, pixmap, image, bitmap, bitmap_image)
648 Pixmap orig_pixmap, orig_bitmap, *pixmap, *bitmap;
649 XImage *orig_image, *orig_bitmap_image, **image, **bitmap_image;
650 int x, y, w, h;
651 {
652 register int j, i;
653 XImage *src_image=NULL, *src_bitmap_image=NULL;
654
655 SetWatchCursor(drawWindow);
656 SetWatchCursor(mainWindow);
657
658 *pixmap = XCreatePixmap(mainDisplay, dummyPixmap, w, h, mainDepth);
659 *bitmap = XCreatePixmap(mainDisplay, dummyBitmap, w, h, 1);
660 *image = (*pixmap==None ? NULL : XGetImage(mainDisplay, *pixmap, 0, 0, w, h,
661 AllPlanes, ZPixmap));
662 *bitmap_image = (*bitmap==None ? NULL : XGetImage(mainDisplay, *bitmap, 0, 0,
663 w, h, 1, ZPixmap));
664 if (orig_image != NULL && x == 0 && y == 0) {
665 src_image = orig_image;
666 } else {
667 src_image = XGetImage(mainDisplay, orig_pixmap, x, y, w, h, AllPlanes,
668 ZPixmap);
669 }
670 if (orig_bitmap_image != NULL && x == 0 && y == 0) {
671 src_bitmap_image = orig_bitmap_image;
672 } else {
673 src_bitmap_image = XGetImage(mainDisplay, orig_bitmap, x, y, w, h, 1,
674 ZPixmap);
675 }
676 if (*pixmap == None || *bitmap == None || *image==NULL ||
677 *bitmap_image==NULL || src_image==NULL || src_bitmap_image==NULL) {
678 if (*pixmap == None) {
679 FailAllocPixmapMessage(w, h);
680 } else if (*bitmap == None) {
681 FailAllocBitmapMessage(w, h);
682 } else {
683 MsgBox(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM), TOOL_NAME,
684 INFO_MB);
685 }
686 if (*pixmap != None) XFreePixmap(mainDisplay, *pixmap);
687 if (*bitmap != None) XFreePixmap(mainDisplay, *bitmap);
688 if (*image != NULL) XDestroyImage(*image);
689 if (*bitmap_image != NULL) XDestroyImage(*bitmap_image);
690 if (orig_image != NULL) XDestroyImage(src_image);
691 if (orig_bitmap_image != NULL) XDestroyImage(src_bitmap_image);
692 if (!(orig_image != NULL && x==0 && y==0) && src_image != NULL) {
693 XDestroyImage(src_image);
694 }
695 if (!(orig_bitmap_image != NULL && x==0 && y==0) &&
696 src_bitmap_image != NULL) {
697 XDestroyImage(src_bitmap_image);
698 }
699 *pixmap = *bitmap = None;
700 *image = *bitmap_image = NULL;
701 SetDefaultCursor(mainWindow);
702 SetDefaultCursor(drawWindow);
703 return FALSE;
704 }
705 for (i = 0; i < h; i++) {
706 for (j = 0; j < w; j++) {
707 XPutPixel(*image, j, i, XGetPixel(src_image, j, i));
708 XPutPixel(*bitmap_image, j, i, XGetPixel(src_bitmap_image, j, i));
709 }
710 }
711 XPutImage(mainDisplay, *pixmap, xpmGC, *image, 0, 0, 0, 0, w, h);
712 XPutImage(mainDisplay, *bitmap, xbmGC, *bitmap_image, 0, 0, 0, 0, w, h);
713 SetDefaultCursor(mainWindow);
714 SetDefaultCursor(drawWindow);
715
716 if (!(orig_image != NULL && x == 0 && y == 0)) XDestroyImage(src_image);
717 if (!(orig_bitmap_image != NULL && x == 0 && y == 0)) {
718 XDestroyImage(src_bitmap_image);
719 }
720 return TRUE;
721 }
722
CutXPixmap(ObjPtrToCut,pAbsX,pAbsY,pAbsW,pAbsH)723 struct ObjRec *CutXPixmap(ObjPtrToCut, pAbsX, pAbsY, pAbsW, pAbsH)
724 struct ObjRec *ObjPtrToCut; /* if NULL, use topSel->obj */
725 int *pAbsX, *pAbsY, *pAbsW, *pAbsH;
726 /*
727 * if (ObjPtrToCut != NULL) {
728 * return new_obj_ptr if cut was done successfully
729 * return ObjPtrToCut if there is no need to cut anything
730 * return NULL if something is wrong and object needs to be deleted
731 * }
732 * Note: if ObjPtrToCut is not NULL, then ObjPtrToCut is topSel->obj and
733 * it's called from CropImage() with topSel->obj->ctm != NULL
734 * with fullTrueColorMode == TRUE && HasZlibSupport() == TRUE
735 */
736 {
737 register int j, i;
738 int w, h, chars_per_pixel, ncolors=0, *pixels=NULL, len;
739 int ltx, lty, rbx, rby, new_w, new_h;
740 int src_x=0, src_y=0, src_w=0, src_h=0, image_w=0, image_h=0;
741 char *color_char, **color_str;
742 float h_scale=1.0, v_scale=1.0, mag=1.0;
743 Pixmap dest_pixmap=None, dest_bitmap=None;
744 XImage *dest_image=NULL, *dest_bitmap_image=NULL;
745 struct ObjRec *obj_ptr=topSel->obj, *new_obj_ptr=NULL;
746 struct XPmRec *xpm_ptr=obj_ptr->detail.xpm, *new_xpm_ptr=NULL;
747
748 src_x = 0;
749 src_y = 0;
750 if (ObjPtrToCut != NULL && pAbsX != NULL && pAbsY != NULL && pAbsW != NULL &&
751 pAbsH != NULL) {
752 obj_ptr = ObjPtrToCut;
753 xpm_ptr = obj_ptr->detail.xpm;
754 image_w = xpm_ptr->image_w;
755 image_h = xpm_ptr->image_h;
756 src_x = *pAbsX;
757 src_y = *pAbsY;
758 src_w = *pAbsW;
759 src_h = *pAbsH;
760 if (src_x==0 && src_y==0 && src_w==image_w && src_h==image_h &&
761 mag==1.0) {
762 return obj_ptr;
763 }
764 if (src_w==0 || src_h==0) {
765 MsgBox(TgLoadString(STID_XPM_CANT_HAVE_0_W_OR_H), TOOL_NAME, INFO_MB);
766 return NULL;
767 }
768 } else {
769 src_w = image_w = xpm_ptr->image_w;
770 src_h = image_h = xpm_ptr->image_h;
771 mag = 1.0;
772
773 h_scale = ((float)((float)(obj_ptr->obbox.rbx-obj_ptr->obbox.ltx)) /
774 ((float)image_w));
775 v_scale = ((float)((float)(obj_ptr->obbox.rby-obj_ptr->obbox.lty)) /
776 ((float)image_h));
777
778 if (pAbsX == NULL && pAbsY == NULL && pAbsW == NULL && pAbsH == NULL) {
779 char mag_spec[MAXSTRING];
780
781 sprintf(gszMsgBox, TgLoadString(STID_ENTER_GEOM_SPEC_ORIG_SIZE),
782 image_w, image_h);
783 *mag_spec = '\0';
784 Dialog(gszMsgBox, TgLoadCachedString(CSTID_DLG_ACCEPT_CANCEL),
785 mag_spec);
786 UtilTrimBlanks(mag_spec);
787 if (*mag_spec == '\0') return obj_ptr;
788
789 ParseCutSpec(mag_spec, image_w, image_h, &mag, &src_x, &src_y, &src_w,
790 &src_h);
791 } else {
792 src_x = *pAbsX;
793 src_y = *pAbsY;
794 src_w = *pAbsW;
795 src_h = *pAbsH;
796 }
797 if (src_x==0 && src_y==0 && src_w==image_w && src_h==image_h &&
798 mag==1.0) {
799 return obj_ptr;
800 }
801 if (src_w==0 || src_h==0) {
802 MsgBox(TgLoadString(STID_XPM_CANT_HAVE_0_W_OR_H), TOOL_NAME, INFO_MB);
803 return NULL;
804 }
805 PrepareToRecord(CMD_REPLACE, topSel, botSel, numObjSelected);
806 }
807 if (!ExtractPixmap(xpm_ptr->pixmap, xpm_ptr->image, xpm_ptr->bitmap,
808 xpm_ptr->bitmap_image, src_x, src_y, src_w, src_h,
809 &dest_pixmap, &dest_image, &dest_bitmap, &dest_bitmap_image)) {
810 if (ObjPtrToCut == NULL || pAbsX == NULL || pAbsY == NULL ||
811 pAbsW == NULL || pAbsH == NULL) {
812 AbortPrepareCmd(CMD_REPLACE);
813 }
814 return NULL;
815 }
816 if ((xpm_ptr->real_type == XPM_JPEG || xpm_ptr->real_type == PPM_TRUE) &&
817 fullTrueColorMode && HasZlibSupport()) {
818 char tmp_fname[MAXPATHLENGTH];
819
820 if (MkTempFile(tmp_fname, sizeof(tmp_fname), tmpDir, TOOL_NAME) == NULL) {
821 if (ObjPtrToCut == NULL || pAbsX == NULL || pAbsY == NULL ||
822 pAbsW == NULL || pAbsH == NULL) {
823 AbortPrepareCmd(CMD_REPLACE);
824 }
825 return NULL;
826 }
827 if (DumpXImageToPpmFile(dest_image, src_w, src_h, tmp_fname, TRUE)) {
828 char deflated_fname[MAXPATHLENGTH];
829 unsigned int data_size=0;
830 char *ppm_data=NULL;
831
832 snprintf(deflated_fname, sizeof(deflated_fname), "%s.ppm.z",
833 tmp_fname);
834 ppm_data = ReadFileIntoBuf(deflated_fname, &data_size);
835 unlink(deflated_fname);
836 unlink(tmp_fname);
837 if (ppm_data) {
838 new_obj_ptr = CreatePpmTrueObjFromImage(dest_image, src_w, src_h,
839 ppm_data, data_size);
840 }
841 }
842 XFreePixmap(mainDisplay, dest_pixmap);
843 XFreePixmap(mainDisplay, dest_bitmap);
844 XDestroyImage(dest_image);
845 XDestroyImage(dest_bitmap_image);
846 dest_pixmap = dest_bitmap = None;
847 dest_image = dest_bitmap_image = NULL;
848
849 if (new_obj_ptr == NULL) {
850 if (ObjPtrToCut == NULL || pAbsX == NULL || pAbsY == NULL ||
851 pAbsW == NULL || pAbsH == NULL) {
852 AbortPrepareCmd(CMD_REPLACE);
853 }
854 return NULL;
855 }
856 MoveObj(new_obj_ptr, obj_ptr->x, obj_ptr->y);
857 }
858 sprintf(gszMsgBox, TgLoadCachedString(CSTID_NEW_XPM_SIZE_IS_W_X_H),
859 src_w, src_h);
860 Msg(gszMsgBox);
861 if (ObjPtrToCut != NULL && pAbsX != NULL && pAbsY != NULL && pAbsW != NULL &&
862 pAbsH != NULL) {
863 return new_obj_ptr;
864 } else {
865 UnlinkObj(obj_ptr);
866
867 ltx = selLtX; lty = selLtY; rbx = selRbX; rby = selRbY;
868 HighLightReverse();
869
870 w = new_w = (int)(((float)src_w) * mag);
871 h = new_h = (int)(((float)src_h) * mag);
872 }
873 if (new_obj_ptr == NULL) {
874 new_obj_ptr = (struct ObjRec *)malloc(sizeof(struct ObjRec));
875 if (new_obj_ptr == NULL) FailAllocMessage();
876 memset(new_obj_ptr, 0, sizeof(struct ObjRec));
877 DupObjBasics(obj_ptr, new_obj_ptr);
878
879 new_xpm_ptr = (struct XPmRec *)malloc(sizeof(struct XPmRec));
880 if (new_xpm_ptr == NULL) FailAllocMessage();
881 memset(new_xpm_ptr, 0, sizeof(struct XPmRec));
882 new_obj_ptr->detail.xpm = new_xpm_ptr;
883
884 new_xpm_ptr->image_w = src_w;
885 new_xpm_ptr->image_h = src_h;
886 new_xpm_ptr->pixmap = dest_pixmap;
887 new_xpm_ptr->image = dest_image;
888 new_xpm_ptr->bitmap = dest_bitmap;
889 new_xpm_ptr->bitmap_image = dest_bitmap_image;
890 new_xpm_ptr->data = NULL;
891 new_xpm_ptr->fill = xpm_ptr->fill;
892 new_xpm_ptr->flip = xpm_ptr->flip;
893 new_xpm_ptr->cached_zoom = 0;
894 new_xpm_ptr->cached_pixmap = None;
895 new_xpm_ptr->cached_bitmap = None;
896 new_xpm_ptr->cached_flip = 0;
897 new_xpm_ptr->cached_w = 0;
898 new_xpm_ptr->cached_h = 0;
899 new_xpm_ptr->cached_color = (-1);
900
901 chars_per_pixel = new_xpm_ptr->chars_per_pixel = xpm_ptr->chars_per_pixel;
902 new_xpm_ptr->first_pixel_is_bg = xpm_ptr->first_pixel_is_bg;
903
904 ncolors = new_xpm_ptr->ncolors = xpm_ptr->ncolors;
905 color_char = new_xpm_ptr->color_char =
906 (char*)malloc((ncolors*chars_per_pixel)*sizeof(char));
907 if (color_char == NULL) FailAllocMessage();
908 color_str = new_xpm_ptr->color_str =
909 (char**)malloc(ncolors*sizeof(char*));
910 if (color_str == NULL) FailAllocMessage();
911 pixels = new_xpm_ptr->pixels = (int*)malloc(ncolors*sizeof(int));
912 if (pixels == NULL) FailAllocMessage();
913 for (i = 0; i < ncolors; i++) {
914 pixels[i] = xpm_ptr->pixels[i];
915
916 for (j = 0; j < chars_per_pixel; j++) {
917 color_char[i*chars_per_pixel+j] =
918 xpm_ptr->color_char[i*chars_per_pixel+j];
919 }
920 len = strlen(xpm_ptr->color_str[i]);
921 color_str[i] = (char*)malloc((len+1)*sizeof(char));
922 if (color_str[i] == NULL) FailAllocMessage();
923 strcpy(color_str[i], xpm_ptr->color_str[i]);
924 }
925 new_w = round(h_scale * ((float)w));
926 new_h = round(v_scale * ((float)h));
927
928 new_obj_ptr->obbox.ltx = obj_ptr->obbox.ltx;
929 new_obj_ptr->obbox.lty = obj_ptr->obbox.lty;
930 new_obj_ptr->obbox.rbx = new_obj_ptr->bbox.rbx = obj_ptr->obbox.ltx+new_w;
931 new_obj_ptr->obbox.rby = new_obj_ptr->bbox.rby = obj_ptr->obbox.lty+new_h;
932
933 AdjObjBBox(new_obj_ptr);
934 }
935 topSel->obj = botSel->obj = new_obj_ptr;
936 AddObj(NULL, topObj, new_obj_ptr);
937 if (pAbsX != NULL && pAbsY != NULL) {
938 MoveObj(new_obj_ptr, *pAbsX, *pAbsY);
939 }
940 RecordCmd(CMD_REPLACE, NULL, topSel, botSel, numObjSelected);
941 FreeObj(obj_ptr);
942
943 UpdSelBBox();
944 RedrawAreas(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
945 rbx+GRID_ABS_SIZE(1), rby+GRID_ABS_SIZE(1),
946 selLtX-GRID_ABS_SIZE(1), selLtY-GRID_ABS_SIZE(1),
947 selRbX+GRID_ABS_SIZE(1), selRbY+GRID_ABS_SIZE(1));
948 HighLightForward();
949 SetFileModified(TRUE);
950 justDupped = FALSE;
951
952 return new_obj_ptr;
953 }
954
955 static
SaveXPmColors(FP,def_color_index,xpm_ptr,ncolors,chars_per_pixel,color_char,color_str,pixels)956 void SaveXPmColors(FP, def_color_index, xpm_ptr, ncolors, chars_per_pixel,
957 color_char, color_str, pixels)
958 FILE *FP;
959 int def_color_index, ncolors, chars_per_pixel, *pixels;
960 struct XPmRec *xpm_ptr;
961 char *color_char, **color_str;
962 {
963 register int i, j;
964 int cur_pixel, found_index;
965
966 if (!colorDisplay && xpm_ptr->red != NULL) {
967 for (i=0; i < ncolors; i++) {
968 if (fprintf(FP, " \"") == EOF) writeFileFailed = TRUE;
969 for (j=0; j < chars_per_pixel; j++) {
970 if (fprintf(FP, "%c", color_char[i*chars_per_pixel+j]) == EOF) {
971 writeFileFailed = TRUE;
972 }
973 }
974 if (i == ncolors-1) {
975 if (fprintf(FP, "\", \"%s\", %1d, %1d, %1d],[\n", color_str[i],
976 (int)(xpm_ptr->red[i]), (int)(xpm_ptr->green[i]),
977 (int)(xpm_ptr->blue[i])) == EOF) {
978 writeFileFailed = TRUE;
979 }
980 } else {
981 if (fprintf(FP, "\", \"%s\", %1d, %1d, %1d,\n", color_str[i],
982 (int)(xpm_ptr->red[i]), (int)(xpm_ptr->green[i]),
983 (int)(xpm_ptr->blue[i])) == EOF) {
984 writeFileFailed = TRUE;
985 }
986 }
987 }
988 } else {
989 for (i=0; i < ncolors; i++) {
990 found_index = def_color_index;
991 cur_pixel = pixels[i];
992 if (cur_pixel != (-1)) {
993 for (j=0; j < maxColors; j++) {
994 if (colorPixels[j] == cur_pixel) {
995 found_index = j;
996 break;
997 }
998 }
999 }
1000 if (fprintf(FP, " \"") == EOF) writeFileFailed = TRUE;
1001 for (j = 0; j < chars_per_pixel; j++) {
1002 if (fprintf(FP, "%c", color_char[i*chars_per_pixel+j]) == EOF) {
1003 writeFileFailed = TRUE;
1004 }
1005 }
1006 if (i == ncolors-1) {
1007 if (fprintf(FP, "\", \"%s\", %1d, %1d, %1d],[\n", color_str[i],
1008 (int)(10000*((int)tgifColors[found_index].red)/maxRGB),
1009 (int)(10000*((int)tgifColors[found_index].green)/maxRGB),
1010 (int)(10000*((int)tgifColors[found_index].blue)/maxRGB)) ==
1011 EOF) {
1012 writeFileFailed = TRUE;
1013 }
1014 } else {
1015 if (fprintf(FP, "\", \"%s\", %1d, %1d, %1d,\n", color_str[i],
1016 (int)(10000*((int)tgifColors[found_index].red)/maxRGB),
1017 (int)(10000*((int)tgifColors[found_index].green)/maxRGB),
1018 (int)(10000*((int)tgifColors[found_index].blue)/maxRGB)) ==
1019 EOF) {
1020 writeFileFailed = TRUE;
1021 }
1022 }
1023 }
1024 }
1025 }
1026
1027 static
PrTgifDumpOldXPmObj(FP,ObjPtr,pmtrx)1028 void PrTgifDumpOldXPmObj(FP, ObjPtr, pmtrx)
1029 FILE *FP;
1030 struct ObjRec *ObjPtr;
1031 struct MtrxRec *pmtrx;
1032 {
1033 int row=0, i=0, index=0, col=0, j=0, num_nibbles=0, nibble_count=0;
1034 int ltx=0, lty=0, rbx=0, rby=0, w=0, h=0, image_w=0, image_h=0;
1035 int ncolors=0, *pixels=NULL, flip=0, orig_x=0, orig_y=0;
1036 int chars_per_pixel=0, x=0, y=0;
1037 int h_blocks=0, v_blocks=0, block_w=0, block_h=0, bit_count=0, data=0;
1038 char *xpm_data=NULL, bg_char[2];
1039 Pixmap pixmap, bitmap=(Pixmap)0;
1040 struct XPmRec *xpm_ptr=NULL;
1041
1042 bg_char[0] = bg_char[1] = '\0';
1043
1044 ltx = ObjPtr->obbox.ltx;
1045 lty = ObjPtr->obbox.lty;
1046 rbx = ObjPtr->obbox.rbx;
1047 rby = ObjPtr->obbox.rby;
1048
1049 xpm_ptr = ObjPtr->detail.xpm;
1050
1051 pixmap = xpm_ptr->pixmap;
1052 bitmap = xpm_ptr->bitmap;
1053 pixels = xpm_ptr->pixels;
1054 ncolors = xpm_ptr->ncolors;
1055 flip = xpm_ptr->flip;
1056 image_w = xpm_ptr->image_w;
1057 image_h = xpm_ptr->image_h;
1058
1059 w = rbx - ltx;
1060 h = rby - lty;
1061
1062 orig_x = (pmtrx->transformed_w >= 0.0) ? ltx : ltx+w;
1063 orig_y = (pmtrx->transformed_h >= 0.0) ? lty : lty+h;
1064
1065 xpm_data = xpm_ptr->data;
1066 chars_per_pixel = xpm_ptr->chars_per_pixel;
1067
1068 fprintf(stderr, "%s\n", TgLoadString(STID_WARN_XPM_ALL_NON_BG_BE_BLACK));
1069 switch (chars_per_pixel) {
1070 case 1:
1071 bg_char[0] = xpm_ptr->color_char[0];
1072 bg_char[1] = '\0';
1073 if (*bg_char != '`' && *bg_char != ' ') {
1074 bg_char[0] = bg_char[1] = '\0';
1075 }
1076 break;
1077 case 2:
1078 bg_char[0] = xpm_ptr->color_char[0];
1079 bg_char[1] = xpm_ptr->color_char[1];
1080 if (!(bg_char[0] == '`' && bg_char[1] == '`') &&
1081 !(bg_char[0] == ' ' && bg_char[1] == ' ')) {
1082 bg_char[0] = '\0';
1083 }
1084 break;
1085 }
1086
1087 h_blocks = ((image_w&0xff) == 0) ? (image_w>>8) : ((image_w>>8)+1);
1088 v_blocks = ((image_h&0xff) == 0) ? (image_h>>8) : ((image_h>>8)+1);
1089
1090 fprintf(FP, "%s\n", gPsCmd[PS_GSAVE]);
1091 fprintf(FP, " %1d %1d %s %.3f %.3f %s %1d %s\n\n",
1092 orig_x, orig_y, gPsCmd[PS_TRANSLATE],
1093 pmtrx->dump_h_scale, pmtrx->dump_v_scale, gPsCmd[PS_SCALE],
1094 pmtrx->degree, gPsCmd[PS_ROTATE]);
1095
1096 for (row=0; row < v_blocks; row++) {
1097 y = row<<8;
1098 block_h = (row == v_blocks-1) ? image_h-y : 0x100;
1099
1100 for (col=0; col < h_blocks; col++) {
1101 x = col<<8;
1102 block_w = (col == h_blocks-1) ? image_w-x : 0x100;
1103
1104 num_nibbles = ((block_w%4) == 0) ? (int)(block_w>>2) :
1105 (int)(block_w>>2)+1;
1106
1107 fprintf(FP, " %s\n", gPsCmd[PS_GSAVE]);
1108 fprintf(FP, " %1d %1d %s\n", x, y, gPsCmd[PS_TRANSLATE]);
1109 fprintf(FP, " %1d %1d true [1 0 0 1 0 0]\n {<", block_w,
1110 block_h);
1111
1112 nibble_count = 0;
1113 for (i=0; i < block_h; i++) {
1114 bit_count = 0;
1115 data = 0;
1116 for (j=0; j < block_w; j++) {
1117 switch (chars_per_pixel) {
1118 case 1:
1119 data = (xpm_data[(i+y)*image_w+j+x] != *bg_char) ?
1120 (data<<1) | 1 : (data<<1);
1121 break;
1122 case 2:
1123 index = ((i+y)*image_w+j+x)*chars_per_pixel;
1124 data = (xpm_data[index] == bg_char[0] &&
1125 xpm_data[index+1] == bg_char[1]) ?
1126 (data<<1) : (data<<1) | 1;
1127 break;
1128 }
1129 if (++bit_count == 4) {
1130 if (nibble_count++ == 64) {
1131 nibble_count = 1;
1132 fprintf(FP, "\n ");
1133 }
1134 fprintf(FP, "%c", hexValue[data]);
1135 bit_count = 0;
1136 data = 0;
1137 }
1138 }
1139 if ((block_w % 4) != 0) {
1140 data <<= (4 - (block_w % 4));
1141 if (nibble_count++ == 64) {
1142 nibble_count = 1;
1143 fprintf(FP, "\n ");
1144 }
1145 fprintf(FP, "%c", hexValue[data]);
1146 }
1147 if ((num_nibbles & 0x1) == 1) {
1148 if (nibble_count++ == 64) {
1149 nibble_count = 1;
1150 fprintf(FP, "\n ");
1151 }
1152 fprintf(FP, "0");
1153 }
1154 }
1155 fprintf(FP, ">}\n");
1156 fprintf(FP, " %s\n", gPsCmd[PS_IMAGEMASK]);
1157 fprintf(FP, " %s\n", gPsCmd[PS_GRESTORE]);
1158 if (row!=v_blocks-1 || col!=h_blocks-1) fprintf(FP, "\n");
1159 }
1160 }
1161 fprintf(FP, "%s\n", gPsCmd[PS_GRESTORE]);
1162 fprintf(FP, "\n");
1163 }
1164
1165 static
MalformedPpmMessage(tmp_fname)1166 int MalformedPpmMessage(tmp_fname)
1167 char *tmp_fname;
1168 {
1169 sprintf(gszMsgBox, TgLoadString(STID_CANT_IMPORT_GIVEN_PPM_MALFORM),
1170 tmp_fname);
1171 if (PRTGIF) {
1172 fprintf(stderr, "%s\n", gszMsgBox);
1173 } else {
1174 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1175 }
1176 return FALSE;
1177 }
1178
1179 static
ReadPpmHeaderStr(ppm_fp,tmp_fname,buf,sz_buf)1180 int ReadPpmHeaderStr(ppm_fp, tmp_fname, buf, sz_buf)
1181 FILE *ppm_fp;
1182 char *tmp_fname, *buf;
1183 int sz_buf;
1184 {
1185 int i=0, write_index=0;
1186
1187 for (i=0; i < sz_buf-1; i++) {
1188 char ch='\0';
1189
1190 if (fread(&ch, sizeof(char), 1, ppm_fp) != 1) {
1191 /* failed */
1192 break;
1193 }
1194 if (i == 0 && ch == '#') {
1195 /* skip a comment line */
1196 char *line_buf=UtilGetALine(ppm_fp);
1197
1198 if (line_buf != NULL) {
1199 UtilFree(line_buf);
1200 i = (-1);
1201 } else {
1202 break;
1203 }
1204 } else if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') {
1205 if (write_index != 0) {
1206 buf[write_index++] = '\0';
1207 return TRUE;
1208 }
1209 } else {
1210 buf[write_index++] = ch;
1211 }
1212 }
1213 return MalformedPpmMessage(tmp_fname);
1214 }
1215
1216 static
ReadPpmHeader(ppm_fp,tmp_fname,pn_format,pn_w,pn_h,pn_max_val)1217 int ReadPpmHeader(ppm_fp, tmp_fname, pn_format, pn_w, pn_h, pn_max_val)
1218 FILE *ppm_fp;
1219 char *tmp_fname;
1220 int *pn_format, *pn_w, *pn_h, *pn_max_val;
1221 {
1222 char buf[MAXSTRING];
1223
1224 if (!ReadPpmHeaderStr(ppm_fp, tmp_fname, buf, sizeof(buf))) {
1225 return FALSE;
1226 }
1227 if (strcmp(buf, "P3") == 0) {
1228 if (pn_format != NULL) *pn_format = TYPE_PPM3;
1229 } else if (strcmp(buf, "P6") == 0) {
1230 if (pn_format != NULL) *pn_format = TYPE_PPM6;
1231 } else if (strcmp(buf, "P5") == 0) {
1232 if (pn_format != NULL) *pn_format = TYPE_PPM5;
1233 } else {
1234 return MalformedPpmMessage(tmp_fname);
1235 }
1236 if (!ReadPpmHeaderStr(ppm_fp, tmp_fname, buf, sizeof(buf))) {
1237 return FALSE;
1238 }
1239 if (sscanf(buf, "%d", pn_w) != 1) {
1240 return MalformedPpmMessage(tmp_fname);
1241 }
1242 if (!ReadPpmHeaderStr(ppm_fp, tmp_fname, buf, sizeof(buf))) {
1243 return FALSE;
1244 }
1245 if (sscanf(buf, "%d", pn_h) != 1) {
1246 return MalformedPpmMessage(tmp_fname);
1247 }
1248 if (!ReadPpmHeaderStr(ppm_fp, tmp_fname, buf, sizeof(buf))) {
1249 return FALSE;
1250 }
1251 if (sscanf(buf, "%d", pn_max_val) != 1) {
1252 return MalformedPpmMessage(tmp_fname);
1253 }
1254 return TRUE;
1255 }
1256
1257 static
DumpPpm6File(FP,image_w,image_h,tmp_fname)1258 void DumpPpm6File(FP, image_w, image_h, tmp_fname)
1259 FILE *FP;
1260 int image_w, image_h;
1261 char *tmp_fname;
1262 {
1263 FILE *ppm_fp=fopen(tmp_fname, "r");
1264 int format=0, w=0, h=0, max_val=0, row=0, col=0;
1265
1266 if (ppm_fp == NULL) {
1267 FailToOpenMessage(tmp_fname, "r", NULL);
1268 return;
1269 }
1270 if (!ReadPpmHeader(ppm_fp, tmp_fname, &format, &w, &h, &max_val)) {
1271 fclose(ppm_fp);
1272 return;
1273 }
1274 if (w != image_w || h != image_h) {
1275 sprintf(gszMsgBox, TgLoadString(STID_PPM6_DIM_NOT_MATCH), w, h, tmp_fname,
1276 image_w, image_h);
1277 if (PRTGIF) {
1278 fprintf(stderr, "%s\n", gszMsgBox);
1279 } else {
1280 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1281 }
1282 fclose(ppm_fp);
1283 return;
1284 }
1285 if (max_val != 255 && max_val != 65535) {
1286 sprintf(gszMsgBox, TgLoadString(STID_UNSUP_PPM6_MAX_VAL), max_val,
1287 tmp_fname);
1288 if (PRTGIF) {
1289 fprintf(stderr, "%s\n", gszMsgBox);
1290 } else {
1291 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1292 }
1293 fclose(ppm_fp);
1294 return;
1295 }
1296 for (row=0; row < image_h; row++) {
1297 for (col=0; col < image_w; col++) {
1298 unsigned char buf[4];
1299
1300 if (format == TYPE_PPM6) {
1301 if (max_val == 65535) {
1302 unsigned char r_buf[2], g_buf[2], b_buf[2];
1303
1304 if (fread(r_buf, sizeof(char), 2, ppm_fp) != 2 ||
1305 fread(g_buf, sizeof(char), 2, ppm_fp) != 2 ||
1306 fread(b_buf, sizeof(char), 2, ppm_fp) != 2) {
1307 MalformedPpmMessage(tmp_fname);
1308 fclose(ppm_fp);
1309 return;
1310 }
1311 if (littleEndianPpm6) {
1312 buf[0] = r_buf[1];
1313 buf[1] = g_buf[1];
1314 buf[2] = b_buf[1];
1315 } else {
1316 buf[0] = r_buf[0];
1317 buf[1] = g_buf[0];
1318 buf[2] = b_buf[0];
1319 }
1320 } else {
1321 if (fread(buf, sizeof(char), 3, ppm_fp) != 3) {
1322 MalformedPpmMessage(tmp_fname);
1323 fclose(ppm_fp);
1324 return;
1325 }
1326 }
1327 } else if (format == TYPE_PPM5) {
1328 if (max_val == 65535) {
1329 unsigned char g_buf[2];
1330
1331 if (fread(g_buf, sizeof(char), 2, ppm_fp) != 2) {
1332 MalformedPpmMessage(tmp_fname);
1333 fclose(ppm_fp);
1334 return;
1335 }
1336 if (littleEndianPpm6) {
1337 buf[0] = buf[1] = buf[2] = g_buf[1];
1338 } else {
1339 buf[0] = buf[1] = buf[2] = g_buf[0];
1340 }
1341 } else {
1342 if (fread(buf, sizeof(char), 1, ppm_fp) != 1) {
1343 MalformedPpmMessage(tmp_fname);
1344 fclose(ppm_fp);
1345 return;
1346 }
1347 buf[1] = buf[2] = buf[0];
1348 }
1349 } else {
1350 int red=0, green=0, blue=0;
1351
1352 if (fscanf(FP, "%d %d %d", &red, &green, &blue) != 3) {
1353 MalformedPpmMessage(tmp_fname);
1354 fclose(ppm_fp);
1355 return;
1356 }
1357 buf[0] = (unsigned char)(red & 0x0ff);
1358 buf[1] = (unsigned char)(green & 0x0ff);
1359 buf[2] = (unsigned char)(blue & 0x0ff);
1360 }
1361 buf[3] = '\0';
1362 if (!colorDump) {
1363 double dr=(double)0, dg=(double)0, db=(double)0, dgray=(double)0;
1364 int igray=0;
1365
1366 dr = (double)(unsigned int)(buf[0]);
1367 dg = (double)(unsigned int)(buf[1]);
1368 db = (double)(unsigned int)(buf[2]);
1369 dgray = (0.299*dr)+(0.587*dg)+(0.114*db);
1370 igray = round(dgray);
1371 if (igray > 255) igray = 255;
1372 if (igray < 0) igray = 0;
1373 buf[0] = buf[1] = buf[2] = (unsigned char)(igray & 0x0ff);
1374 }
1375 fprintf(FP, "%02x%02x%02x", (unsigned int)(buf[0]),
1376 (unsigned int)(buf[1]), (unsigned int)(buf[2]));
1377 if (col%12 == 11) fprintf(FP, "\n ");
1378 }
1379 if (col%12 != 11) fprintf(FP, "\n");
1380 if (row != image_h-1) fprintf(FP, " ");
1381 }
1382 fclose(ppm_fp);
1383 }
1384
1385 static
ObjHasXpmObj(ObjPtr)1386 int ObjHasXpmObj(ObjPtr)
1387 struct ObjRec *ObjPtr;
1388 {
1389 switch (ObjPtr->type) {
1390 case OBJ_XPM:
1391 if (!colorLayers || ObjInVisibleLayer(ObjPtr)) {
1392 return TRUE;
1393 }
1394 return FALSE;
1395
1396 case OBJ_SYM:
1397 case OBJ_ICON:
1398 case OBJ_GROUP:
1399 if (!colorLayers || ObjInVisibleLayer(ObjPtr)) {
1400 struct ObjRec *obj_ptr=ObjPtr->detail.r->last;
1401
1402 for ( ; obj_ptr != NULL; obj_ptr=obj_ptr->prev) {
1403 obj_ptr->tmp_parent = ObjPtr;
1404 if (ObjHasXpmObj(obj_ptr)) return TRUE;
1405 }
1406 return TRUE;
1407 }
1408 return FALSE;
1409 case OBJ_PIN:
1410 if (!colorLayers || ObjInVisibleLayer(ObjPtr)) {
1411 struct ObjRec *obj_ptr=GetPinObj(ObjPtr);
1412
1413 for ( ; obj_ptr != NULL; obj_ptr=obj_ptr->prev) {
1414 obj_ptr->tmp_parent = ObjPtr;
1415 if (ObjHasXpmObj(obj_ptr)) return TRUE;
1416 }
1417 return TRUE;
1418 }
1419 return FALSE;
1420
1421 default: break;
1422 }
1423 return FALSE;
1424 }
1425
1426 static
PageHasXpmObj(page_ptr)1427 int PageHasXpmObj(page_ptr)
1428 struct PageRec *page_ptr;
1429 {
1430 struct ObjRec *obj_ptr=NULL;
1431
1432 for (obj_ptr=page_ptr->bot; obj_ptr != NULL; obj_ptr=obj_ptr->prev) {
1433 obj_ptr->tmp_parent = NULL;
1434 if (ObjHasXpmObj(obj_ptr)) return TRUE;
1435 }
1436 return FALSE;
1437 }
1438
1439 static
FileHasXpmObj()1440 int FileHasXpmObj()
1441 {
1442 struct PageRec *page_ptr=NULL;
1443
1444 for (page_ptr=firstPage; page_ptr != NULL; page_ptr=page_ptr->next) {
1445 if (PageHasXpmObj(page_ptr)) return TRUE;
1446 }
1447 return FALSE;
1448 }
1449
1450 static
HashAllColorPixels()1451 void HashAllColorPixels()
1452 {
1453 int i=0;
1454
1455 for (i=0; i < maxColors; i++) {
1456 int pixel=colorPixels[i];
1457
1458 HashStoreInt(&gColorsHashForPrinting, (char*)(&pixel), sizeof(int), i);
1459 }
1460 }
1461
CleanUpCachedColorsForPrinting()1462 void CleanUpCachedColorsForPrinting()
1463 {
1464 if (gnColorsHashForPrintingValid) {
1465 CleanUpHash(&gColorsHashForPrinting);
1466 gnColorsHashForPrintingValid = FALSE;
1467 }
1468 }
1469
CacheColorsForPrinting()1470 void CacheColorsForPrinting()
1471 {
1472 XColor *saved_tgif_colors=tgifColors;
1473
1474 if (PRTGIF && !cmdLineOpenDisplay) return;
1475 if (!FileHasXpmObj()) return;
1476
1477 gnColorsHashForPrintingValid = TRUE;
1478 InitHash(&gColorsHashForPrinting, TG_HASH_SIZE_LARGE);
1479
1480 if (printUsingRequestedColor) tgifColors = tgifRequestedColors;
1481
1482 HashAllColorPixels();
1483
1484 if (printUsingRequestedColor) tgifColors = saved_tgif_colors;
1485 }
1486
1487 typedef struct tagImagePixelInfo {
1488 int image_w, image_h;
1489 int **image_pixels;
1490 /*
1491 * transparent is not used for now because the only to create a pixmap
1492 * object with too many colors is to import a XPM object
1493 * we assume that people just use JPEG and GIF import
1494 */
1495 unsigned char **transparent;
1496 } ImagePixelInfo;
1497
1498 static
FreeImagePixels(pipi)1499 void FreeImagePixels(pipi)
1500 ImagePixelInfo *pipi;
1501 {
1502 int row=0, image_h=pipi->image_h;
1503 int **image_pixels=NULL;
1504 unsigned char **transparent=NULL;
1505
1506 if (pipi == NULL) return;
1507
1508 image_pixels = pipi->image_pixels;
1509 transparent = pipi->transparent;
1510
1511 if (image_pixels != NULL) {
1512 for (row=0; row < image_h; row++) {
1513 if (image_pixels[row] != NULL) free(image_pixels[row]);
1514 }
1515 free(image_pixels);
1516 }
1517 if (transparent != NULL) {
1518 for (row=0; row < image_h; row++) {
1519 if (transparent[row] != NULL) free(transparent[row]);
1520 }
1521 free(transparent);
1522 }
1523 memset(pipi, 0, sizeof(ImagePixelInfo));
1524 }
1525
1526 static
SetAColorByteInfoByXpmRGB(pcb,xpm_ptr,pixel_index)1527 void SetAColorByteInfoByXpmRGB(pcb, xpm_ptr, pixel_index)
1528 ColorBytes *pcb;
1529 struct XPmRec *xpm_ptr;
1530 int pixel_index;
1531 {
1532 double red=0, green=0, blue=0;
1533 int r=0, g=0, b=0;
1534
1535 red = ((double)255) * ((double)(xpm_ptr->red[pixel_index])) /
1536 ((double)10000.0);
1537 green = ((double)255) * ((double)(xpm_ptr->green[pixel_index])) /
1538 ((double)10000.0);
1539 blue = ((double)255) * ((double)(xpm_ptr->blue[pixel_index])) /
1540 ((double)10000.0);
1541
1542 r = round(red);
1543 g = round(green);
1544 b = round(blue);
1545
1546 if (r > 255) r = 255;
1547 if (g > 255) g = 255;
1548 if (b > 255) b = 255;
1549
1550 if (r < 0) r = 0;
1551 if (g < 0) g = 0;
1552 if (b < 0) b = 0;
1553
1554 pcb->r = (unsigned char)(r & 0x0ff);
1555 pcb->g = (unsigned char)(g & 0x0ff);
1556 pcb->b = (unsigned char)(b & 0x0ff);
1557
1558 pcb->valid = TRUE;
1559 }
1560
1561 static
SetAColorByteByXpmRGB(pcb,xpm_ptr,index,table_size)1562 void SetAColorByteByXpmRGB(pcb, xpm_ptr, index, table_size)
1563 ColorBytes *pcb;
1564 struct XPmRec *xpm_ptr;
1565 int index, table_size;
1566 {
1567 #ifdef _TGIF_DBG /* debug, do not translate */
1568 TgAssert(index >= 0 && index < table_size,
1569 "index out of range in SetAColorByteByXpmRGB()", NULL);
1570 #endif /* _TGIF_DBG */
1571 if (pcb[index].valid) return;
1572
1573 SetAColorByteInfoByXpmRGB(&pcb[index], xpm_ptr, index);
1574 }
1575
1576 static
SetAColorByteByMaxRGB(pcb,xpm_color_index,global_color_index,table_size)1577 void SetAColorByteByMaxRGB(pcb, xpm_color_index, global_color_index, table_size)
1578 ColorBytes *pcb;
1579 int xpm_color_index, global_color_index, table_size;
1580 {
1581 #ifdef _TGIF_DBG /* debug, do not translate */
1582 TgAssert(xpm_color_index >= 0 && xpm_color_index < table_size,
1583 "xpm_color_index out of range in SetAColorByteByXpmRGB()", NULL);
1584 #endif /* _TGIF_DBG */
1585 if (pcb[xpm_color_index].valid) return;
1586
1587 SetAColorByteInfo(&pcb[xpm_color_index], &tgifColors[global_color_index]);
1588 }
1589
ConvertPpmTrueToPpm6(ppm_data,ppm_data_size,ppm_data_compress,tmp_ppm6_fname,tmp_ppm6_sz)1590 int ConvertPpmTrueToPpm6(ppm_data, ppm_data_size, ppm_data_compress,
1591 tmp_ppm6_fname, tmp_ppm6_sz)
1592 char *ppm_data, *tmp_ppm6_fname;
1593 int ppm_data_size, ppm_data_compress, tmp_ppm6_sz;
1594 {
1595 *tmp_ppm6_fname = '\0';
1596 if (ppm_data_compress == PPM_JPEG_COMPRESS) {
1597 char jpeg_fname[MAXPATHLENGTH+1];
1598
1599 if (!WriteBufIntoTmpFile(ppm_data, ppm_data_size, jpeg_fname,
1600 sizeof(jpeg_fname))) {
1601 return FALSE;
1602 }
1603 if (!ConvertJpegToPpm6(jpeg_fname, tmp_ppm6_fname, tmp_ppm6_sz)) {
1604 unlink(jpeg_fname);
1605 return FALSE;
1606 }
1607 unlink(jpeg_fname);
1608 } else if (ppm_data_compress == PPM_DATA_DEFLATED) {
1609 FILE *fp=NULL;
1610 int rc=0;
1611
1612 if (MkTempFile(tmp_ppm6_fname, tmp_ppm6_sz, tmpDir, TOOL_NAME) == NULL) {
1613 return FALSE;
1614 }
1615 if ((fp=fopen(tmp_ppm6_fname, "w")) == NULL) {
1616 FailToOpenMessage(tmp_ppm6_fname, "w", NULL);
1617 return FALSE;
1618 }
1619 if (!DoInflate(ppm_data, ppm_data_size, fp, FALSE, &rc)) {
1620 fclose(fp);
1621 unlink(tmp_ppm6_fname);
1622 ZlibError(rc, FALSE);
1623 return FALSE;
1624 }
1625 fclose(fp);
1626 }
1627 return TRUE;
1628 }
1629
1630 static
GetImagePixels(ObjPtr,xpm_ptr,pipi,pxtii,pcb)1631 int GetImagePixels(ObjPtr, xpm_ptr, pipi, pxtii, pcb)
1632 struct ObjRec *ObjPtr;
1633 struct XPmRec *xpm_ptr;
1634 ImagePixelInfo *pipi;
1635 XpmTransIndexInfo *pxtii;
1636 ColorBytes *pcb;
1637 /*
1638 * can only get here if the object has too many colors and colorDump
1639 * also, this object canont have transparent pixels
1640 */
1641 {
1642 int row=0, image_w=xpm_ptr->image_w, image_h=xpm_ptr->image_h;
1643 int chars_per_pixel=0, pixel_index=0;
1644 int ncolors=0;
1645 char *xpm_data=NULL, *color_char=NULL;
1646 Pixmap pixmap=(Pixmap)0, bitmap=(Pixmap)0;
1647 XImage *image=NULL, *bitmap_image=NULL;
1648
1649 memset(pipi, 0, sizeof(ImagePixelInfo));
1650 if (image_h == 0) return FALSE;
1651
1652 pixmap = xpm_ptr->pixmap;
1653 bitmap = xpm_ptr->bitmap;
1654
1655 if ((!PRTGIF || cmdLineOpenDisplay) &&
1656 (image=xpm_ptr->image) == NULL) {
1657 if ((image=xpm_ptr->image=XGetImage(mainDisplay, pixmap, 0, 0,
1658 image_w, image_h, AllPlanes, ZPixmap)) == NULL) {
1659 Msg(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM));
1660 return FALSE;
1661 }
1662 }
1663 if ((!PRTGIF || cmdLineOpenDisplay) &&
1664 (bitmap_image=xpm_ptr->bitmap_image) == NULL) {
1665 if ((bitmap_image=xpm_ptr->bitmap_image=XGetImage(mainDisplay, bitmap,
1666 0, 0, image_w, image_h, 1, ZPixmap)) == NULL) {
1667 Msg(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM));
1668 return FALSE;
1669 }
1670 }
1671 pipi->image_pixels = (int**)malloc(image_h*sizeof(int*));
1672 pipi->transparent =
1673 (unsigned char **)malloc(image_h*sizeof(unsigned char *));
1674 if (pipi->image_pixels == NULL || pipi->transparent == NULL) {
1675 FailAllocMessage();
1676 }
1677 memset(pipi->image_pixels, 0, image_h*sizeof(int*));
1678 memset(pipi->transparent, 0, image_h*sizeof(unsigned char *));
1679 for (row=0; row < image_h; row++) {
1680 pipi->image_pixels[row] = (int*)malloc(image_w*sizeof(int));
1681 pipi->transparent[row] =
1682 (unsigned char *)malloc(image_w*sizeof(unsigned char));
1683 if (pipi->image_pixels[row] == NULL || pipi->transparent[row] == NULL) {
1684 FailAllocMessage();
1685 }
1686 memset(pipi->image_pixels[row], 0, image_w*sizeof(int));
1687 memset(pipi->transparent[row], 0, image_w*sizeof(unsigned char));
1688 }
1689 ncolors = xpm_ptr->ncolors;
1690
1691 xpm_data = xpm_ptr->data;
1692 chars_per_pixel = xpm_ptr->chars_per_pixel;
1693 color_char = xpm_ptr->color_char;
1694
1695 for (row=0; row < image_h; row++) {
1696 int col=0;
1697
1698 for (col=0; col < image_w; col++) {
1699 int transparent_pixel=INVALID;
1700 #ifdef NOT_DEFINED
1701 float gray=(float)0;
1702 int value=0;
1703 #endif /* NOT_DEFINED */
1704
1705 if (PRTGIF && !cmdLineOpenDisplay) {
1706 /* this works! */
1707 pixel_index = XPmLookUp(INVALID, chars_per_pixel,
1708 &(xpm_data[(row*image_w+col)*chars_per_pixel]), NULL);
1709 SetAColorByteByXpmRGB(pcb, xpm_ptr, pixel_index, ncolors+3);
1710
1711 if (!pxtii->has_transparent_pixel) {
1712 if (!colorDump) {
1713 /* should never get here */
1714 #ifdef NOT_DEFINED
1715 gray = 0.299*((float)xpm_ptr->red[pixel_index]/10000.0) +
1716 0.587*((float)xpm_ptr->green[pixel_index]/10000.0) +
1717 0.114*((float)xpm_ptr->blue[pixel_index]/10000.0);
1718 value = gray*256;
1719 pixel_index = ((value>255) ? 255 : ((value<0) ? 0 : value));
1720 #endif /* NOT_DEFINED */
1721 } else {
1722 if (pxtii->has_transparent_pixel &&
1723 pxtii->found_transparent_pixel &&
1724 pxtii->transparent_pixel_index == pixel_index) {
1725 pipi->transparent[row][col] = TRUE;
1726 }
1727 }
1728 } else {
1729 /* should never get here */
1730 if (pxtii->has_transparent_pixel &&
1731 pxtii->found_transparent_pixel &&
1732 pxtii->transparent_pixel_index == pixel_index) {
1733 pipi->transparent[row][col] = TRUE;
1734 }
1735 }
1736 } else {
1737 if (colorDump || pxtii->has_transparent_pixel) {
1738 if (!colorDisplay && xpm_ptr->red != NULL) {
1739 pixel_index = XPmLookUp(INVALID, chars_per_pixel,
1740 &(xpm_data[(row*image_w+col)*chars_per_pixel]), NULL);
1741 SetAColorByteByXpmRGB(pcb, xpm_ptr, pixel_index, ncolors+3);
1742 } else if (XGetPixel(bitmap_image,col,row) != 0) {
1743 /* this works! */
1744 int pixel=XGetPixel(image,col,row), global_color_index=(-1);
1745
1746 pixel_index = XPmLookUp(pixel, INVALID, NULL, NULL);
1747 if (HashLookUpInt(&gColorsHashForPrinting,
1748 (char*)(&pixel), sizeof(int), &global_color_index)) {
1749 SetAColorByteByMaxRGB(pcb, pixel_index, global_color_index,
1750 ncolors+3);
1751 } else {
1752 }
1753 } else {
1754 /* transparent pixel */
1755 pixel_index = XPmLookUp((-1), INVALID, NULL, NULL);
1756 transparent_pixel = pixel_index;
1757 }
1758 if (pxtii->has_transparent_pixel &&
1759 pxtii->found_transparent_pixel &&
1760 pxtii->transparent_pixel_index == pixel_index) {
1761 pipi->transparent[row][col] = TRUE;
1762 }
1763 } else {
1764 /* should never get here */
1765 #ifdef NOT_DEFINED
1766 if (!colorDisplay && xpm_ptr->red != NULL) {
1767 pixel_index = XPmLookUp(INVALID, chars_per_pixel,
1768 &(xpm_data[(row*image_w+col)*chars_per_pixel]), NULL);
1769 gray = 0.299*((float)xpm_ptr->red[pixel_index]/10000.0) +
1770 0.587*((float)xpm_ptr->green[pixel_index]/10000.0) +
1771 0.114*((float)xpm_ptr->blue[pixel_index]/10000.0);
1772 } else {
1773 int cur_pixel=0, found_index=0;
1774
1775 if (XGetPixel(bitmap_image, col, row) != 0) {
1776 cur_pixel = XGetPixel(image, col, row);
1777 } else {
1778 found_index = ObjPtr->color;
1779 cur_pixel = (-1);
1780 }
1781 if (cur_pixel != (-1)) {
1782 int i=0;
1783
1784 for (i=0; i < maxColors; i++) {
1785 if (colorPixels[i] == cur_pixel) {
1786 found_index = i;
1787 break;
1788 }
1789 }
1790 }
1791 gray = 0.299*((float)tgifColors[found_index].red/maxRGB) +
1792 0.587*((float)tgifColors[found_index].green/maxRGB) +
1793 0.114*((float)tgifColors[found_index].blue/maxRGB);
1794 SetAColorByteByMaxRGB(pcb, pixel_index, ncolors+3);
1795 }
1796 value = gray*256;
1797 pixel_index = ((value>255) ? 255 : ((value<0) ? 0 : value));
1798 #endif /* NOT_DEFINED */
1799 }
1800 }
1801 pipi->image_pixels[row][col] = pixel_index;
1802 }
1803 }
1804 return TRUE;
1805 }
1806
1807 static
PrepareColorsForConvertObjToPpm6(xpm_ptr,pxtii)1808 int PrepareColorsForConvertObjToPpm6(xpm_ptr, pxtii)
1809 struct XPmRec *xpm_ptr;
1810 XpmTransIndexInfo *pxtii;
1811 {
1812 int index=0, ncolors=xpm_ptr->ncolors;
1813 int chars_per_pixel=xpm_ptr->chars_per_pixel;
1814 char *color_char=xpm_ptr->color_char;
1815 int *pixels=xpm_ptr->pixels;
1816
1817 if (colorDump) {
1818 if ((PRTGIF && !cmdLineOpenDisplay) ||
1819 (!colorDisplay && xpm_ptr->red != NULL)) {
1820 if (!BuildXPmBuckets(ncolors, NULL, NULL, chars_per_pixel,
1821 color_char, pxtii)) {
1822 return FALSE;
1823 }
1824 for (index=0; index < ncolors; index++) {
1825 if (xpm_ptr->red[index] == (-1)) {
1826 if (pxtii->has_transparent_pixel) {
1827 if (pxtii->found_transparent_pixel) {
1828 #ifdef _TGIF_DBG /* debug, do not translate */
1829 TgAssert(FALSE,
1830 "Found transparent pixel again in PrepareColorsForConvertObjToPpm6()",
1831 NULL);
1832 #endif /* _TGIF_DBG */
1833 } else {
1834 pxtii->found_transparent_pixel = TRUE;
1835 pxtii->transparent_pixel_index = index;
1836 }
1837 }
1838 }
1839 }
1840 } else {
1841 /* interactive printing */
1842 pxtii->dump_index_to_color_index =
1843 (int*)malloc((maxColors+3)*sizeof(int));
1844 if (pxtii->dump_index_to_color_index == NULL) FailAllocMessage();
1845 for (index=0; index < maxColors+3; index++) {
1846 pxtii->dump_index_to_color_index[index] = INVALID;
1847 }
1848 if (!BuildXPmBuckets(ncolors, pixels,
1849 pxtii->dump_index_to_color_index, INVALID, NULL, pxtii)) {
1850 return FALSE;
1851 }
1852 }
1853 } else if ((PRTGIF && !cmdLineOpenDisplay) ||
1854 (!colorDisplay && xpm_ptr->red != NULL)) {
1855 if (!BuildXPmBuckets(ncolors, NULL, NULL, chars_per_pixel, color_char,
1856 pxtii)) {
1857 return FALSE;
1858 }
1859 } else if (pxtii->has_transparent_pixel) {
1860 /*
1861 * should never get here since such object is not suppose to have
1862 * transparent pixels!
1863 */
1864 pxtii->dump_index_to_color_index =
1865 (int*)malloc((maxColors+3)*sizeof(int));
1866 if (pxtii->dump_index_to_color_index == NULL) FailAllocMessage();
1867 for (index=0; index < maxColors+3; index++) {
1868 pxtii->dump_index_to_color_index[index] = INVALID;
1869 }
1870 if (!BuildXPmBuckets(ncolors, pixels, pxtii->dump_index_to_color_index,
1871 INVALID, NULL, pxtii)) {
1872 return FALSE;
1873 }
1874 }
1875 return TRUE;
1876 }
1877
1878 static
ConvertObjToPpm6(ObjPtr,xpm_ptr,psz_ppm6_path,ppm6_path_sz,pxtii)1879 int ConvertObjToPpm6(ObjPtr, xpm_ptr, psz_ppm6_path, ppm6_path_sz, pxtii)
1880 struct ObjRec *ObjPtr;
1881 struct XPmRec *xpm_ptr;
1882 char *psz_ppm6_path;
1883 int ppm6_path_sz;
1884 XpmTransIndexInfo *pxtii;
1885 {
1886 FILE *ppm_fp=NULL;
1887 int row=0, image_w=xpm_ptr->image_w, image_h=xpm_ptr->image_h, pixel_index=0;
1888 int ncolors=xpm_ptr->ncolors;
1889 XColor *saved_tgif_colors=tgifColors;
1890 ColorBytes *pcb=(ColorBytes*)malloc((ncolors+3)*sizeof(ColorBytes));
1891 ImagePixelInfo ipi;
1892
1893 if (!PrepareColorsForConvertObjToPpm6(xpm_ptr, pxtii)) return FALSE;
1894
1895 /*
1896 * pcb maps an object color index to an RGB value
1897 */
1898 if (pcb == NULL) FailAllocMessage();
1899 memset(pcb, 0, (ncolors+3)*sizeof(ColorBytes));
1900 if (printUsingRequestedColor) tgifColors = tgifRequestedColors;
1901
1902 if (MkTempFile(psz_ppm6_path, ppm6_path_sz, tmpDir, TOOL_NAME) == NULL) {
1903 free(pcb);
1904 if (printUsingRequestedColor) tgifColors = saved_tgif_colors;
1905 return FALSE;
1906 }
1907 if ((ppm_fp=fopen(psz_ppm6_path, "w")) == NULL) {
1908 free(pcb);
1909 if (printUsingRequestedColor) tgifColors = saved_tgif_colors;
1910 return FailToOpenMessage(psz_ppm6_path, "w", NULL);
1911 }
1912 memset(&ipi, 0, sizeof(ImagePixelInfo));
1913
1914 if (!GetImagePixels(ObjPtr, xpm_ptr, &ipi, pxtii, pcb)) {
1915 free(pcb);
1916 if (printUsingRequestedColor) tgifColors = saved_tgif_colors;
1917 return FALSE;
1918 }
1919 writeFileFailed = FALSE;
1920
1921 fprintf(ppm_fp, "P6\n%1d %1d\n255\n", image_w, image_h);
1922 for (row=0; row < image_h; row++) {
1923 int col=0;
1924
1925 for (col=0; col < image_w; col++) {
1926 pixel_index = ipi.image_pixels[row][col];
1927
1928 if (fprintf(ppm_fp, "%c%c%c", pcb[pixel_index].r, pcb[pixel_index].g,
1929 pcb[pixel_index].b) == EOF) {
1930 writeFileFailed = TRUE;
1931 }
1932 }
1933 }
1934 fclose(ppm_fp);
1935 FreeImagePixels(&ipi);
1936
1937 if (writeFileFailed) {
1938 FailToWriteFileMessage(psz_ppm6_path);
1939 }
1940 if (printUsingRequestedColor) tgifColors = saved_tgif_colors;
1941 free(pcb);
1942
1943 return TRUE;
1944 }
1945
DumpXPmObj(FP,ObjPtr)1946 void DumpXPmObj(FP, ObjPtr)
1947 FILE *FP;
1948 struct ObjRec *ObjPtr;
1949 {
1950 int row=0, i=0, index=0, col=0, too_many_colors=FALSE;
1951 int ltx=0, lty=0, rbx=0, rby=0, w=0, h=0, image_w=0, image_h=0;
1952 int ncolors=0, *pixels=NULL, flip=0, orig_x=0, orig_y=0;
1953 int cur_pixel=0, chars_per_pixel=0, x=0, y=0, found_index=0, pixel_index=0;
1954 int has_transparent_pixel=FALSE, is_linked_jpeg=IsLinkedJpegObj(ObjPtr);
1955 unsigned int trans_color_pixel_r=0, trans_color_pixel_g=0, trans_color_pixel_b=0;
1956 int is_ppm_true=FALSE;
1957 char *xpm_data=NULL, *color_char=NULL;
1958 Pixmap pixmap=(Pixmap)0, bitmap=(Pixmap)0;
1959 XImage *image=NULL, *bitmap_image=NULL;
1960 struct XPmRec *xpm_ptr=NULL;
1961 struct MtrxRec mtrx;
1962 XpmTransIndexInfo xtii;
1963
1964 memset(&mtrx, 0, sizeof(struct MtrxRec));
1965 memset(&xtii, 0, sizeof(XpmTransIndexInfo));
1966
1967 ltx = ObjPtr->obbox.ltx;
1968 lty = ObjPtr->obbox.lty;
1969 rbx = ObjPtr->obbox.rbx;
1970 rby = ObjPtr->obbox.rby;
1971
1972 xpm_ptr = ObjPtr->detail.xpm;
1973
1974 pixmap = xpm_ptr->pixmap;
1975 bitmap = xpm_ptr->bitmap;
1976 pixels = xpm_ptr->pixels;
1977 ncolors = xpm_ptr->ncolors;
1978 flip = xpm_ptr->flip;
1979 image_w = xpm_ptr->image_w;
1980 image_h = xpm_ptr->image_h;
1981
1982 w = rbx - ltx;
1983 h = rby - lty;
1984
1985 is_ppm_true = IsPpmTrueObj(xpm_ptr->real_type, xpm_ptr->ppm_data_compress,
1986 xpm_ptr->ppm_data);
1987
1988 if ((!PRTGIF || cmdLineOpenDisplay) &&
1989 (image=xpm_ptr->image) == NULL) {
1990 if ((image=xpm_ptr->image=XGetImage(mainDisplay, pixmap, 0, 0,
1991 image_w, image_h, AllPlanes, ZPixmap)) == NULL) {
1992 Msg(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM));
1993 return;
1994 }
1995 }
1996 if ((!PRTGIF || cmdLineOpenDisplay) &&
1997 (bitmap_image=xpm_ptr->bitmap_image) == NULL) {
1998 if ((bitmap_image=xpm_ptr->bitmap_image=XGetImage(mainDisplay, bitmap,
1999 0, 0, image_w, image_h, 1, ZPixmap)) == NULL) {
2000 Msg(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM));
2001 return;
2002 }
2003 }
2004 mtrx.image_w = (float)image_w; mtrx.image_h = (float)image_h;
2005 mtrx.w = (float)w; mtrx.h = (float)h;
2006 mtrx.rotate = ROTATE0; mtrx.flip = flip;
2007
2008 CalcTransform(&mtrx);
2009
2010 orig_x = (mtrx.transformed_w >= 0.0) ? ltx : ltx+w;
2011 orig_y = (mtrx.transformed_h >= 0.0) ? lty : lty+h;
2012
2013 fprintf(FP, "%% XPM\n");
2014
2015 xpm_data = xpm_ptr->data;
2016 chars_per_pixel = xpm_ptr->chars_per_pixel;
2017 color_char = xpm_ptr->color_char;
2018
2019 if (PRTGIF && !cmdLineOpenDisplay && fileVersion < 25) {
2020 /* can't print color with PRTGIF, treat it like a bitmap */
2021 PrTgifDumpOldXPmObj(FP, ObjPtr, &mtrx);
2022 return;
2023 }
2024 if ((PRTGIF && !cmdLineOpenDisplay) ||
2025 (!colorDisplay && xpm_ptr->red != NULL)) {
2026 if (xpm_ptr->real_type == PPM_TRUE && xpm_ptr->has_transparent_color) {
2027 has_transparent_pixel = TRUE;
2028 trans_color_pixel_r = (unsigned int)xpm_ptr->transparent_color[0];
2029 trans_color_pixel_g = (unsigned int)xpm_ptr->transparent_color[1];
2030 trans_color_pixel_b = (unsigned int)xpm_ptr->transparent_color[2];
2031 } else {
2032 int *red_ptr=xpm_ptr->red;
2033
2034 if (ncolors > 0xff) {
2035 too_many_colors = TRUE;
2036 }
2037 for (index = 0; index < ncolors; index++) {
2038 if (red_ptr[index] == (-1)) {
2039 has_transparent_pixel = TRUE;
2040 break;
2041 }
2042 }
2043 }
2044 } else {
2045 if (fullTrueColorMode && xpm_ptr->real_type == PPM_TRUE &&
2046 xpm_ptr->has_transparent_color) {
2047 has_transparent_pixel = TRUE;
2048 trans_color_pixel_r = (unsigned int)xpm_ptr->transparent_color[0];
2049 trans_color_pixel_g = (unsigned int)xpm_ptr->transparent_color[1];
2050 trans_color_pixel_b = (unsigned int)xpm_ptr->transparent_color[2];
2051 } else {
2052 if (ncolors > 0xff) {
2053 too_many_colors = TRUE;
2054 }
2055 for (index = 0; index < ncolors; index++) {
2056 if (pixels[index] == (-1)) {
2057 has_transparent_pixel = TRUE;
2058 break;
2059 }
2060 }
2061 }
2062 }
2063 if (has_transparent_pixel) {
2064 xtii.has_transparent_pixel = TRUE;
2065 if (((PRTGIF && !cmdLineOpenDisplay) || fullTrueColorMode) &&
2066 xpm_ptr->real_type == PPM_TRUE && xpm_ptr->has_transparent_color) {
2067 } else if (too_many_colors && colorDump) {
2068 sprintf(gszMsgBox, TgLoadString(STID_TRANS_XPM_TOO_MANY_COLORS_SKP),
2069 ncolors);
2070 if (PRTGIF) {
2071 fprintf(stderr, "%s\n", gszMsgBox);
2072 } else {
2073 Msg(gszMsgBox);
2074 }
2075 xpmHasTooManyColorsForPrinting = TRUE;
2076 return;
2077 }
2078 }
2079 x = (mtrx.transformed_w >= 0.0) ? ltx : ltx+w;
2080 y = (mtrx.transformed_h >= 0.0) ? lty : lty+h;
2081
2082 fprintf(FP, "%s\n", gPsCmd[PS_GSAVE]);
2083 if (is_linked_jpeg) {
2084 if (!ConvertJpegToPpm6(xpm_ptr->filename, xpm_ptr->tmp_ppm6_fname,
2085 sizeof(xpm_ptr->tmp_ppm6_fname))) {
2086 return;
2087 }
2088 } else if (is_ppm_true) {
2089 if (!ConvertPpmTrueToPpm6(xpm_ptr->ppm_data, xpm_ptr->ppm_data_size,
2090 xpm_ptr->ppm_data_compress, xpm_ptr->tmp_ppm6_fname,
2091 sizeof(xpm_ptr->tmp_ppm6_fname))) {
2092 return;
2093 }
2094 } else if (too_many_colors && colorDump) {
2095 if (!ConvertObjToPpm6(ObjPtr, xpm_ptr, xpm_ptr->tmp_ppm6_fname,
2096 sizeof(xpm_ptr->tmp_ppm6_fname), &xtii)) {
2097 return;
2098 }
2099 } else if (colorDump) {
2100 fprintf(FP, " 3 %1d %s %s tgifsetpixels\n", ncolors,
2101 gPsCmd[PS_MUL], gPsCmd[PS_ARRAY]);
2102
2103 if ((PRTGIF && !cmdLineOpenDisplay) ||
2104 (!colorDisplay && xpm_ptr->red != NULL)) {
2105 if (!BuildXPmBuckets(ncolors, NULL, NULL, chars_per_pixel,
2106 color_char, &xtii)) {
2107 return;
2108 }
2109 for (index = 0; index < ncolors; index++) {
2110 if (xpm_ptr->red[index] == (-1)) {
2111 fprintf(FP, "%s%3d [ -1.00 -1.00 -1.00 ] tgifsetpix",
2112 ((index & 0x1) ? "" : " "), index*3);
2113 } else {
2114 fprintf(FP, "%s%3d [ %.3f %.3f %.3f ] tgifsetpix",
2115 ((index & 0x1) ? "" : " "), index*3,
2116 ((float)xpm_ptr->red[index])/((float)10000.0),
2117 ((float)xpm_ptr->green[index])/((float)10000.0),
2118 ((float)xpm_ptr->blue[index])/((float)10000.0));
2119 }
2120 fprintf(FP, "%s", ((index & 0x1) ? "\n" : " "));
2121 }
2122 } else {
2123 if (!BuildXPmBuckets(ncolors, pixels, NULL, INVALID, NULL, &xtii)) {
2124 return;
2125 }
2126 for (index = 0; index < ncolors; index++) {
2127 cur_pixel = pixels[index];
2128 if (cur_pixel != (-1)) {
2129 found_index = ObjPtr->color;
2130 for (i = 0; i < maxColors; i++) {
2131 if (colorPixels[i] == cur_pixel) {
2132 found_index = i;
2133 break;
2134 }
2135 }
2136 fprintf(FP, "%s%3d [ %.3f %.3f %.3f ] tgifsetpix",
2137 ((index & 0x1) ? "" : " "), index*3,
2138 ((float)tgifColors[found_index].red/maxRGB),
2139 ((float)tgifColors[found_index].green/maxRGB),
2140 ((float)tgifColors[found_index].blue/maxRGB));
2141 } else {
2142 fprintf(FP, "%s%3d [ -1.00 -1.00 -1.00 ] tgifsetpix",
2143 ((index & 0x1) ? "" : " "), index*3);
2144 }
2145 fprintf(FP, "%s", ((index & 0x1) ? "\n" : " "));
2146 }
2147 }
2148 if (ncolors & 0x1) fprintf(FP, "\n");
2149 } else if ((PRTGIF && !cmdLineOpenDisplay) ||
2150 (!colorDisplay && xpm_ptr->red != NULL)) {
2151 if (!BuildXPmBuckets(ncolors, NULL, NULL, chars_per_pixel, color_char,
2152 &xtii)) {
2153 return;
2154 }
2155 if (has_transparent_pixel) {
2156 fprintf(FP, " 3 %1d %s %s tgifsetpixels\n", ncolors,
2157 gPsCmd[PS_MUL], gPsCmd[PS_ARRAY]);
2158
2159 for (index = 0; index < ncolors; index++) {
2160 if (xpm_ptr->red[index] == (-1)) {
2161 fprintf(FP, "%s%3d [ -1.00 -1.00 -1.00 ] tgifsetpix",
2162 ((index & 0x1) ? "" : " "), index*3);
2163 } else {
2164 float gray;
2165
2166 gray = 0.299*((float)xpm_ptr->red[index]/10000.0) +
2167 0.587*((float)xpm_ptr->green[index]/10000.0) +
2168 0.114*((float)xpm_ptr->blue[index]/10000.0);
2169 fprintf(FP, "%s%3d [ %.3f %.3f %.3f ] tgifsetpix",
2170 ((index & 0x1) ? "" : " "), index*3,
2171 gray, gray, gray);
2172 }
2173 fprintf(FP, "%s", ((index & 0x1) ? "\n" : " "));
2174 }
2175 }
2176 } else if (has_transparent_pixel) {
2177 if (!BuildXPmBuckets(ncolors, pixels, NULL, INVALID, NULL, &xtii)) {
2178 return;
2179 }
2180 fprintf(FP, " 3 %1d %s %s tgifsetpixels\n", ncolors,
2181 gPsCmd[PS_MUL], gPsCmd[PS_ARRAY]);
2182
2183 for (index = 0; index < ncolors; index++) {
2184 cur_pixel = pixels[index];
2185 if (cur_pixel != (-1)) {
2186 float gray;
2187
2188 found_index = ObjPtr->color;
2189 for (i = 0; i < maxColors; i++) {
2190 if (colorPixels[i] == cur_pixel) {
2191 found_index = i;
2192 break;
2193 }
2194 }
2195 gray = 0.299*((float)tgifColors[found_index].red)/((float)maxRGB) +
2196 0.587*((float)tgifColors[found_index].green)/((float)maxRGB) +
2197 0.114*((float)tgifColors[found_index].blue)/((float)maxRGB);
2198 fprintf(FP, "%s%3d [ %.3f %.3f %.3f ] tgifsetpix",
2199 ((index & 0x1) ? "" : " "), index*3,
2200 gray, gray, gray);
2201 } else {
2202 fprintf(FP, "%s%3d [ -1.00 -1.00 -1.00 ] tgifsetpix",
2203 ((index & 0x1) ? "" : " "), index*3);
2204 }
2205 fprintf(FP, "%s", ((index & 0x1) ? "\n" : " "));
2206 }
2207 } else {
2208 /* grayscale */
2209 }
2210 if (((PRTGIF && !cmdLineOpenDisplay) || fullTrueColorMode) &&
2211 xpm_ptr->real_type == PPM_TRUE && xpm_ptr->has_transparent_color) {
2212 fprintf(FP, " %1d %1d %1d tgifsetppmtruetranspix\n",
2213 trans_color_pixel_r, trans_color_pixel_g, trans_color_pixel_b);
2214 }
2215 if (ObjPtr->ctm == NULL) {
2216 fprintf(FP, " %1d %1d %s %.3f %.3f %s %1d %s\n", x, y,
2217 gPsCmd[PS_TRANSLATE], mtrx.dump_h_scale, mtrx.dump_v_scale,
2218 gPsCmd[PS_SCALE], mtrx.degree, gPsCmd[PS_ROTATE]);
2219 } else {
2220 float m[6];
2221
2222 m[CTM_SX] = ((float)ObjPtr->ctm->m[CTM_SX])/((float)1000.0);
2223 m[CTM_SY] = ((float)ObjPtr->ctm->m[CTM_SY])/((float)1000.0);
2224 m[CTM_SIN] = ((float)ObjPtr->ctm->m[CTM_SIN])/((float)1000.0);
2225 m[CTM_MSIN] = ((float)ObjPtr->ctm->m[CTM_MSIN])/((float)1000.0);
2226 fprintf(FP, " %1d %1d %s\n", ObjPtr->x, ObjPtr->y,
2227 gPsCmd[PS_TRANSLATE]);
2228 fprintf(FP, " [%.3f %.3f %.3f %.3f %1d %1d] %s\n",
2229 m[CTM_SX], m[CTM_SIN], m[CTM_MSIN], m[CTM_SY],
2230 ObjPtr->ctm->t[CTM_TX], ObjPtr->ctm->t[CTM_TY], gPsCmd[PS_CONCAT]);
2231 }
2232 fprintf(FP, " %1d %1d 8\n [1 0 0 1 0 0]\n", image_w, image_h);
2233
2234 if (preDumpSetup) {
2235 PSUseColorImage();
2236 hasReadHexString = TRUE;
2237 }
2238 if (is_linked_jpeg || is_ppm_true || (too_many_colors && colorDump)) {
2239 if (((PRTGIF && !cmdLineOpenDisplay) || fullTrueColorMode) &&
2240 xpm_ptr->real_type == PPM_TRUE && xpm_ptr->has_transparent_color) {
2241 fprintf(FP, " { }\n");
2242 fprintf(FP, " false 3 tgiftransppmtruecolorimage\n ");
2243 } else {
2244 fprintf(FP, " {currentfile\n");
2245 fprintf(FP, " tgifbwpicstr readhexstring pop}\n");
2246 fprintf(FP, " false 3 colorimage\n ");
2247 }
2248 } else if (colorDump) {
2249 fprintf(FP, " {currentfile\n");
2250 fprintf(FP, " tgifbwpicstr readhexstring pop 0 get tgifcolorspot}\n");
2251 if (has_transparent_pixel) {
2252 fprintf(FP, " false 3 tgiftranscolorimage\n ");
2253 } else {
2254 fprintf(FP, " false 3 colorimage\n ");
2255 }
2256 } else {
2257 /* grayscale */
2258 if (has_transparent_pixel) {
2259 fprintf(FP, " {currentfile\n");
2260 fprintf(FP, " %s}\n",
2261 "tgifbwpicstr readhexstring pop 0 get tgifcolorspot");
2262 fprintf(FP, " false 3 tgiftranscolorimage\n ");
2263 } else {
2264 fprintf(FP, " {currentfile\n");
2265 fprintf(FP, " tgifbwpicstr readhexstring pop}\n");
2266 fprintf(FP, " %s\n ", gPsCmd[PS_IMAGE]);
2267 }
2268 }
2269 /*
2270 * Transparent_pixel is dealt with a little bit differently here.
2271 * When generating colors for a particular pixel, if the pixel is
2272 * suppose to be transparent, the color components are all
2273 * (-1). The postscript code will take care of it and not
2274 * put down any ink.
2275 * Whether we are doing colorDump or not doesn't matter here.
2276 */
2277 if (is_linked_jpeg || is_ppm_true || (too_many_colors && colorDump)) {
2278 DumpPpm6File(FP, image_w, image_h, xpm_ptr->tmp_ppm6_fname);
2279 unlink(xpm_ptr->tmp_ppm6_fname);
2280 *xpm_ptr->tmp_ppm6_fname = '\0';
2281 if (xtii.dump_index_to_color_index != NULL) {
2282 free(xtii.dump_index_to_color_index);
2283 }
2284 } else if (PRTGIF && !cmdLineOpenDisplay) {
2285 for (row=0; row < image_h; row++) {
2286 for (col=0; col < image_w; col++) {
2287 float gray;
2288 int value;
2289
2290 pixel_index = XPmLookUp(INVALID, chars_per_pixel,
2291 &(xpm_data[(row*image_w+col)*chars_per_pixel]), NULL);
2292
2293 if (!has_transparent_pixel) {
2294 if (!colorDump) {
2295 gray = 0.299*((float)xpm_ptr->red[pixel_index]/10000.0) +
2296 0.587*((float)xpm_ptr->green[pixel_index]/10000.0) +
2297 0.114*((float)xpm_ptr->blue[pixel_index]/10000.0);
2298 value = gray*256;
2299 pixel_index = ((value>255) ? 255 : ((value<0) ? 0 : value));
2300 }
2301 }
2302 fprintf(FP, "%c", hexValue[(pixel_index>>4)&0x0f]);
2303 fprintf(FP, "%c", hexValue[pixel_index&0x0f]);
2304 if (col%36 == 35) fprintf(FP, "\n ");
2305 }
2306 if (col%36 != 0) fprintf(FP, "\n");
2307 if (row != image_h-1) fprintf(FP, " ");
2308 }
2309 } else {
2310 for (row=0; row < image_h; row++) {
2311 for (col=0; col < image_w; col++) {
2312 if (colorDump || has_transparent_pixel) {
2313 if (!colorDisplay && xpm_ptr->red != NULL) {
2314 pixel_index = XPmLookUp(INVALID, chars_per_pixel,
2315 &(xpm_data[(row*image_w+col)*chars_per_pixel]), NULL);
2316 } else if (XGetPixel(bitmap_image,col,row) != 0) {
2317 pixel_index = XPmLookUp(XGetPixel(image,col,row), INVALID,
2318 NULL, NULL);
2319 } else {
2320 pixel_index = XPmLookUp((-1), INVALID, NULL, NULL);
2321 }
2322 } else {
2323 float gray;
2324 int value;
2325
2326 if (!colorDisplay && xpm_ptr->red != NULL) {
2327 pixel_index = XPmLookUp(INVALID, chars_per_pixel,
2328 &(xpm_data[(row*image_w+col)*chars_per_pixel]), NULL);
2329 gray = 0.299*((float)xpm_ptr->red[pixel_index]/10000.0) +
2330 0.587*((float)xpm_ptr->green[pixel_index]/10000.0) +
2331 0.114*((float)xpm_ptr->blue[pixel_index]/10000.0);
2332 } else {
2333 if (XGetPixel(bitmap_image, col, row) != 0) {
2334 cur_pixel = XGetPixel(image, col, row);
2335 } else {
2336 found_index = ObjPtr->color;
2337 cur_pixel = (-1);
2338 }
2339 if (cur_pixel != (-1)) {
2340 for (i = 0; i < maxColors; i++) {
2341 if (colorPixels[i] == cur_pixel) {
2342 found_index = i;
2343 break;
2344 }
2345 }
2346 }
2347 gray = 0.299*((float)tgifColors[found_index].red/maxRGB) +
2348 0.587*((float)tgifColors[found_index].green/maxRGB) +
2349 0.114*((float)tgifColors[found_index].blue/maxRGB);
2350 }
2351 value = gray*256;
2352 pixel_index = ((value>255) ? 255 : ((value<0) ? 0 : value));
2353 }
2354 fprintf(FP, "%c", hexValue[(pixel_index>>4)&0x0f]);
2355 fprintf(FP, "%c", hexValue[pixel_index&0x0f]);
2356 if (col%36 == 35) {
2357 fprintf(FP, "\n%s",
2358 (col==image_w-1 && row==image_h-1) ? "" : " ");
2359 }
2360 }
2361 if (col%36 != 0) fprintf(FP, "\n");
2362 if (row != image_h-1 && (col%36) != 0) fprintf(FP, " ");
2363 }
2364 }
2365 fprintf(FP, "%s\n", gPsCmd[PS_GRESTORE]);
2366 fprintf(FP, "\n");
2367 }
2368
NeedsToCacheXPmObj(ObjPtr)2369 int NeedsToCacheXPmObj(ObjPtr)
2370 struct ObjRec *ObjPtr;
2371 {
2372 register struct XPmRec *xpm_ptr=ObjPtr->detail.xpm;
2373 int w, h;
2374
2375 w = ObjPtr->obbox.rbx - ObjPtr->obbox.ltx;
2376 h = ObjPtr->obbox.rby - ObjPtr->obbox.lty;
2377
2378 return (ObjPtr->ctm != NULL ||
2379 zoomScale != 0 || xpm_ptr->image_w != w || xpm_ptr->image_h != h ||
2380 xpm_ptr->flip != 0);
2381 }
2382
2383 static
DrawHiddenXPm(win,ctm,vs,x,y,w,h,s)2384 void DrawHiddenXPm(win, ctm, vs, x, y, w, h, s)
2385 Window win;
2386 struct XfrmMtrxRec *ctm;
2387 XPoint *vs;
2388 int x, y, w, h;
2389 char *s;
2390 {
2391 int str_w, len, sx, sy;
2392 XGCValues values;
2393
2394 values.foreground = GetDrawingBgPixel(INVALID, INVALID);
2395 values.function = GXcopy;;
2396 values.fill_style = FillSolid;
2397 #ifdef NO_THIN_LINE
2398 values.line_width = 1;
2399 #else
2400 values.line_width = 0;
2401 #endif
2402 values.font = rulerFontPtr->fid;
2403 values.line_style = LineSolid;
2404
2405 XChangeGC(mainDisplay, drawGC,
2406 GCForeground | GCFunction | GCFillStyle | GCLineWidth | GCFont |
2407 GCLineStyle, &values);
2408 if (ctm != NULL) {
2409 XFillPolygon(mainDisplay, win, drawGC, vs, 5, Convex, CoordModeOrigin);
2410 } else {
2411 XFillRectangle(mainDisplay, win, drawGC, x, y, w, h);
2412 }
2413 XSetForeground(mainDisplay, drawGC, GetDrawingFgPixel(INVALID, INVALID));
2414 if (ctm != NULL) {
2415 XDrawLines(mainDisplay, win, drawGC, vs, 5, CoordModeOrigin);
2416 } else {
2417 XDrawRectangle(mainDisplay, win, drawGC, x, y, w, h);
2418 }
2419 XSetForeground(mainDisplay, drawGC, colorPixels[colorIndex]);
2420
2421 len = strlen(s);
2422 str_w = rulerFontWidth*len;
2423 if (str_w < w && rulerFontHeight < h) {
2424 sx = x + ((w-str_w)>>1);
2425 sy = y + ((h-rulerFontHeight)>>1);
2426 XDrawString(mainDisplay, win, drawGC, sx, sy+rulerFontAsc, s, len);
2427 }
2428 XSetFont(mainDisplay, drawGC, canvasFontPtr->fid);
2429 }
2430
RecolorXPmObj(obj_ptr,color_index)2431 void RecolorXPmObj(obj_ptr, color_index)
2432 struct ObjRec *obj_ptr;
2433 int color_index;
2434 {
2435 register int c, r;
2436 struct XPmRec *xpm_ptr=obj_ptr->detail.xpm;
2437 int image_w=xpm_ptr->image_w, image_h=xpm_ptr->image_h;
2438 Pixmap pixmap=None;
2439 XImage *image=NULL;
2440
2441 xpm_ptr->cached_color = (-1);
2442 if (xpm_ptr->bitmap_image == NULL) {
2443 xpm_ptr->bitmap_image = XGetImage(mainDisplay, xpm_ptr->bitmap,
2444 0, 0, image_w, image_h, 1, ZPixmap);
2445 if (xpm_ptr->bitmap_image == NULL) return;
2446 }
2447 if (xpm_ptr->image == NULL) {
2448 xpm_ptr->image = XGetImage(mainDisplay, xpm_ptr->pixmap,
2449 0, 0, image_w, image_h, AllPlanes, ZPixmap);
2450 if (xpm_ptr->image == NULL) return;
2451 }
2452 pixmap = XCreatePixmap(mainDisplay, dummyPixmap, image_w, image_h,
2453 mainDepth);
2454 if (pixmap == None) return;
2455 XFillRectangle(mainDisplay, pixmap, xpmGC, 0, 0, image_w, image_h);
2456 image = XGetImage(mainDisplay, pixmap, 0, 0, image_w, image_h,
2457 AllPlanes, ZPixmap);
2458 if (image == NULL) {
2459 XFreePixmap(mainDisplay, pixmap);
2460 return;
2461 }
2462 for (r=0; r < image_h; r++) {
2463 for (c=0; c < image_w; c++) {
2464 if (XGetPixel(xpm_ptr->bitmap_image, c, r) != 0) {
2465 XPutPixel(image, c, r, XGetPixel(xpm_ptr->image, c, r));
2466 } else {
2467 XPutPixel(image, c, r, colorPixels[color_index]);
2468 }
2469 }
2470 }
2471 XPutImage(mainDisplay, pixmap, xpmGC, image, 0, 0, 0, 0, image_w, image_h);
2472 XFreePixmap(mainDisplay, xpm_ptr->pixmap);
2473 XDestroyImage(xpm_ptr->image);
2474 xpm_ptr->pixmap = pixmap;
2475 xpm_ptr->image = image;
2476 if (obj_ptr->ctm != NULL) {
2477 MakeCachedPixmap(obj_ptr);
2478 }
2479 }
2480
DrawXPmObj(win,XOff,YOff,ObjPtr)2481 void DrawXPmObj(win, XOff, YOff, ObjPtr)
2482 Window win;
2483 int XOff, YOff;
2484 struct ObjRec *ObjPtr;
2485 {
2486 int ltx, lty, rbx, rby, w, h, scr_w, scr_h, real_x_off, real_y_off;
2487 char s[80];
2488 struct XPmRec *xpm_ptr=ObjPtr->detail.xpm;
2489 XGCValues values;
2490
2491 if (userDisableRedraw) return;
2492
2493 if (ObjPtr->prev != NULL && ObjPtr->prev->type == OBJ_XPM &&
2494 Inside(ObjPtr->obbox, ObjPtr->prev->obbox) &&
2495 ObjPtr->prev->detail.xpm->bitmap == None) {
2496 return;
2497 }
2498 w = ObjPtr->obbox.rbx - ObjPtr->obbox.ltx;
2499 h = ObjPtr->obbox.rby - ObjPtr->obbox.lty;
2500
2501 real_x_off = (zoomedIn ? XOff : (XOff>>zoomScale)<<zoomScale);
2502 real_y_off = (zoomedIn ? YOff : (YOff>>zoomScale)<<zoomScale);
2503 ltx = ZOOMED_SIZE(ObjPtr->obbox.ltx - real_x_off);
2504 lty = ZOOMED_SIZE(ObjPtr->obbox.lty - real_y_off);
2505 rbx = ZOOMED_SIZE(ObjPtr->obbox.rbx - real_x_off);
2506 rby = ZOOMED_SIZE(ObjPtr->obbox.rby - real_y_off);
2507 scr_w = rbx - ltx;
2508 scr_h = rby - lty;
2509
2510 if (!mapShown) {
2511 sprintf(s, "(%1dx%1d)", xpm_ptr->image_w, xpm_ptr->image_h);
2512 DrawHiddenXPm(win, ObjPtr->ctm, ObjPtr->rotated_obbox,
2513 ltx, lty, scr_w, scr_h, s);
2514 return;
2515 }
2516 if (NeedsToCacheXPmObj(ObjPtr) &&
2517 (ObjPtr->ctm == NULL ||
2518 (ObjPtr->ctm != NULL && (xpm_ptr->cached_pixmap == None ||
2519 xpm_ptr->clip_mask == None)))) {
2520 MakeCachedPixmap(ObjPtr);
2521 }
2522 XSetFunction(mainDisplay, drawGC, GXcopy);
2523 if (ObjPtr->ctm==NULL && zoomScale==0 &&
2524 xpm_ptr->flip==0 && xpm_ptr->image_w==w && xpm_ptr->image_h==h) {
2525 if (xpm_ptr->bitmap == None) {
2526 XCopyArea(mainDisplay, xpm_ptr->pixmap, win, drawGC, 0, 0, w, h,
2527 ltx, lty);
2528 } else {
2529 values.function = GXcopy;
2530 values.clip_x_origin = ltx;
2531 values.clip_y_origin = lty;
2532 values.clip_mask = xpm_ptr->bitmap;
2533 XChangeGC(mainDisplay, drawGC, GCFunction |
2534 GCClipXOrigin | GCClipYOrigin | GCClipMask, &values);
2535
2536 DrawClippedPixmap(xpm_ptr->pixmap, win, drawGC, scr_w, scr_h,
2537 ltx, lty);
2538
2539 values.clip_x_origin = 0;
2540 values.clip_y_origin = 0;
2541 values.clip_mask = None;
2542 XChangeGC(mainDisplay, drawGC,
2543 GCClipXOrigin | GCClipYOrigin | GCClipMask, &values);
2544 if (numClipRecs > 0) {
2545 XSetClipRectangles(mainDisplay, drawGC, 0, 0, clipRecs,
2546 numClipRecs, clipOrdering);
2547 }
2548 }
2549 } else {
2550 if (xpm_ptr->cached_pixmap == None) return;
2551 if (ObjPtr->ctm == NULL) {
2552 if (xpm_ptr->cached_bitmap == None) {
2553 XCopyArea(mainDisplay, xpm_ptr->cached_pixmap, win, drawGC, 0, 0,
2554 scr_w, scr_h, ltx, lty);
2555 } else {
2556 values.function = GXcopy;
2557 values.clip_x_origin = ltx;
2558 values.clip_y_origin = lty;
2559 values.clip_mask = xpm_ptr->cached_bitmap;
2560 XChangeGC(mainDisplay, drawGC, GCFunction |
2561 GCClipXOrigin | GCClipYOrigin | GCClipMask, &values);
2562
2563 DrawClippedPixmap(xpm_ptr->cached_pixmap, win, drawGC, scr_w, scr_h,
2564 ltx, lty);
2565
2566 values.clip_x_origin = 0;
2567 values.clip_y_origin = 0;
2568 values.clip_mask = None;
2569 XChangeGC(mainDisplay, drawGC,
2570 GCClipXOrigin | GCClipYOrigin | GCClipMask, &values);
2571 if (numClipRecs > 0) {
2572 XSetClipRectangles(mainDisplay, drawGC, 0, 0, clipRecs,
2573 numClipRecs, clipOrdering);
2574 }
2575 }
2576 } else if (xpm_ptr->clip_mask == None) {
2577 XCopyArea(mainDisplay, xpm_ptr->cached_pixmap, win, drawGC, 0, 0,
2578 scr_w, scr_h, ltx, lty);
2579 } else {
2580 values.function = GXcopy;
2581 values.clip_x_origin = ltx;
2582 values.clip_y_origin = lty;
2583 values.clip_mask = xpm_ptr->clip_mask;
2584 XChangeGC(mainDisplay, drawGC, GCFunction |
2585 GCClipXOrigin | GCClipYOrigin | GCClipMask, &values);
2586
2587 DrawClippedPixmap(xpm_ptr->cached_pixmap, win, drawGC, scr_w, scr_h,
2588 ltx, lty);
2589
2590 values.clip_x_origin = 0;
2591 values.clip_y_origin = 0;
2592 values.clip_mask = None;
2593 XChangeGC(mainDisplay, drawGC,
2594 GCClipXOrigin | GCClipYOrigin | GCClipMask, &values);
2595 if (numClipRecs > 0) {
2596 XSetClipRectangles(mainDisplay, drawGC, 0, 0, clipRecs,
2597 numClipRecs, clipOrdering);
2598 }
2599 }
2600 }
2601 }
2602
PrTgifFindColorIndex(ObjPtr,s)2603 int PrTgifFindColorIndex(ObjPtr, s)
2604 struct ObjRec *ObjPtr;
2605 char *s;
2606 {
2607 int i;
2608
2609 for (i=0; i < maxColors; i++) {
2610 int valid=FALSE;
2611 char *s1=s, *s2=colorMenuItems[i];
2612
2613 if (*s1 == *s2) {
2614 valid = TRUE;
2615 } else if (*s1 >= 'a' && *s1 <= 'z') {
2616 if (*s1+'A'-'a' == *s2) {
2617 valid = TRUE;
2618 }
2619 } else if (*s >= 'A' && *s <= 'Z') {
2620 if (*s1+'a'-'A' == *s2) {
2621 valid = TRUE;
2622 }
2623 }
2624 if (valid && (UtilStrICmp(++s1,++s2) == 0)) {
2625 if (ObjPtr != NULL) {
2626 UtilStrCpyN(ObjPtr->color_str, sizeof(ObjPtr->color_str),
2627 colorMenuItems[i]);
2628 }
2629 return i;
2630 }
2631 }
2632 return INVALID;
2633 }
2634
QuickFindColorIndex(ObjPtr,s,new_alloc,use_default)2635 int QuickFindColorIndex(ObjPtr, s, new_alloc, use_default)
2636 struct ObjRec *ObjPtr;
2637 char *s;
2638 int *new_alloc, use_default;
2639 {
2640 register int i;
2641 XColor exact_def, screen_def;
2642
2643 if (new_alloc != NULL) *new_alloc = FALSE;
2644
2645 if (PRTGIF && cmdLineColor && (prTgifFoundColorInfo ||
2646 !cmdLineOpenDisplay)) {
2647 int color_index=PrTgifFindColorIndex(ObjPtr, s);
2648
2649 if (color_index != INVALID || !cmdLineOpenDisplay) {
2650 return color_index;
2651 }
2652 }
2653 if (ObjPtr != NULL) {
2654 UtilStrCpyN(ObjPtr->color_str, sizeof(ObjPtr->color_str), s);
2655 }
2656 if (colorMenuItems == NULL) {
2657 return INVALID;
2658 }
2659 if (*s == '#') {
2660 if (!TgifParseColor(s, &exact_def)) {
2661 if (use_default) {
2662 sprintf(gszMsgBox,
2663 TgLoadCachedString(CSTID_CANNOT_ALLOC_COLOR_USE_ALT),
2664 s, colorMenuItems[colorIndex]);
2665 if (!PRTGIF) Msg(gszMsgBox);
2666 allocColorFailed = TRUE;
2667 if (ObjPtr != NULL) {
2668 UtilStrCpyN(ObjPtr->color_str, sizeof(ObjPtr->color_str),
2669 colorMenuItems[colorIndex]);
2670 }
2671 return colorIndex;
2672 }
2673 return INVALID;
2674 }
2675 } else {
2676 for (i=0; i < maxColors; i++) {
2677 int valid=FALSE;
2678 char *s1=s, *s2=colorMenuItems[i];
2679
2680 if (*s1 == *s2) {
2681 valid = TRUE;
2682 } else if (*s1 >= 'a' && *s1 <= 'z') {
2683 if (*s1+'A'-'a' == *s2) {
2684 valid = TRUE;
2685 }
2686 } else if (*s >= 'A' && *s <= 'Z') {
2687 if (*s1+'a'-'A' == *s2) {
2688 valid = TRUE;
2689 }
2690 }
2691 if (valid && (UtilStrICmp(++s1,++s2) == 0)) {
2692 if (ObjPtr != NULL) {
2693 UtilStrCpyN(ObjPtr->color_str, sizeof(ObjPtr->color_str),
2694 colorMenuItems[i]);
2695 }
2696 return i;
2697 }
2698 }
2699
2700 if (!TgifParseColor(s, &exact_def)) {
2701 if (use_default) {
2702 sprintf(gszMsgBox,
2703 TgLoadCachedString(CSTID_CANNOT_ALLOC_COLOR_USE_ALT),
2704 s, colorMenuItems[colorIndex]);
2705 if (!PRTGIF) Msg(gszMsgBox);
2706 allocColorFailed = TRUE;
2707 if (ObjPtr != NULL) {
2708 UtilStrCpyN(ObjPtr->color_str, sizeof(ObjPtr->color_str),
2709 colorMenuItems[colorIndex]);
2710 }
2711 return colorIndex;
2712 }
2713 return INVALID;
2714 }
2715 }
2716 for (i=0; i < maxColors; i++) {
2717 if (tgifRequestedColors[i].red == exact_def.red &&
2718 tgifRequestedColors[i].green == exact_def.green &&
2719 tgifRequestedColors[i].blue == exact_def.blue) {
2720 if (ObjPtr != NULL) {
2721 UtilStrCpyN(ObjPtr->color_str, sizeof(ObjPtr->color_str),
2722 colorMenuItems[i]);
2723 }
2724 return i;
2725 }
2726 }
2727
2728 memcpy(&screen_def, &exact_def, sizeof(XColor));
2729
2730 if (!XAllocColor(mainDisplay, mainColormap, &screen_def)) {
2731 Colormap colormap;
2732
2733 if (newColormapUsed) {
2734 if (use_default) {
2735 sprintf(gszMsgBox,
2736 TgLoadCachedString(CSTID_CANNOT_ALLOC_COLOR_USE_ALT),
2737 s, colorMenuItems[colorIndex]);
2738 if (!PRTGIF) Msg(gszMsgBox);
2739 allocColorFailed = TRUE;
2740 if (ObjPtr != NULL) {
2741 UtilStrCpyN(ObjPtr->color_str, sizeof(ObjPtr->color_str),
2742 colorMenuItems[colorIndex]);
2743 }
2744 return colorIndex;
2745 }
2746 return INVALID;
2747 }
2748 colormap = XCopyColormapAndFree(mainDisplay, mainColormap);
2749 mainColormap = colormap;
2750 newColormapUsed = TRUE;
2751 XSetWindowColormap(mainDisplay, mainWindow, mainColormap);
2752 if (!XAllocColor(mainDisplay, mainColormap, &screen_def)) {
2753 if (use_default) {
2754 sprintf(gszMsgBox,
2755 TgLoadCachedString(CSTID_CANNOT_ALLOC_COLOR_USE_ALT),
2756 s, colorMenuItems[colorIndex]);
2757 if (!PRTGIF) Msg(gszMsgBox);
2758 allocColorFailed = TRUE;
2759 if (ObjPtr != NULL) {
2760 UtilStrCpyN(ObjPtr->color_str, sizeof(ObjPtr->color_str),
2761 colorMenuItems[colorIndex]);
2762 }
2763 return colorIndex;
2764 }
2765 return INVALID;
2766 }
2767 }
2768 colorPixels = (int*)realloc(colorPixels, (maxColors+1)*sizeof(int));
2769 xorColorPixels = (int*)realloc(xorColorPixels,
2770 (maxColors+1)*sizeof(int));
2771 colorLayerOn = (int*)realloc(colorLayerOn, (maxColors+1)*sizeof(int));
2772 colorMenuItems = (char**)realloc(colorMenuItems,
2773 (maxColors+1)*sizeof(char*));
2774 colorMenuItems[maxColors] = (char*)malloc((strlen(s)+1)*sizeof(char));
2775 if (colorMenuItems[maxColors] == NULL) FailAllocMessage();
2776 tgifColors = (XColor*)realloc(tgifColors,
2777 (maxColors+1)*sizeof(XColor));
2778 tgifRequestedColors = (XColor*)realloc(tgifRequestedColors,
2779 (maxColors+1)*sizeof(XColor));
2780
2781 colorPixels[maxColors] = screen_def.pixel;
2782 xorColorPixels[maxColors] =
2783 screen_def.pixel ^ GetDrawingBgPixel(INVALID, INVALID);
2784 colorLayerOn[maxColors] = TRUE;
2785 strcpy(colorMenuItems[maxColors], s);
2786 tgifRequestedColors[maxColors].red = exact_def.red;
2787 tgifRequestedColors[maxColors].green = exact_def.green;
2788 tgifRequestedColors[maxColors].blue = exact_def.blue;
2789 tgifColors[maxColors].red = screen_def.red;
2790 tgifColors[maxColors].green = screen_def.green;
2791 tgifColors[maxColors].blue = screen_def.blue;
2792 maxColors++;
2793 *new_alloc = TRUE;
2794
2795 DestroyPinnedMenu(MENU_COLOR);
2796 if (!PRTGIF && colorLayers) {
2797 needToRedrawColorWindow = TRUE;
2798 }
2799 return (maxColors-1);
2800 }
2801
CreateXPmObj(ImageW,ImageH,W,H,pixmap,image,bitmap,bitmap_image,ncolors,chars_per_pixel,first_pixel_is_bg,color_char,color_str,pixels,xpm_data)2802 struct ObjRec *CreateXPmObj(ImageW, ImageH, W, H, pixmap, image, bitmap,
2803 bitmap_image, ncolors, chars_per_pixel, first_pixel_is_bg, color_char,
2804 color_str, pixels, xpm_data)
2805 int ImageW, ImageH, W, H;
2806 Pixmap pixmap, bitmap;
2807 XImage *image, *bitmap_image;
2808 int ncolors, chars_per_pixel, first_pixel_is_bg;
2809 char *color_char;
2810 char **color_str;
2811 int *pixels;
2812 char *xpm_data;
2813 {
2814 struct XPmRec *xpm_ptr;
2815 struct ObjRec *obj_ptr;
2816
2817 xpm_ptr = (struct XPmRec *)malloc(sizeof(struct XPmRec));
2818 if (xpm_ptr == NULL) FailAllocMessage();
2819 memset(xpm_ptr, 0, sizeof(struct XPmRec));
2820
2821 xpm_ptr->pixmap = pixmap;
2822 xpm_ptr->image = image;
2823 xpm_ptr->bitmap = bitmap;
2824 xpm_ptr->bitmap_image = bitmap_image;
2825 xpm_ptr->image_w = ImageW;
2826 xpm_ptr->image_h = ImageH;
2827 xpm_ptr->data = xpm_data;
2828
2829 xpm_ptr->fill = objFill;
2830 xpm_ptr->flip = xpm_ptr->cached_flip = 0;
2831 xpm_ptr->cached_zoom = 0;
2832 xpm_ptr->cached_pixmap = None;
2833 xpm_ptr->cached_bitmap = None;
2834 xpm_ptr->cached_w = xpm_ptr->cached_h = 0;
2835 xpm_ptr->cached_color = (-1);
2836
2837 xpm_ptr->ncolors = ncolors;
2838 xpm_ptr->chars_per_pixel = chars_per_pixel;
2839 xpm_ptr->first_pixel_is_bg = first_pixel_is_bg;
2840 xpm_ptr->color_char = color_char;
2841 xpm_ptr->color_str = color_str;
2842 xpm_ptr->pixels = pixels;
2843 if (colorDisplay || ncolors == (-1)) {
2844 xpm_ptr->red = xpm_ptr->green = xpm_ptr->blue = NULL;
2845 } else {
2846 int i;
2847
2848 xpm_ptr->red = (int*)malloc(ncolors*sizeof(int));
2849 xpm_ptr->green = (int*)malloc(ncolors*sizeof(int));
2850 xpm_ptr->blue = (int*)malloc(ncolors*sizeof(int));
2851 if (xpm_ptr->red==NULL || xpm_ptr->green==NULL || xpm_ptr->blue==NULL) {
2852 FailAllocMessage();
2853 }
2854 for (i=0; i < ncolors; i++) {
2855 int new_alloc;
2856 int index=QuickFindColorIndex(NULL, color_str[i], &new_alloc, TRUE);
2857
2858 xpm_ptr->red[i] =
2859 (int)(10000*((int)tgifRequestedColors[index].red)/maxRGB);
2860 xpm_ptr->green[i] =
2861 (int)(10000*((int)tgifRequestedColors[index].green)/maxRGB);
2862 xpm_ptr->blue[i] =
2863 (int)(10000*((int)tgifRequestedColors[index].blue)/maxRGB);
2864 }
2865 }
2866 xpm_ptr->clip_mask = None;
2867
2868 obj_ptr = (struct ObjRec *)malloc(sizeof(struct ObjRec));
2869 if (obj_ptr == NULL) FailAllocMessage();
2870 memset(obj_ptr, 0, sizeof(struct ObjRec));
2871
2872 obj_ptr->bbox.ltx = obj_ptr->obbox.ltx = obj_ptr->x = drawOrigX;
2873 obj_ptr->bbox.lty = obj_ptr->obbox.lty = obj_ptr->y = drawOrigY;
2874 obj_ptr->bbox.rbx = obj_ptr->obbox.rbx = W + drawOrigX;
2875 obj_ptr->bbox.rby = obj_ptr->obbox.rby = H + drawOrigY;
2876 obj_ptr->type = OBJ_XPM;
2877 obj_ptr->color = colorIndex;
2878 if (mainDisplay != NULL) {
2879 UtilStrCpyN(obj_ptr->color_str, sizeof(obj_ptr->color_str),
2880 colorMenuItems[colorIndex]);
2881 }
2882 obj_ptr->id = objId++;
2883 obj_ptr->dirty = FALSE;
2884 obj_ptr->rotation = 0;
2885 obj_ptr->locked = FALSE;
2886 obj_ptr->detail.xpm = xpm_ptr;
2887 obj_ptr->fattr = obj_ptr->lattr = NULL;
2888 obj_ptr->ctm = NULL;
2889 obj_ptr->invisible = FALSE;
2890
2891 return obj_ptr;
2892 }
2893
2894 static
CopyXPmProperties(DestXpmObj,SrcXpmObj)2895 void CopyXPmProperties(DestXpmObj, SrcXpmObj)
2896 struct ObjRec *DestXpmObj, *SrcXpmObj;
2897 {
2898 struct XPmRec *dest_xpm_ptr=DestXpmObj->detail.xpm;
2899 struct XPmRec *src_xpm_ptr=SrcXpmObj->detail.xpm;
2900
2901 dest_xpm_ptr->fill = src_xpm_ptr->fill;
2902 DestXpmObj->color = SrcXpmObj->color;
2903 memcpy(DestXpmObj->color_str, SrcXpmObj->color_str,
2904 sizeof(DestXpmObj->color_str));
2905 }
2906
2907 static
FinishBreakUpXPixmap(obj_ptr,cols_and_rows,cols,rows)2908 int FinishBreakUpXPixmap(obj_ptr, cols_and_rows, cols, rows)
2909 struct ObjRec *obj_ptr;
2910 int cols_and_rows, cols, rows;
2911 {
2912 struct XPmRec *xpm_ptr=obj_ptr->detail.xpm;
2913 int y, image_w=xpm_ptr->image_w, image_h=xpm_ptr->image_h;
2914 int chunk_w=0, chunk_h=0, total_chunks=0;
2915 int orig_x=obj_ptr->x, orig_y=obj_ptr->y;
2916 int ncolors, chars_per_pixel, first_pixel_is_bg;
2917 char tmp_fname[MAXPATHLENGTH];
2918
2919 if (MkTempFile(tmp_fname, sizeof(tmp_fname), tmpDir, TOOL_NAME) == NULL) {
2920 return FALSE;
2921 }
2922 ncolors = xpm_ptr->ncolors;
2923 chars_per_pixel = xpm_ptr->chars_per_pixel;
2924 first_pixel_is_bg = xpm_ptr->first_pixel_is_bg;
2925
2926 if (cols_and_rows) {
2927 chunk_w = (int)(image_w / cols);
2928 chunk_h = (int)(image_h / rows);
2929 } else {
2930 chunk_w = cols;
2931 chunk_h = rows;
2932 }
2933 for (y=0; y < image_h; y += chunk_h) {
2934 int h=min(image_h-y,chunk_h), x;
2935
2936 for (x=0; x < image_w; x += chunk_w) {
2937 int w=min(image_w-x,chunk_w), i, *pixels=NULL;
2938 char *color_char=NULL, **color_str=NULL, *xpm_data=NULL;
2939 struct ObjRec *new_obj_ptr=NULL;
2940 Pixmap dest_pixmap=None, dest_bitmap=None;
2941 XImage *dest_image=NULL, *dest_bitmap_image=NULL;
2942
2943 if (w <= 0 || h <= 0 ||
2944 !ExtractPixmap(xpm_ptr->pixmap, xpm_ptr->image, xpm_ptr->bitmap,
2945 xpm_ptr->bitmap_image, x, y, w, h, &dest_pixmap, &dest_image,
2946 &dest_bitmap, &dest_bitmap_image)) {
2947 continue;
2948 }
2949 if ((xpm_ptr->real_type == XPM_JPEG ||
2950 xpm_ptr->real_type == PPM_TRUE) &&
2951 fullTrueColorMode && HasZlibSupport()) {
2952 if (DumpXImageToPpmFile(dest_image, w, h, tmp_fname, TRUE)) {
2953 char deflated_fname[MAXPATHLENGTH];
2954 unsigned int data_size=0;
2955 char *ppm_data=NULL;
2956
2957 snprintf(deflated_fname, sizeof(deflated_fname), "%s.ppm.z",
2958 tmp_fname);
2959 ppm_data = ReadFileIntoBuf(deflated_fname, &data_size);
2960 unlink(deflated_fname);
2961 unlink(tmp_fname);
2962 if (ppm_data) {
2963 new_obj_ptr = CreatePpmTrueObjFromImage(dest_image, w, h,
2964 ppm_data, data_size);
2965 }
2966 }
2967 if (dest_pixmap != None) XFreePixmap(mainDisplay, dest_pixmap);
2968 if (dest_bitmap != None) XFreePixmap(mainDisplay, dest_bitmap);
2969 if (dest_image != NULL) XDestroyImage(dest_image);
2970 if (dest_bitmap_image != NULL) XDestroyImage(dest_bitmap_image);
2971 dest_pixmap = dest_bitmap = None;
2972 dest_image = dest_bitmap_image = NULL;
2973 if (new_obj_ptr != NULL) {
2974 total_chunks++;
2975 }
2976 } else {
2977 pixels = (int*)malloc(ncolors*sizeof(int));
2978 if (pixels == NULL) FailAllocMessage();
2979 memcpy(pixels, xpm_ptr->pixels, (size_t)(ncolors*sizeof(int)));
2980
2981 color_char = (char*)malloc(ncolors*chars_per_pixel*sizeof(char));
2982 if (color_char == NULL) FailAllocMessage();
2983 memcpy(color_char, xpm_ptr->color_char,
2984 (size_t)(ncolors*chars_per_pixel*sizeof(char)));
2985
2986 color_str = (char**)malloc(ncolors*sizeof(char*));
2987 if (color_str == NULL) FailAllocMessage();
2988 for (i=0; i < ncolors; i++) {
2989 if ((color_str[i]=UtilStrDup(xpm_ptr->color_str[i])) == NULL) {
2990 FailAllocMessage();
2991 }
2992 }
2993 total_chunks++;
2994 new_obj_ptr = CreateXPmObj(w, h, w, h, dest_pixmap, dest_image,
2995 dest_bitmap, dest_bitmap_image, ncolors, chars_per_pixel,
2996 first_pixel_is_bg, color_char, color_str, pixels, xpm_data);
2997 CopyXPmProperties(new_obj_ptr, obj_ptr);
2998 }
2999 if (new_obj_ptr != NULL) {
3000 AdjObjBBox(new_obj_ptr);
3001 MoveObj(new_obj_ptr, orig_x+x, orig_y+y);
3002 AddObj(NULL, topObj, new_obj_ptr);
3003 }
3004 }
3005 }
3006 if (total_chunks > 0) {
3007 int i;
3008
3009 RemoveAllSel();
3010 UnlinkObj(obj_ptr);
3011 FreeObj(obj_ptr);
3012
3013 for (i=0, obj_ptr=topObj; obj_ptr != NULL && i < total_chunks; i++,
3014 obj_ptr=obj_ptr->next) {
3015 AddObjIntoSel(obj_ptr, botSel, NULL, &topSel, &botSel);
3016 }
3017 }
3018 return (total_chunks > 0);
3019 }
3020
BreakUpXPixmap(obj_ptr,cols_and_rows,cols,rows)3021 void BreakUpXPixmap(obj_ptr, cols_and_rows, cols, rows)
3022 struct ObjRec *obj_ptr;
3023 int cols_and_rows, cols, rows;
3024 {
3025 HighLightReverse();
3026 PrepareToReplaceAnObj(obj_ptr);
3027 if (FinishBreakUpXPixmap(obj_ptr, cols_and_rows, cols, rows)) {
3028 UpdSelBBox();
3029 RecordCmd(CMD_ONE_TO_MANY, NULL, topSel, botSel, numObjSelected);
3030 SetFileModified(TRUE);
3031 justDupped = FALSE;
3032 } else {
3033 AbortPrepareCmd(CMD_REPLACE);
3034 }
3035 HighLightForward();
3036 }
3037
3038 static
SaveXPmPixels(FP,xpm_ptr,pixmap,image,bitmap,bitmap_image,w,h,ncolors,chars_per_pixel,color_char,pixels)3039 void SaveXPmPixels(FP, xpm_ptr, pixmap, image, bitmap, bitmap_image, w, h,
3040 ncolors, chars_per_pixel, color_char, pixels)
3041 FILE *FP;
3042 struct XPmRec *xpm_ptr;
3043 Pixmap pixmap, bitmap;
3044 XImage **image, **bitmap_image;
3045 int w, h, ncolors, chars_per_pixel, *pixels;
3046 char *color_char;
3047 {
3048 register int j, data, index, i, k;
3049 char *xpm_data=NULL;
3050
3051 if (*image == NULL) {
3052 *image = XGetImage(mainDisplay, pixmap, 0, 0, w, h, AllPlanes, ZPixmap);
3053 if (*image == NULL) {
3054 sprintf(gszMsgBox, "%s\n\n%s",
3055 TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM),
3056 TgLoadString(STID_SAVED_FILE_MAY_BE_CORRUPTED));
3057 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3058 return;
3059 }
3060 }
3061 if (*bitmap_image == NULL) {
3062 *bitmap_image = XGetImage(mainDisplay, bitmap, 0, 0, w, h, 1, ZPixmap);
3063 if (*bitmap_image == NULL) {
3064 sprintf(gszMsgBox, "%s\n\n%s",
3065 TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM),
3066 TgLoadString(STID_SAVED_FILE_MAY_BE_CORRUPTED));
3067 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3068 return;
3069 }
3070 }
3071 xpm_data = xpm_ptr->data;
3072 for (i=0; i < h; i++) {
3073 if (fprintf(FP, " \"") == EOF) writeFileFailed = TRUE;
3074 for (j=0; j < w; j++) {
3075 if (!colorDisplay && xpm_data != NULL && xpm_ptr->red != NULL) {
3076 for (k=0; k < chars_per_pixel; k++) {
3077 if (fprintf(FP, "%c", xpm_data[j*chars_per_pixel+k]) == EOF) {
3078 writeFileFailed = TRUE;
3079 }
3080 }
3081 } else {
3082 if (XGetPixel(*bitmap_image, j, i) != 0) {
3083 data = XGetPixel(*image,j,i);
3084 } else {
3085 data = (-1);
3086 }
3087 index = XPmLookUp(data, INVALID, NULL, NULL);
3088 if (index == INVALID) {
3089 sprintf(gszMsgBox,
3090 TgLoadString(STID_UNRECOG_GIVEN_PIXEL_VAL_PRINT),
3091 j, i, data, (long)data);
3092 Msg(gszMsgBox);
3093 return;
3094 }
3095 for (k=0; k < chars_per_pixel; k++) {
3096 if (fprintf(FP, "%c", color_char[index*chars_per_pixel+k]) ==
3097 EOF) {
3098 writeFileFailed = TRUE;
3099 }
3100 }
3101 }
3102 }
3103 if (xpm_data != NULL) xpm_data += w*chars_per_pixel;
3104 if (i == h-1) {
3105 if (fprintf(FP, "\"],") == EOF) writeFileFailed = TRUE;
3106 } else {
3107 if (fprintf(FP, "\",\n") == EOF) writeFileFailed = TRUE;
3108 }
3109 }
3110 }
3111
3112 static
WritePpmTrueData(FP,xpm_ptr)3113 int WritePpmTrueData(FP, xpm_ptr)
3114 FILE *FP;
3115 struct XPmRec *xpm_ptr;
3116 {
3117 char *psz=xpm_ptr->ppm_data;
3118 int total_bytes_to_write=xpm_ptr->ppm_data_size;
3119
3120 while (total_bytes_to_write > 0) {
3121 int bytes_to_read=min(48, total_bytes_to_write), bytes_to_write=0;
3122 char out_buf[65];
3123
3124 bytes_to_write = (bytes_to_read / 3);
3125 if ((bytes_to_read % 3) == 0) {
3126 bytes_to_write = bytes_to_write << 2;
3127 } else {
3128 bytes_to_write = (bytes_to_write+1) << 2;
3129 }
3130 *out_buf = '\0';
3131 DoBase64Encode(psz, bytes_to_read, out_buf);
3132 if (fprintf(FP, " \"") == EOF) writeFileFailed = TRUE;
3133 if (fwrite(out_buf, 1, bytes_to_write, FP) != bytes_to_write) {
3134 writeFileFailed = TRUE;
3135 }
3136 psz += bytes_to_read;
3137 total_bytes_to_write -= bytes_to_read;
3138 if (total_bytes_to_write > 0) {
3139 if (fprintf(FP, "\",\n") == EOF) writeFileFailed = TRUE;
3140 } else {
3141 if (fprintf(FP, "\"],[\n") == EOF) writeFileFailed = TRUE;
3142 }
3143 }
3144 if (xpm_ptr->ppm_mask_data != NULL) {
3145 TgAssert(FALSE, "xpm_ptr->ppm_mask_data != NULL in WritePpmTrueData()",
3146 NULL);
3147 }
3148 if (fprintf(FP, " ],") == EOF) writeFileFailed = TRUE;
3149
3150 return TRUE;
3151 }
3152
3153 static
ReadPpmTrueData(fp,ppm_data_size)3154 char *ReadPpmTrueData(fp, ppm_data_size)
3155 FILE *fp;
3156 int ppm_data_size;
3157 {
3158 char line[64+20], *write_ptr=NULL;
3159 char *buf_return=(char*)malloc(ppm_data_size+1);
3160
3161 if (buf_return == NULL) FailAllocMessage();
3162 write_ptr = buf_return;
3163 while (fgets(line, sizeof(line), fp) != NULL) {
3164 int len=strlen(line), bytes_converted=0;
3165 char *s=NULL, buf[64+20], out_buf[49];
3166
3167 scanLineNum++;
3168 if (len > 0 && line[len-1] != '\n') {
3169 sprintf(gszMsgBox, TgLoadString(STID_BAD_LINE_READING_GIVEN_OBJ),
3170 "ppm_true");
3171 if (PRTGIF) {
3172 fprintf(stderr, "%s\n", gszMsgBox);
3173 } else {
3174 Msg(gszMsgBox);
3175 }
3176 UtilFree(buf_return);
3177 return NULL;
3178 }
3179 s = FindChar((int)'"', line);
3180 s = ParseStr(s, (int)'"', buf, sizeof(buf));
3181 len = strlen(buf);
3182 if (len > 64 || (len & 0x3) != 0) {
3183 sprintf(gszMsgBox, TgLoadString(STID_BAD_LINE_READING_GIVEN_OBJ),
3184 "ppm_true");
3185 if (PRTGIF) {
3186 fprintf(stderr, "%s\n", gszMsgBox);
3187 } else {
3188 Msg(gszMsgBox);
3189 }
3190 UtilFree(buf_return);
3191 return NULL;
3192 }
3193 /* bytes_converted = (len >> 2) * 3; */
3194 bytes_converted = DoBase64Decode(buf, len, out_buf);
3195 ppm_data_size -= bytes_converted;
3196 if (ppm_data_size < 0) {
3197 sprintf(gszMsgBox, TgLoadString(STID_INSUF_DATA_READING_GIVEN_OBJ),
3198 "ppm_true");
3199 if (PRTGIF) {
3200 fprintf(stderr, "%s\n", gszMsgBox);
3201 } else {
3202 Msg(gszMsgBox);
3203 }
3204 UtilFree(buf_return);
3205 return NULL;
3206 }
3207 memcpy(write_ptr, out_buf, bytes_converted);
3208 write_ptr += bytes_converted;
3209 if (ppm_data_size == 0) break;
3210 }
3211 if (ppm_data_size != 0) {
3212 sprintf(gszMsgBox, TgLoadString(STID_BAD_LINE_READING_GIVEN_OBJ),
3213 "ppm_true");
3214 if (PRTGIF) {
3215 fprintf(stderr, "%s\n", gszMsgBox);
3216 } else {
3217 Msg(gszMsgBox);
3218 }
3219 UtilFree(buf_return);
3220 return NULL;
3221 }
3222 return buf_return;
3223 }
3224
3225 static
ReadPpmTrueMask(fp,ppm_mask_size)3226 char *ReadPpmTrueMask(fp, ppm_mask_size)
3227 FILE *fp;
3228 int ppm_mask_size;
3229 {
3230 char line[64+20];
3231
3232 while (fgets(line, sizeof(line), fp) != NULL) {
3233 /* this feature has not been implemented yet */
3234 break;
3235 }
3236 return NULL;
3237 }
3238
SaveXPmObj(FP,ObjPtr)3239 void SaveXPmObj(FP, ObjPtr)
3240 FILE *FP;
3241 struct ObjRec *ObjPtr;
3242 {
3243 int ltx, lty, rbx, rby, fill, ncolors, *pixels=NULL;
3244 int chars_per_pixel, first_pixel_is_bg, image_w, image_h;
3245 int compressed=FALSE, real_type=0, linked_jpeg=FALSE, jpeg=FALSE;
3246 int ppm_z=FALSE;
3247 struct XPmRec *xpm_ptr=ObjPtr->detail.xpm;
3248 char *color_char=NULL, **color_str=NULL, *jpeg_filename=NULL;
3249
3250 ltx = ObjPtr->obbox.ltx; lty = ObjPtr->obbox.lty;
3251 rbx = ObjPtr->obbox.rbx; rby = ObjPtr->obbox.rby;
3252 image_w = xpm_ptr->image_w;
3253 image_h = xpm_ptr->image_h;
3254 fill = xpm_ptr->fill;
3255 ncolors = xpm_ptr->ncolors;
3256 chars_per_pixel = xpm_ptr->chars_per_pixel;
3257 first_pixel_is_bg = xpm_ptr->first_pixel_is_bg;
3258 color_char = xpm_ptr->color_char;
3259 color_str = xpm_ptr->color_str;
3260 pixels = xpm_ptr->pixels;
3261
3262 real_type = xpm_ptr->real_type;
3263 linked_jpeg = xpm_ptr->linked_jpeg;
3264 jpeg_filename = xpm_ptr->filename;
3265
3266 /* only doing linked JPEG */
3267 jpeg = (real_type == XPM_JPEG && linked_jpeg && jpeg_filename != NULL);
3268 ppm_z = (real_type == PPM_TRUE);
3269
3270 if (!colorDisplay && xpm_ptr->red == NULL && !shownXPmErrorMessage) {
3271 MsgBox(TgLoadString(STID_CANT_SAVE_XPM_ON_BW_DPY), TOOL_NAME, INFO_MB);
3272 shownXPmErrorMessage = TRUE;
3273 return;
3274 }
3275 if (jpeg) {
3276 if (fprintf(FP, "jpeg('%s','',", colorMenuItems[ObjPtr->color]) == EOF) {
3277 writeFileFailed = TRUE;
3278 }
3279 } else if (ppm_z) {
3280 if (fprintf(FP, "ppm_true('%s',", colorMenuItems[ObjPtr->color]) == EOF) {
3281 writeFileFailed = TRUE;
3282 }
3283 if (xpm_ptr->has_transparent_color) {
3284 if (fprintf(FP, "'#%02x%02x%02x',1,",
3285 xpm_ptr->transparent_color[0], xpm_ptr->transparent_color[1],
3286 xpm_ptr->transparent_color[2]) == EOF) {
3287 writeFileFailed = TRUE;
3288 }
3289 } else {
3290 if (fprintf(FP, "'#ffffff',0,") == EOF) {
3291 writeFileFailed = TRUE;
3292 }
3293 }
3294 } else {
3295 if (fprintf(FP, "xpm('%s','',", colorMenuItems[ObjPtr->color]) == EOF) {
3296 writeFileFailed = TRUE;
3297 }
3298 }
3299 if (ppm_z) {
3300 if (fprintf(FP,
3301 "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,",
3302 ltx, lty, rbx, rby, ObjPtr->id, ObjPtr->rotation, image_w,
3303 image_h) == EOF) {
3304 writeFileFailed = TRUE;
3305 }
3306 } else {
3307 if (fprintf(FP,
3308 "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,",
3309 ltx, lty, rbx, rby, fill, ncolors, chars_per_pixel,
3310 first_pixel_is_bg, ObjPtr->id, ObjPtr->rotation, image_w,
3311 image_h) == EOF) {
3312 writeFileFailed = TRUE;
3313 }
3314 }
3315 if (jpeg) {
3316 if (fprintf(FP,
3317 "0,%1d,%1d,%1d,%1d,%1d,%1d,%1d,\n \"%s\",",
3318 xpm_ptr->flip, ObjPtr->locked, compressed,
3319 ObjPtr->ctm!=NULL, ObjPtr->invisible, real_type, linked_jpeg,
3320 jpeg_filename) == EOF) {
3321 writeFileFailed = TRUE;
3322 }
3323 } else if (ppm_z) {
3324 if (fprintf(FP,
3325 "0,%1d,%1d,%1d,%1d,%1d,%1d,%1d,",
3326 xpm_ptr->flip, ObjPtr->locked, ObjPtr->ctm!=NULL, ObjPtr->invisible,
3327 xpm_ptr->ppm_data_compress, xpm_ptr->ppm_data_size,
3328 xpm_ptr->ppm_mask_size) == EOF) {
3329 writeFileFailed = TRUE;
3330 }
3331 } else {
3332 if (fprintf(FP,
3333 "0,%1d,%1d,%1d,%1d,%1d,",
3334 xpm_ptr->flip, ObjPtr->locked, compressed,
3335 ObjPtr->ctm!=NULL, ObjPtr->invisible) == EOF) {
3336 writeFileFailed = TRUE;
3337 }
3338 }
3339 if (ObjPtr->ctm != NULL && fprintf(FP,
3340 "[\n %1d,%1d,%1d,%1d,%1d,%1d,%g,%g,%g,%g,%1d,%1d],",
3341 ObjPtr->x, ObjPtr->y,
3342 ObjPtr->orig_obbox.ltx, ObjPtr->orig_obbox.lty,
3343 ObjPtr->orig_obbox.rbx, ObjPtr->orig_obbox.rby,
3344 ObjPtr->ctm->m[CTM_SX], ObjPtr->ctm->m[CTM_SIN],
3345 ObjPtr->ctm->m[CTM_MSIN], ObjPtr->ctm->m[CTM_SY],
3346 ObjPtr->ctm->t[CTM_TX], ObjPtr->ctm->t[CTM_TY]) == EOF) {
3347 writeFileFailed = TRUE;
3348 }
3349 if (jpeg) {
3350 /* nothing to write here */
3351 } else if (ppm_z) {
3352 if (fprintf(FP, "[\n") == EOF) writeFileFailed = TRUE;
3353 if (!WritePpmTrueData(FP, xpm_ptr)) {
3354 return;
3355 }
3356 } else {
3357 if (fprintf(FP, "[\n") == EOF) writeFileFailed = TRUE;
3358 if (!colorDisplay && xpm_ptr->red != NULL) {
3359 if (!BuildXPmBuckets(ncolors, NULL, NULL, chars_per_pixel,
3360 color_char, NULL)) {
3361 return;
3362 }
3363 } else {
3364 if (!BuildXPmBuckets(ncolors, pixels, NULL, INVALID, NULL, NULL)) {
3365 return;
3366 }
3367 }
3368 SaveXPmColors(FP, ObjPtr->color, xpm_ptr, ncolors, chars_per_pixel,
3369 color_char, color_str, pixels);
3370 SaveXPmPixels(FP, xpm_ptr, xpm_ptr->pixmap, &(xpm_ptr->image),
3371 xpm_ptr->bitmap, &(xpm_ptr->bitmap_image),
3372 image_w, image_h, ncolors, chars_per_pixel, color_char, pixels);
3373 }
3374 if (serializingFile) SaveCreatorID(FP, ObjPtr, " ");
3375 SaveAttrs(FP, ObjPtr->lattr);
3376 if (fprintf(FP, ")") == EOF) writeFileFailed = TRUE;
3377 }
3378
3379 static
FreeAuxData(fp,ncolors,color_char,color_str,p_pixels,pixels_used,p_pixmap,p_image,p_bitmap,p_bitmap_image)3380 void FreeAuxData(fp, ncolors, color_char, color_str,
3381 p_pixels, pixels_used, p_pixmap, p_image, p_bitmap, p_bitmap_image)
3382 FILE *fp;
3383 int ncolors;
3384 char *color_char, **color_str;
3385 int **p_pixels, *pixels_used;
3386 Pixmap *p_pixmap, *p_bitmap;
3387 XImage **p_image, **p_bitmap_image;
3388 {
3389 register int i;
3390
3391 for (i = 0; i < ncolors; i++) free(color_str[i]);
3392 free(color_char);
3393 free(color_str);
3394 if (p_pixels != NULL && *p_pixels != NULL) free(*p_pixels);
3395 if (pixels_used != NULL) free(pixels_used);
3396 if (p_pixmap != NULL && *p_pixmap != None) {
3397 XFreePixmap(mainDisplay, *p_pixmap);
3398 }
3399 if (p_bitmap != NULL && *p_bitmap != None){
3400 XFreePixmap(mainDisplay, *p_bitmap);
3401 }
3402 if (p_image != NULL && *p_image != NULL) XDestroyImage(*p_image);
3403 if (p_bitmap_image != NULL && *p_bitmap_image != NULL) {
3404 XDestroyImage(*p_bitmap_image);
3405 }
3406 fclose(fp);
3407 }
3408
MyReadPixmapFile(file_name,image_w_return,image_h_return,w_return,h_return,pixmap_return,image_return,bitmap_return,bitmap_image_return,ncolors_return,chars_per_pixel_return,first_pixel_is_bg_return,color_char,color_str,pixels,xpm_data)3409 int MyReadPixmapFile(file_name, image_w_return, image_h_return, w_return,
3410 h_return, pixmap_return, image_return, bitmap_return, bitmap_image_return,
3411 ncolors_return, chars_per_pixel_return, first_pixel_is_bg_return,
3412 color_char, color_str, pixels, xpm_data)
3413 char *file_name;
3414 int *image_w_return, *image_h_return, *w_return, *h_return;
3415 int *ncolors_return;
3416 int *chars_per_pixel_return, *first_pixel_is_bg_return;
3417 Pixmap *pixmap_return, *bitmap_return;
3418 XImage **image_return, **bitmap_image_return;
3419 char **color_char, ***color_str;
3420 int **pixels;
3421 char **xpm_data;
3422 {
3423 register int j, k;
3424 register char *c_ptr;
3425 FILE *fp;
3426 char inbuf[MAXSTRING], *line, s[MAXSTRING];
3427 char mag_spec[MAXSTRING], *xpm_data_ptr=NULL;
3428 int i, len, format, found=FALSE, index, saved_max_colors, xpm_version=1;
3429 int x, y, w, h, chars_per_pixel, new_alloc, image_w=0, image_h=0;
3430 int *pixels_used=NULL, bg_pixel;
3431 float mag=(float)0;
3432
3433 myReadTransparentPixmap = FALSE;
3434
3435 if (xpm_data != NULL) *xpm_data = NULL;
3436 gnNumNewColorsInPixmapFile = 0;
3437
3438 if ((fp=fopen(file_name, "r")) == NULL) return BitmapOpenFailed;
3439
3440 saved_max_colors = maxColors;
3441 while (fgets(inbuf, MAXSTRING, fp) != NULL) {
3442 if (strncmp(inbuf, "#define ", 8) == 0) {
3443 xpm_version = 1;
3444 found = TRUE;
3445 break;
3446 } else if (strncmp(inbuf, "/* XPM */", 9) == 0) {
3447 xpm_version = 3;
3448 found = TRUE;
3449 break;
3450 }
3451 }
3452 if (!found) return BitmapFileInvalid;
3453
3454 if (xpm_version == 1) {
3455 c_ptr = FindChar((int)' ', inbuf);
3456 c_ptr = ParseStr(c_ptr, (int)' ', s, sizeof(s));
3457 len = strlen(s);
3458 if (len <= 7 || strcmp(&s[len-7], "_format") != 0) {
3459 return BitmapFileInvalid;
3460 }
3461 sscanf(c_ptr, "%d", &format);
3462 if (format != 1) {
3463 sprintf(gszMsgBox, TgLoadString(STID_CANT_IMPORT_GIVEN_FORMAT_XPM),
3464 format);
3465 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3466 return BitmapFileInvalid;
3467 }
3468 if (fgets(inbuf, MAXSTRING, fp)==NULL) return BitmapFileInvalid;
3469 c_ptr = FindChar((int)' ', inbuf);
3470 c_ptr = ParseStr(c_ptr, (int)' ', s, sizeof(s));
3471 len = strlen(s);
3472 if (len <= 6 || strcmp(&s[len-6], "_width") != 0) {
3473 return BitmapFileInvalid;
3474 }
3475 sscanf(c_ptr, "%d", &image_w);
3476 if (image_w_return != NULL) *image_w_return = image_w;
3477
3478 if (fgets(inbuf, MAXSTRING, fp)==NULL) return BitmapFileInvalid;
3479 c_ptr = FindChar((int)' ', inbuf);
3480 c_ptr = ParseStr(c_ptr, (int)' ', s, sizeof(s));
3481 len = strlen(s);
3482 if (len <= 7 || strcmp(&s[len-7], "_height") != 0) {
3483 return BitmapFileInvalid;
3484 }
3485 sscanf(c_ptr, "%d", &image_h);
3486 if (image_h_return != NULL) *image_h_return = image_h;
3487
3488 if (fgets(inbuf, MAXSTRING, fp)==NULL) return BitmapFileInvalid;
3489 c_ptr = FindChar((int)' ', inbuf);
3490 c_ptr = ParseStr(c_ptr, (int)' ', s, sizeof(s));
3491 len = strlen(s);
3492 if (len <= 8 || strcmp(&s[len-8], "_ncolors") != 0) {
3493 return BitmapFileInvalid;
3494 }
3495 sscanf(c_ptr, "%d", ncolors_return);
3496
3497 if (fgets(inbuf, MAXSTRING, fp)==NULL) return BitmapFileInvalid;
3498 c_ptr = FindChar((int)' ', inbuf);
3499 c_ptr = ParseStr(c_ptr, (int)' ', s, sizeof(s));
3500 len = strlen(s);
3501 if (len <= 16 || strcmp(&s[len-16], "_chars_per_pixel") != 0) {
3502 return BitmapFileInvalid;
3503 }
3504 sscanf(c_ptr, "%d", &chars_per_pixel);
3505 if (chars_per_pixel_return != NULL) {
3506 *chars_per_pixel_return = chars_per_pixel;
3507 }
3508 if (chars_per_pixel > 2) {
3509 sprintf(gszMsgBox, TgLoadString(STID_CANT_IMPORT_GIVEN_CPP_XPM),
3510 chars_per_pixel);
3511 Msg(gszMsgBox);
3512 return BitmapFileInvalid;
3513 }
3514
3515 if (fgets(inbuf, MAXSTRING, fp)==NULL) return BitmapFileInvalid;
3516 len = strlen(inbuf);
3517 if (len <= 27 || strncmp(inbuf, "static char *", 13) != 0 ||
3518 strncmp(&inbuf[len-14], "_colors[] = {\n", 14) != 0) {
3519 return BitmapFileInvalid;
3520 }
3521 } else {
3522 /* xpm_version is 3 */
3523 found = FALSE;
3524 while (fgets(inbuf, MAXSTRING, fp) != NULL) {
3525 if (*inbuf == '"') {
3526 found = TRUE;
3527 break;
3528 }
3529 }
3530 if (!found) return BitmapFileInvalid;
3531 c_ptr = &inbuf[1];
3532 if (sscanf(c_ptr, "%d %d %d %d", &image_w, &image_h,
3533 ncolors_return, &chars_per_pixel) != 4) {
3534 return BitmapFileInvalid;
3535 }
3536 if (image_w_return != NULL) *image_w_return = image_w;
3537 if (image_h_return != NULL) *image_h_return = image_h;
3538 if (chars_per_pixel_return != NULL) {
3539 *chars_per_pixel_return = chars_per_pixel;
3540 }
3541 }
3542
3543 *color_char =
3544 (char*)malloc((*ncolors_return)*(chars_per_pixel)*sizeof(char)+1);
3545 *color_str = (char**)malloc((*ncolors_return)*sizeof(char*));
3546 if (color_char == NULL || color_str == NULL) FailAllocMessage();
3547 if (pixels != NULL) {
3548 *pixels = (int*)malloc((*ncolors_return)*sizeof(int));
3549 pixels_used = (int*)malloc((*ncolors_return)*sizeof(int));
3550 if (*pixels == NULL || pixels_used == NULL) FailAllocMessage();
3551 memset(pixels_used, 0, (*ncolors_return)*sizeof(int));
3552 }
3553 if (pixmap_return != NULL) *pixmap_return = None;
3554 if (bitmap_return != NULL) *bitmap_return = None;
3555 if (image_return != NULL) *image_return = NULL;
3556 if (bitmap_image_return != NULL) *bitmap_image_return = NULL;
3557 if (first_pixel_is_bg_return != NULL) *first_pixel_is_bg_return = FALSE;
3558
3559 bg_pixel = GetDrawingBgPixel(INVALID, INVALID);
3560 if (xpm_version == 1) {
3561 for (i = 0; i < *ncolors_return; i++) {
3562 if (fgets(inbuf, MAXSTRING, fp) == NULL) {
3563 FreeAuxData(fp, i, *color_char, *color_str, pixels, pixels_used,
3564 pixmap_return, image_return, bitmap_return,
3565 bitmap_image_return);
3566 return BitmapFileInvalid;
3567 }
3568 c_ptr = FindChar((int)'"', inbuf);
3569 for (j = 0; j < chars_per_pixel; j++) {
3570 (*color_char)[i*(chars_per_pixel)+j] = c_ptr[j];
3571 }
3572 if (guessXPmBgColor && i == 0 &&
3573 ((chars_per_pixel == 1 && (*c_ptr=='`' || *c_ptr==' ')) ||
3574 (chars_per_pixel == 2 && ((c_ptr[0]=='`' && c_ptr[1]=='`') ||
3575 (c_ptr[0]==' ' && c_ptr[1]==' '))))) {
3576 strcpy(s, (myFileBgColorStr==NULL ? myBgColorStr :
3577 myFileBgColorStr));
3578 if (pixels != NULL) (*pixels)[0] = bg_pixel;
3579 if (first_pixel_is_bg_return != NULL) {
3580 *first_pixel_is_bg_return = TRUE;
3581 }
3582 } else {
3583 c_ptr = FindChar((int)'"', c_ptr);
3584 c_ptr = FindChar((int)'"', c_ptr);
3585 ParseStr(c_ptr, (int)'"', s, sizeof(s));
3586 if (pixels != NULL) {
3587 if (UtilStrICmp(s, "None") == 0) {
3588 (*pixels)[i] = (-1);
3589 myReadTransparentPixmap = TRUE;
3590 } else if ((index=QuickFindColorIndex(NULL, s, &new_alloc,
3591 TRUE)) == INVALID) {
3592 sprintf(gszMsgBox,
3593 TgLoadCachedString(CSTID_CANNOT_ALLOC_COLOR_USE_ALT),
3594 s, colorMenuItems[colorIndex]);
3595 Msg(gszMsgBox);
3596 strcpy(s, colorMenuItems[colorIndex]);
3597 (*pixels)[i] = colorPixels[colorIndex];
3598 allocColorFailed = TRUE;
3599 } else {
3600 (*pixels)[i] = colorPixels[index];
3601 }
3602 } else {
3603 if (UtilStrICmp(s, "None") == 0) {
3604 myReadTransparentPixmap = TRUE;
3605 }
3606 }
3607 }
3608 len = strlen(s);
3609 (*color_str)[i] = (char*)malloc((len+1)*sizeof(char));
3610 if ((*color_str)[i] == NULL) FailAllocMessage();
3611 strcpy((*color_str)[i], s);
3612 }
3613
3614 if (fgets(inbuf, MAXSTRING, fp) == NULL ||
3615 inbuf[0] != '}' ||
3616 fgets(inbuf, MAXSTRING, fp) == NULL) {
3617 FreeAuxData(fp, *ncolors_return, *color_char, *color_str, pixels,
3618 pixels_used, pixmap_return, image_return, bitmap_return,
3619 bitmap_image_return);
3620 return BitmapFileInvalid;
3621 }
3622 len = strlen(inbuf);
3623 if (len <= 27 || strncmp(inbuf, "static char *", 13) != 0 ||
3624 strncmp(&inbuf[len-14], "_pixels[] = {\n", 14) != 0) {
3625 return BitmapFileInvalid;
3626 }
3627 } else {
3628 /* xpm_version is 3 */
3629 for (i=0; i < *ncolors_return; i++) {
3630 if (i == 0) {
3631 found = FALSE;
3632 while (fgets(inbuf, MAXSTRING, fp) != NULL) {
3633 if (*inbuf == '"') {
3634 found = TRUE;
3635 break;
3636 }
3637 }
3638 if (!found) {
3639 FreeAuxData(fp, i, *color_char, *color_str, pixels, pixels_used,
3640 pixmap_return, image_return, bitmap_return,
3641 bitmap_image_return);
3642 return BitmapFileInvalid;
3643 }
3644 } else if (fgets(inbuf, MAXSTRING, fp) == NULL) {
3645 FreeAuxData(fp, i, *color_char, *color_str, pixels, pixels_used,
3646 pixmap_return, image_return, bitmap_return,
3647 bitmap_image_return);
3648 return BitmapFileInvalid;
3649 }
3650 c_ptr = FindChar((int)'"', inbuf);
3651 for (j = 0; j < chars_per_pixel; j++) {
3652 (*color_char)[i*(chars_per_pixel)+j] = c_ptr[j];
3653 }
3654 if (guessXPmBgColor && i == 0 &&
3655 ((chars_per_pixel == 1 && (*c_ptr=='`' || *c_ptr==' ')) ||
3656 (chars_per_pixel == 2 && ((c_ptr[0]=='`' && c_ptr[1]=='`') ||
3657 (c_ptr[0]==' ' && c_ptr[1]==' '))))) {
3658 strcpy(s, (myFileBgColorStr==NULL ? myBgColorStr :
3659 myFileBgColorStr));
3660 if (pixels != NULL) (*pixels)[0] = bg_pixel;
3661 if (first_pixel_is_bg_return != NULL) {
3662 *first_pixel_is_bg_return = TRUE;
3663 }
3664 } else {
3665 char *ptr;
3666
3667 c_ptr += chars_per_pixel;
3668 while (*c_ptr != '\0') {
3669 while (*c_ptr == ' ' || *c_ptr == '\t') c_ptr++;
3670 if ((*c_ptr == 'c' || *c_ptr == 'm') &&
3671 (c_ptr[1]==' ' || c_ptr[1]=='\t')) {
3672 break;
3673 }
3674 while (*c_ptr!=' ' && *c_ptr!='\t' && *c_ptr!='\0') c_ptr++;
3675 while (*c_ptr == ' ' || *c_ptr == '\t') c_ptr++;
3676 while (*c_ptr!=' ' && *c_ptr!='\t' && *c_ptr!='\0') c_ptr++;
3677 }
3678 if (*c_ptr++ == '\0') {
3679 FreeAuxData(fp, i, *color_char, *color_str, pixels, pixels_used,
3680 pixmap_return, image_return, bitmap_return,
3681 bitmap_image_return);
3682 return BitmapFileInvalid;
3683 }
3684 while (*c_ptr == ' ' || *c_ptr == '\t') c_ptr++;
3685 for (ptr=c_ptr; *ptr != '"' && *ptr != '\0'; ptr++) {
3686 if (*ptr == ' ' || *ptr == '\t') {
3687 char tmp_ch=ptr[1];
3688
3689 if (tmp_ch == 'm' || tmp_ch == 's') {
3690 tmp_ch = ptr[2];
3691 if (tmp_ch == ' ' || tmp_ch == '\t') {
3692 break;
3693 }
3694 } else if (tmp_ch == 'g') {
3695 tmp_ch = ptr[2];
3696 if (tmp_ch == ' ' || tmp_ch == '\t') {
3697 break;
3698 } else if (tmp_ch == '4') {
3699 tmp_ch = ptr[4];
3700 if (tmp_ch == ' ' || tmp_ch == '\t') {
3701 break;
3702 }
3703 }
3704 }
3705 }
3706 }
3707 if (*ptr == '\0') {
3708 FreeAuxData(fp, i, *color_char, *color_str, pixels, pixels_used,
3709 pixmap_return, image_return, bitmap_return,
3710 bitmap_image_return);
3711 return BitmapFileInvalid;
3712 }
3713 while (ptr >= c_ptr) {
3714 if (*ptr == ' ' || *ptr == '\t' || *ptr == '"') {
3715 ptr--;
3716 } else {
3717 break;
3718 }
3719 }
3720 if (ptr < c_ptr) {
3721 FreeAuxData(fp, i, *color_char, *color_str, pixels, pixels_used,
3722 pixmap_return, image_return, bitmap_return,
3723 bitmap_image_return);
3724 return BitmapFileInvalid;
3725 }
3726 *(++ptr) = '\0';
3727 strcpy(s, c_ptr);
3728 if (pixels != NULL) {
3729 if (UtilStrICmp(s, "None") == 0) {
3730 (*pixels)[i] = (-1);
3731 myReadTransparentPixmap = TRUE;
3732 } else if ((index=QuickFindColorIndex(NULL, s, &new_alloc,
3733 TRUE)) == INVALID) {
3734 sprintf(gszMsgBox,
3735 TgLoadCachedString(CSTID_CANNOT_ALLOC_COLOR_USE_ALT),
3736 s, colorMenuItems[colorIndex]);
3737 Msg(gszMsgBox);
3738 strcpy(s, colorMenuItems[colorIndex]);
3739 (*pixels)[i] = colorPixels[colorIndex];
3740 allocColorFailed = TRUE;
3741 } else {
3742 (*pixels)[i] = colorPixels[index];
3743 }
3744 } else {
3745 if (UtilStrICmp(s, "None") == 0) {
3746 myReadTransparentPixmap = TRUE;
3747 }
3748 }
3749 }
3750 len = strlen(s);
3751 (*color_str)[i] = (char*)malloc((len+1)*sizeof(char));
3752 if ((*color_str)[i] == NULL) FailAllocMessage();
3753 strcpy((*color_str)[i], s);
3754 }
3755 }
3756 if (chars_per_pixel_return == NULL && first_pixel_is_bg_return == NULL &&
3757 pixels == NULL && xpm_data == NULL) {
3758 /* just getting the colors, so no need to read data */
3759 if (pixels_used != NULL) free(pixels_used);
3760 return BitmapSuccess;
3761 }
3762
3763 x = 0;
3764 y = 0;
3765 w = image_w;
3766 h = image_h;
3767 if (pixmap_return != NULL && bitmap_return != NULL &&
3768 image_return != NULL && bitmap_image_return != NULL) {
3769 mag = 1.0;
3770 if (askForXPmSpec) {
3771 sprintf(gszMsgBox, TgLoadString(STID_ENTER_GEOM_SPEC_ORIG_SIZE),
3772 image_w, image_h);
3773 *mag_spec = '\0';
3774 Dialog(gszMsgBox, TgLoadCachedString(CSTID_DLG_ACCEPT_CONTINUE),
3775 mag_spec);
3776 if (*mag_spec != '\0') {
3777 ParseCutSpec(mag_spec, image_w, image_h, &mag, &x, &y, &w, &h);
3778 }
3779 }
3780 *pixmap_return = XCreatePixmap(mainDisplay, dummyPixmap, w, h, mainDepth);
3781 *bitmap_return = XCreatePixmap(mainDisplay, dummyBitmap, w, h, 1);
3782 if (*pixmap_return == None || *bitmap_return == None) {
3783 FreeAuxData(fp, *ncolors_return, *color_char, *color_str, pixels,
3784 pixels_used, pixmap_return, image_return, bitmap_return,
3785 bitmap_image_return);
3786 return BitmapNoMemory;
3787 }
3788 XFillRectangle(mainDisplay, *pixmap_return, xpmGC, 0, 0, w, h);
3789 XSetForeground(mainDisplay, xbmGC, 1);
3790 XFillRectangle(mainDisplay, *bitmap_return, xbmGC, 0, 0, w, h);
3791 XSetForeground(mainDisplay, xbmGC, 0);
3792 *image_return = XGetImage(mainDisplay, *pixmap_return, 0, 0, w, h,
3793 AllPlanes, ZPixmap);
3794 *bitmap_image_return = XGetImage(mainDisplay, *bitmap_return, 0, 0, w, h,
3795 1, ZPixmap);
3796 if (*image_return == NULL || *bitmap_image_return == NULL) {
3797 MsgBox(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM), TOOL_NAME,
3798 INFO_MB);
3799 FreeAuxData(fp, *ncolors_return, *color_char, *color_str, pixels,
3800 pixels_used, pixmap_return, image_return, bitmap_return,
3801 bitmap_image_return);
3802 return BitmapNoMemory;
3803 }
3804 }
3805 if (!BuildXPmBuckets(*ncolors_return, NULL, NULL, chars_per_pixel,
3806 *color_char, NULL)) {
3807 FreeAuxData(fp, *ncolors_return, *color_char, *color_str, pixels,
3808 pixels_used, pixmap_return, image_return, bitmap_return,
3809 bitmap_image_return);
3810 return BitmapFileInvalid;
3811 }
3812 if (!colorDisplay) {
3813 if (xpm_data != NULL) {
3814 xpm_data_ptr = *xpm_data = (char*)malloc(
3815 image_w*image_h*chars_per_pixel*sizeof(char)+1);
3816 if (*xpm_data == NULL) FailAllocMessage();
3817 }
3818 }
3819 line = (char*)malloc((image_w*chars_per_pixel+20)*sizeof(char));
3820 if (line == NULL) FailAllocMessage();
3821 for (i=0; i < y+h; i++) {
3822 if (xpm_version == 3 && i == 0) {
3823 found = FALSE;
3824 while (fgets(line, image_w*chars_per_pixel+20, fp) != NULL) {
3825 if (*line == '"') {
3826 found = TRUE;
3827 break;
3828 }
3829 }
3830 if (!found) {
3831 FreeAuxData(fp, *ncolors_return, *color_char, *color_str, pixels,
3832 pixels_used, pixmap_return, image_return, bitmap_return,
3833 bitmap_image_return);
3834 return BitmapFileInvalid;
3835 }
3836 } else if (fgets(line, image_w*chars_per_pixel+20, fp)==NULL) {
3837 FreeAuxData(fp, *ncolors_return, *color_char, *color_str, pixels,
3838 pixels_used, pixmap_return, image_return, bitmap_return,
3839 bitmap_image_return);
3840 free(line);
3841 return BitmapFileInvalid;
3842 }
3843 if (i >= y) {
3844 c_ptr = FindChar((int)'"', line);
3845 if (xpm_data_ptr != NULL) {
3846 strncpy(xpm_data_ptr, c_ptr, image_w*chars_per_pixel);
3847 xpm_data_ptr += image_w*chars_per_pixel;
3848 }
3849 if (pixels != NULL) {
3850 for (j=0; j < x+w; j++, c_ptr+=chars_per_pixel) {
3851 if (j >= x) {
3852 k = XPmLookUp(INVALID, chars_per_pixel, c_ptr, NULL);
3853 if (k == INVALID) {
3854 FreeAuxData(fp, *ncolors_return, *color_char, *color_str,
3855 pixels, pixels_used, pixmap_return, image_return,
3856 bitmap_return, bitmap_image_return);
3857 free(line);
3858 return BitmapFileInvalid;
3859 }
3860 if (pixels_used != NULL) pixels_used[k] = TRUE;
3861 if ((*pixels)[k] == (-1)) {
3862 if (bitmap_image_return != NULL) {
3863 XPutPixel(*bitmap_image_return, j-x, i-y, 0);
3864 }
3865 if (image_return != NULL) {
3866 XPutPixel(*image_return, j-x, i-y,
3867 colorPixels[colorIndex]);
3868 }
3869 } else {
3870 if (image_return != NULL) {
3871 XPutPixel(*image_return, j-x, i-y, (*pixels)[k]);
3872 }
3873 }
3874 }
3875 }
3876 }
3877 }
3878 }
3879 if (xpm_data_ptr != NULL) *xpm_data_ptr = '\0';
3880 free(line);
3881 fclose(fp);
3882 if (pixmap_return != NULL && image_return != NULL) {
3883 XPutImage(mainDisplay,*pixmap_return,xpmGC,*image_return,0,0,0,0,w,h);
3884 }
3885 if (bitmap_return != NULL && bitmap_image_return != NULL) {
3886 XPutImage(mainDisplay, *bitmap_return, xbmGC, *bitmap_image_return,
3887 0, 0, 0, 0, w, h);
3888 }
3889 if (image_w_return != NULL) *image_w_return = w;
3890 if (image_h_return != NULL) *image_h_return = h;
3891 if (w_return != NULL) *w_return = (int)(((float)w) * mag);
3892 if (h_return != NULL) *h_return = (int)(((float)h) * mag);
3893 if (pixels != NULL) {
3894 int new_ncolors=0;
3895
3896 for (i=0; i < *ncolors_return; i++) {
3897 if (pixels_used[i]) {
3898 new_ncolors++;
3899 }
3900 }
3901 if (new_ncolors < *ncolors_return) {
3902 /* some pixels are not used */
3903 char *new_color_char=(char*)malloc(
3904 new_ncolors*chars_per_pixel*sizeof(char));
3905 char **new_color_str=(char**)malloc(new_ncolors*sizeof(char *));
3906 int *new_pixels=(int*)malloc(new_ncolors*sizeof(int));
3907
3908 if (new_color_char == NULL || new_color_str == NULL ||
3909 new_pixels == NULL) {
3910 FailAllocMessage();
3911 } else {
3912 int new_index=0, ok=TRUE;
3913
3914 for (i=0; i < *ncolors_return; i++) {
3915 if (pixels_used[i]) {
3916 int j;
3917
3918 strncpy(&new_color_char[new_index*chars_per_pixel],
3919 &(*color_char)[i*chars_per_pixel],
3920 chars_per_pixel*sizeof(char));
3921 new_color_str[new_index] = UtilStrDup((*color_str)[i]);
3922 if (new_color_str[new_index] == NULL) {
3923 for (j=0; j < i; j++) {
3924 free(new_color_str[j]);
3925 }
3926 free(new_color_char);
3927 free(new_color_str);
3928 free(new_pixels);
3929 new_color_char = NULL;
3930 new_color_str = NULL;
3931 new_pixels = NULL;
3932 ok = FALSE;
3933 break;
3934 }
3935 new_pixels[new_index] = (*pixels)[i];
3936 new_index++;
3937 }
3938 }
3939 if (ok) {
3940 free(*color_char);
3941 *color_char = new_color_char;
3942 for (i=0; i < *ncolors_return; i++) {
3943 free((*color_str)[i]);
3944 }
3945 free(*color_str);
3946 *color_str = new_color_str;
3947 free(*pixels);
3948 *pixels = new_pixels;
3949 if (first_pixel_is_bg_return != NULL &&
3950 *first_pixel_is_bg_return && pixels_used[0]) {
3951 *first_pixel_is_bg_return = FALSE;
3952 }
3953 new_color_char = NULL;
3954 new_color_str = NULL;
3955 new_pixels = NULL;
3956 *ncolors_return = new_ncolors;
3957 }
3958 }
3959 if (new_color_char != NULL) free(new_color_char);
3960 if (new_color_str != NULL) free(new_color_str);
3961 if (new_pixels != NULL) free(new_pixels);
3962 }
3963 }
3964 if (pixels_used != NULL) free(pixels_used);
3965 gnNumNewColorsInPixmapFile = maxColors - saved_max_colors;
3966 if (gnNumNewColorsInPixmapFile != 0) {
3967 sprintf(gszMsgBox, TgLoadCachedString(CSTID_GIVEN_ADDTNL_COLOR_ALLOCATED),
3968 gnNumNewColorsInPixmapFile);
3969 Msg(gszMsgBox);
3970 }
3971 return BitmapSuccess;
3972 }
3973
ReadXPmObj(FP,Inbuf,ObjPtr)3974 void ReadXPmObj(FP, Inbuf, ObjPtr)
3975 FILE *FP;
3976 char *Inbuf;
3977 struct ObjRec **ObjPtr;
3978 {
3979 struct XPmRec *xpm_ptr;
3980 char color_s[40], trans_color_s[40], *s, inbuf[MAXSTRING], *c_ptr, *line;
3981 int ltx, lty, rbx, rby, i, j, k, image_w, image_h;
3982 int ncolors, * pixels, len, index, fill, color_index;
3983 int *red=NULL, *green=NULL, *blue=NULL;
3984 int unrecognized_color = FALSE, rotation, chars_per_pixel;
3985 int first_pixel_is_bg, first_pixel_maybe_bg, new_alloc;
3986 int id=0, rotate=ROTATE0, flip=NO_FLIP, locked=FALSE;
3987 int compressed=FALSE, real_x=0, real_y=0;
3988 int transformed=FALSE, invisible=FALSE, bg_pixel;
3989 char *xpm_data=NULL, *color_char, **color_str;
3990 Pixmap pixmap=None, bitmap=None;
3991 XImage *image=NULL, *bitmap_image=NULL;
3992 struct XfrmMtrxRec *ctm=NULL;
3993 struct BBRec orig_obbox;
3994
3995 *ObjPtr = NULL;
3996
3997 s = FindChar((int)'(', Inbuf);
3998 s = ParseStr(s, (int)',', color_s, sizeof(color_s));
3999 if (fileVersion >= 37) {
4000 s = ParseStr(s, (int)',', trans_color_s, sizeof(trans_color_s));
4001 }
4002 InitScan(s, "\t\n, ");
4003
4004 rotation = 0;
4005 chars_per_pixel = 1;
4006 first_pixel_maybe_bg = TRUE;
4007 first_pixel_is_bg = TRUE;
4008 if (fileVersion <= 9) {
4009 sprintf(gszMsgBox, TgLoadCachedString(CSTID_INVALID_FILEVER_FOR_XPM),
4010 fileVersion);
4011 if (PRTGIF) {
4012 fprintf(stderr, "%s\n", gszMsgBox);
4013 } else {
4014 Msg(gszMsgBox);
4015 }
4016 return;
4017 } else if (fileVersion <= 13) {
4018 if (GETINT("xpixmap", ltx, "ltx") == INVALID ||
4019 GETINT("xpixmap", lty, "lty") == INVALID ||
4020 GETINT("xpixmap", rbx, "rbx") == INVALID ||
4021 GETINT("xpixmap", rby, "rby") == INVALID ||
4022 GETINT("xpixmap", fill, "fill") == INVALID ||
4023 GETINT("xpixmap", ncolors, "ncolors") == INVALID ||
4024 GETINT("xpixmap", id, "id") == INVALID) {
4025 return;
4026 }
4027 if (id >= objId) objId = id+1;
4028 } else if (fileVersion <= 14) {
4029 if (GETINT("xpixmap", ltx, "ltx") == INVALID ||
4030 GETINT("xpixmap", lty, "lty") == INVALID ||
4031 GETINT("xpixmap", rbx, "rbx") == INVALID ||
4032 GETINT("xpixmap", rby, "rby") == INVALID ||
4033 GETINT("xpixmap", fill, "fill") == INVALID ||
4034 GETINT("xpixmap", ncolors, "ncolors") == INVALID ||
4035 GETINT("xpixmap", id, "id") == INVALID ||
4036 GETINT("xpixmap", rotation, "rotation") == INVALID) {
4037 return;
4038 }
4039 if (id >= objId) objId = id+1;
4040 } else if (fileVersion <= 22) {
4041 if (GETINT("xpixmap", ltx, "ltx") == INVALID ||
4042 GETINT("xpixmap", lty, "lty") == INVALID ||
4043 GETINT("xpixmap", rbx, "rbx") == INVALID ||
4044 GETINT("xpixmap", rby, "rby") == INVALID ||
4045 GETINT("xpixmap", fill, "fill") == INVALID ||
4046 GETINT("xpixmap", ncolors, "ncolors") == INVALID ||
4047 GETINT("xpixmap", chars_per_pixel, "chars_per_pixel") == INVALID ||
4048 GETINT("xpixmap", first_pixel_is_bg,"first_pixel_is_bg") == INVALID ||
4049 GETINT("xpixmap", id, "id") == INVALID ||
4050 GETINT("xpixmap", rotation, "rotation") == INVALID) {
4051 return;
4052 }
4053 if (id >= objId) objId = id+1;
4054 first_pixel_maybe_bg = FALSE;
4055 } else if (fileVersion <= 25) {
4056 if (GETINT("xpixmap", ltx, "ltx") == INVALID ||
4057 GETINT("xpixmap", lty, "lty") == INVALID ||
4058 GETINT("xpixmap", rbx, "rbx") == INVALID ||
4059 GETINT("xpixmap", rby, "rby") == INVALID ||
4060 GETINT("xpixmap", fill, "fill") == INVALID ||
4061 GETINT("xpixmap", ncolors, "ncolors") == INVALID ||
4062 GETINT("xpixmap", chars_per_pixel, "chars_per_pixel") == INVALID ||
4063 GETINT("xpixmap", first_pixel_is_bg,"first_pixel_is_bg") == INVALID ||
4064 GETINT("xpixmap", id, "id") == INVALID ||
4065 GETINT("xpixmap", rotation, "rotation") == INVALID ||
4066 GETINT("xpixmap", image_w, "image_w") == INVALID ||
4067 GETINT("xpixmap", image_h, "image_h") == INVALID ||
4068 GETINT("xpixmap", rotate, "rotate") == INVALID ||
4069 GETINT("xpixmap", flip, "flip") == INVALID) {
4070 return;
4071 }
4072 if (id >= objId) objId = id+1;
4073 first_pixel_maybe_bg = FALSE;
4074 } else if (fileVersion <= 32) {
4075 if (GETINT("xpixmap", ltx, "ltx") == INVALID ||
4076 GETINT("xpixmap", lty, "lty") == INVALID ||
4077 GETINT("xpixmap", rbx, "rbx") == INVALID ||
4078 GETINT("xpixmap", rby, "rby") == INVALID ||
4079 GETINT("xpixmap", fill, "fill") == INVALID ||
4080 GETINT("xpixmap", ncolors, "ncolors") == INVALID ||
4081 GETINT("xpixmap", chars_per_pixel, "chars_per_pixel") == INVALID ||
4082 GETINT("xpixmap", first_pixel_is_bg,"first_pixel_is_bg") == INVALID ||
4083 GETINT("xpixmap", id, "id") == INVALID ||
4084 GETINT("xpixmap", rotation, "rotation") == INVALID ||
4085 GETINT("xpixmap", image_w, "image_w") == INVALID ||
4086 GETINT("xpixmap", image_h, "image_h") == INVALID ||
4087 GETINT("xpixmap", rotate, "rotate") == INVALID ||
4088 GETINT("xpixmap", flip, "flip") == INVALID ||
4089 GETINT("xpixmap", locked, "locked") == INVALID) {
4090 return;
4091 }
4092 if (id >= objId) objId = id+1;
4093 first_pixel_maybe_bg = FALSE;
4094 } else {
4095 if (GETINT("xpixmap", ltx, "ltx") == INVALID ||
4096 GETINT("xpixmap", lty, "lty") == INVALID ||
4097 GETINT("xpixmap", rbx, "rbx") == INVALID ||
4098 GETINT("xpixmap", rby, "rby") == INVALID ||
4099 GETINT("xpixmap", fill, "fill") == INVALID ||
4100 GETINT("xpixmap", ncolors, "ncolors") == INVALID ||
4101 GETINT("xpixmap", chars_per_pixel, "chars_per_pixel") == INVALID ||
4102 GETINT("xpixmap", first_pixel_is_bg,"first_pixel_is_bg") == INVALID ||
4103 GETINT("xpixmap", id, "id") == INVALID ||
4104 GETINT("xpixmap", rotation, "rotation") == INVALID ||
4105 GETINT("xpixmap", image_w, "image_w") == INVALID ||
4106 GETINT("xpixmap", image_h, "image_h") == INVALID ||
4107 GETINT("xpixmap", rotate, "rotate") == INVALID ||
4108 GETINT("xpixmap", flip, "flip") == INVALID ||
4109 GETINT("xpixmap", locked, "locked") == INVALID ||
4110 GETINT("xpixmap", compressed, "compressed") == INVALID ||
4111 GETINT("xpixmap", transformed, "transformed") == INVALID ||
4112 GETINT("xpixmap", invisible, "invisible") == INVALID) {
4113 return;
4114 }
4115 if (id >= objId) objId = id+1;
4116 first_pixel_maybe_bg = FALSE;
4117 }
4118 if (fileVersion <= 22) {
4119 image_w = rbx-ltx;
4120 image_h = rby-lty;
4121 rotate = ROTATE0;
4122 flip = 0;
4123 }
4124 if (fileVersion >= 33 && transformed) {
4125 (void)fgets(inbuf, MAXSTRING, FP);
4126 scanLineNum++;
4127 InitScan(inbuf, "\t\n, ");
4128
4129 ctm = (struct XfrmMtrxRec *)malloc(sizeof(struct XfrmMtrxRec));
4130 if (ctm == NULL) FailAllocMessage();
4131 if (GETINT("xpixmap", real_x, "real_x") == INVALID ||
4132 GETINT("xpixmap", real_y, "real_y") == INVALID ||
4133 GETINT("xpixmap", orig_obbox.ltx, "orig_obbox.ltx") == INVALID ||
4134 GETINT("xpixmap", orig_obbox.lty, "orig_obbox.lty") == INVALID ||
4135 GETINT("xpixmap", orig_obbox.rbx, "orig_obbox.rbx") == INVALID ||
4136 GETINT("xpixmap", orig_obbox.rby, "orig_obbox.rby") == INVALID ||
4137 GETDBL("xpixmap", ctm->m[CTM_SX], "CTM_SX") == INVALID ||
4138 GETDBL("xpixmap", ctm->m[CTM_SIN], "CTM_SIN") == INVALID ||
4139 GETDBL("xpixmap", ctm->m[CTM_MSIN], "CTM_MSIN") == INVALID ||
4140 GETDBL("xpixmap", ctm->m[CTM_SY], "CTM_SY") == INVALID ||
4141 GETINT("xpixmap", ctm->t[CTM_TX], "CTM_TX") == INVALID ||
4142 GETINT("xpixmap", ctm->t[CTM_TY], "CTM_TY") == INVALID) {
4143 return;
4144 }
4145 }
4146 fill = UpgradePenFill(fill);
4147
4148 *ObjPtr = (struct ObjRec *)malloc(sizeof(struct ObjRec));
4149 if (*ObjPtr == NULL) FailAllocMessage();
4150 memset(*ObjPtr, 0, sizeof(struct ObjRec));
4151 xpm_ptr = (struct XPmRec *)malloc(sizeof(struct XPmRec));
4152 if (xpm_ptr == NULL) FailAllocMessage();
4153 memset(xpm_ptr, 0, sizeof(struct XPmRec));
4154
4155 color_index = QuickFindColorIndex(*ObjPtr, color_s, &new_alloc, TRUE);
4156
4157 (*ObjPtr)->color = color_index;
4158 if (mainDisplay != NULL) {
4159 UtilStrCpyN((*ObjPtr)->color_str, sizeof((*ObjPtr)->color_str),
4160 colorMenuItems[color_index]);
4161 }
4162 (*ObjPtr)->dirty = FALSE;
4163 (*ObjPtr)->id = id;
4164 (*ObjPtr)->rotation = rotation;
4165 (*ObjPtr)->locked = locked;
4166 (*ObjPtr)->type = OBJ_XPM;
4167 (*ObjPtr)->obbox.ltx = (*ObjPtr)->bbox.ltx = (*ObjPtr)->x = ltx;
4168 (*ObjPtr)->obbox.lty = (*ObjPtr)->bbox.lty = (*ObjPtr)->y = lty;
4169 (*ObjPtr)->obbox.rbx = (*ObjPtr)->bbox.rbx = rbx;
4170 (*ObjPtr)->obbox.rby = (*ObjPtr)->bbox.rby = rby;
4171 (*ObjPtr)->detail.xpm = xpm_ptr;
4172 (*ObjPtr)->ctm = ctm;
4173 (*ObjPtr)->invisible = invisible;
4174
4175 if (ctm != NULL) {
4176 memcpy(&(*ObjPtr)->orig_obbox, &orig_obbox, sizeof(struct BBRec));
4177 (*ObjPtr)->x = real_x;
4178 (*ObjPtr)->y = real_y;
4179 GetTransformedOBBoxOffsetVs(*ObjPtr, (*ObjPtr)->rotated_obbox);
4180 }
4181 color_char = (char*)malloc(ncolors*chars_per_pixel*sizeof(char));
4182 color_str = (char**)malloc(ncolors*sizeof(char*));
4183 pixels = (int*)malloc(ncolors*sizeof(int));
4184 if (color_char == NULL || color_str == NULL || pixels == NULL) {
4185 FailAllocMessage();
4186 }
4187 if (fileVersion >= 25 && ((PRTGIF && !cmdLineOpenDisplay) ||
4188 !colorDisplay)) {
4189 red = (int*)malloc(ncolors*sizeof(int));
4190 green = (int*)malloc(ncolors*sizeof(int));
4191 blue = (int*)malloc(ncolors*sizeof(int));
4192 if (red == NULL || green == NULL || blue == NULL) FailAllocMessage();
4193 }
4194 xpm_ptr->pixmap = None;
4195 xpm_ptr->image = NULL;
4196 xpm_ptr->bitmap = None;
4197 xpm_ptr->bitmap_image = NULL;
4198 xpm_ptr->cached_pixmap = None;
4199 xpm_ptr->cached_bitmap = None;
4200 xpm_ptr->cached_zoom = 0;
4201 xpm_ptr->data = NULL;
4202 xpm_ptr->fill = fill;
4203 xpm_ptr->flip = flip;
4204 xpm_ptr->cached_flip = 0;
4205 xpm_ptr->cached_w = xpm_ptr->cached_h = 0;
4206 xpm_ptr->cached_color = (-1);
4207 xpm_ptr->image_w = image_w;
4208 xpm_ptr->image_h = image_h;
4209
4210 xpm_ptr->ncolors = ncolors;
4211 xpm_ptr->chars_per_pixel = chars_per_pixel;
4212 xpm_ptr->first_pixel_is_bg = first_pixel_is_bg;
4213 xpm_ptr->color_char = color_char;
4214 xpm_ptr->color_str = color_str;
4215 xpm_ptr->pixels = pixels;
4216 xpm_ptr->red = red;
4217 xpm_ptr->green = green;
4218 xpm_ptr->blue = blue;
4219
4220 bg_pixel = GetDrawingBgPixel(INVALID, INVALID);
4221 for (i=0; i < ncolors; i++) {
4222 (void)fgets(inbuf, MAXSTRING, FP);
4223 scanLineNum++;
4224 c_ptr = FindChar((int)'"', inbuf);
4225 for (j = 0; j < chars_per_pixel; j++) {
4226 color_char[i*chars_per_pixel+j] = c_ptr[j];
4227 }
4228 c_ptr = FindChar((int)'"', c_ptr);
4229 c_ptr = FindChar((int)'"', c_ptr);
4230 c_ptr = ParseStr(c_ptr, (int)'"', color_s, sizeof(color_s));
4231 if (!PRTGIF || cmdLineOpenDisplay) {
4232 if (i == 0 && (first_pixel_is_bg || (first_pixel_maybe_bg &&
4233 (color_char[i]=='`' || color_char[i]==' ')))) {
4234 strcpy(color_s, (myFileBgColorStr==NULL ? myBgColorStr :
4235 myFileBgColorStr));
4236 pixels[i] = bg_pixel;
4237 xpm_ptr->first_pixel_is_bg = first_pixel_is_bg = TRUE;
4238 } else if (UtilStrICmp(color_s, "None") == 0) {
4239 pixels[i] = (-1);
4240 } else if ((index = QuickFindColorIndex(NULL, color_s, &new_alloc,
4241 TRUE)) == INVALID) {
4242 sprintf(gszMsgBox,
4243 TgLoadCachedString(CSTID_CANNOT_ALLOC_COLOR_USE_ALT),
4244 color_s, colorMenuItems[colorIndex]);
4245 Msg(gszMsgBox);
4246 allocColorFailed = TRUE;
4247 strcpy(color_s, colorMenuItems[colorIndex]);
4248 pixels[i] = colorPixels[colorIndex];
4249 } else {
4250 pixels[i] = colorPixels[index];
4251 }
4252
4253 len = strlen(color_s);
4254 color_str[i] = (char*)malloc((len+1)*sizeof(char));
4255 if (color_str[i] == NULL) FailAllocMessage();
4256 strcpy(color_str[i], color_s);
4257 }
4258 if (fileVersion >= 25 && ((PRTGIF && !cmdLineOpenDisplay) ||
4259 !colorDisplay)) {
4260 /* has RGB information for PRTGIF */
4261 InitScan(c_ptr, "\t\n, ");
4262
4263 if (GETINT("xpixmap", red[i], "red") == INVALID ||
4264 GETINT("xpixmap", green[i], "green") == INVALID ||
4265 GETINT("xpixmap", blue[i], "blue") == INVALID) {
4266 return;
4267 }
4268 if (UtilStrICmp(color_s, "None") == 0) {
4269 red[i] = green[i] = blue[i] = (-1);
4270 } else if (PRTGIF && cmdLineColor && (prTgifFoundColorInfo ||
4271 !cmdLineOpenDisplay)) {
4272 int found_index=PrTgifFindColorIndex(NULL, color_s);
4273
4274 if (found_index != INVALID) {
4275 red[i] =
4276 (int)(10000*((int)tgifColors[found_index].red)/maxRGB);
4277 green[i] =
4278 (int)(10000*((int)tgifColors[found_index].green)/maxRGB);
4279 blue[i] =
4280 (int)(10000*((int)tgifColors[found_index].blue)/maxRGB);
4281 }
4282 }
4283 }
4284 }
4285 xpm_ptr->clip_mask = None;
4286
4287 if (PRTGIF && !cmdLineOpenDisplay) {
4288 xpm_data = (char*)malloc(image_w*image_h*chars_per_pixel*sizeof(char));
4289 if (xpm_data == NULL) FailAllocMessage();
4290 xpm_ptr->data = xpm_data;
4291
4292 line = (char*)malloc((image_w*chars_per_pixel+20)*sizeof(char));
4293 if (line == NULL) FailAllocMessage();
4294 for (i=0; i < image_h; i++, xpm_data += image_w*chars_per_pixel) {
4295 (void)fgets(line, image_w*chars_per_pixel+20, FP);
4296 scanLineNum++;
4297 c_ptr = &line[4];
4298 strncpy(xpm_data, c_ptr, image_w*chars_per_pixel);
4299 }
4300 free(line);
4301 } else {
4302 if (fileVersion >= 25 && !colorDisplay) {
4303 xpm_data = (char*)malloc(image_w*image_h*chars_per_pixel*sizeof(char));
4304 if (xpm_data == NULL) FailAllocMessage();
4305 xpm_ptr->data = xpm_data;
4306 }
4307 pixmap = XCreatePixmap(mainDisplay, dummyPixmap, image_w, image_h,
4308 mainDepth);
4309 bitmap = XCreatePixmap(mainDisplay, dummyPixmap, image_w, image_h, 1);
4310 XFillRectangle(mainDisplay, pixmap, xpmGC, 0, 0, image_w, image_h);
4311 XSetForeground(mainDisplay, xbmGC, 1);
4312 XFillRectangle(mainDisplay, bitmap, xbmGC, 0, 0, image_w, image_h);
4313 XSetForeground(mainDisplay, xbmGC, 0);
4314 image = XGetImage(mainDisplay, pixmap, 0, 0, image_w, image_h, AllPlanes,
4315 ZPixmap);
4316 bitmap_image = XGetImage(mainDisplay, bitmap, 0, 0, image_w, image_h, 1,
4317 ZPixmap);
4318 if (image == NULL || bitmap_image == NULL) {
4319 MsgBox(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM), TOOL_NAME,
4320 INFO_MB);
4321 XFreePixmap(mainDisplay, pixmap);
4322 XFreePixmap(mainDisplay, bitmap);
4323 if (image != NULL) XDestroyImage(image);
4324 if (bitmap_image != NULL) XDestroyImage(bitmap_image);
4325 return;
4326 }
4327 if (!BuildXPmBuckets(ncolors, NULL, NULL, chars_per_pixel, color_char,
4328 NULL)) {
4329 XFreePixmap(mainDisplay, pixmap);
4330 XFreePixmap(mainDisplay, bitmap);
4331 if (image != NULL) XDestroyImage(image);
4332 if (bitmap_image != NULL) XDestroyImage(bitmap_image);
4333 return;
4334 }
4335 line = (char*)malloc((image_w*chars_per_pixel+20)*sizeof(char));
4336 if (line == NULL) FailAllocMessage();
4337 for (i=0; i < image_h; i++) {
4338 (void)fgets(line, image_w*chars_per_pixel+20, FP);
4339 scanLineNum++;
4340 c_ptr = &line[4];
4341 if (xpm_data != NULL) {
4342 strncpy(xpm_data, c_ptr, image_w*chars_per_pixel);
4343 }
4344 for (j = 0; j < image_w; j++, c_ptr+=chars_per_pixel) {
4345 k = XPmLookUp(INVALID, chars_per_pixel, c_ptr, NULL);
4346 if (k == INVALID) {
4347 XPutPixel(image, j, i, pixels[0]);
4348 unrecognized_color = TRUE;
4349 } else if (pixels[k] == (-1)) {
4350 XPutPixel(bitmap_image, j, i, 0);
4351 XPutPixel(image, j, i, colorPixels[color_index]);
4352 } else {
4353 XPutPixel(image, j, i, pixels[k]);
4354 }
4355 }
4356 if (xpm_data != NULL) xpm_data += image_w*chars_per_pixel;
4357 }
4358 free(line);
4359 XPutImage(mainDisplay,pixmap,xpmGC,image,0,0,0,0,image_w,image_h);
4360 XPutImage(mainDisplay,bitmap,xbmGC,bitmap_image,0,0,0,0,image_w,image_h);
4361 xpm_ptr->pixmap = pixmap;
4362 xpm_ptr->image = image;
4363 xpm_ptr->bitmap = bitmap;
4364 xpm_ptr->bitmap_image = bitmap_image;
4365
4366 if (unrecognized_color) {
4367 sprintf(gszMsgBox,
4368 TgLoadCachedString(CSTID_COLOR_SUBS_FOR_UNRECOG_IN_XPM),
4369 color_str[0]);
4370 Msg(gszMsgBox);
4371 }
4372 }
4373 if (fileVersion < 33 && (rotate != ROTATE0 || flip != NO_FLIP)) {
4374 double dz=(double)0.0, d1=(double)1000.0, dm1=((double)-1000.0);
4375
4376 if (rotate == ROTATE90 || rotate == ROTATE270) {
4377 int h=(*ObjPtr)->obbox.rbx-(*ObjPtr)->obbox.ltx;
4378 int w=(*ObjPtr)->obbox.rby-(*ObjPtr)->obbox.lty;
4379
4380 (*ObjPtr)->obbox.rby = (*ObjPtr)->obbox.lty + h;
4381 (*ObjPtr)->obbox.rbx = (*ObjPtr)->obbox.ltx + w;
4382 }
4383 ltx = ((*ObjPtr)->obbox.ltx);
4384 lty = ((*ObjPtr)->obbox.lty);
4385 SetRotatePivotByObject(*ObjPtr);
4386
4387 if (flip & HORI_EVEN) {
4388 ShearObj(*ObjPtr, CORNER_LEFT, dz, dz, dm1, d1, <x, <y);
4389 }
4390 if (flip & VERT_EVEN) {
4391 ShearObj(*ObjPtr, CORNER_TOP, dz, dz, d1, dm1, <x, <y);
4392 }
4393 if (rotate == ROTATE0) {
4394 if (flip & (HORI_ODD | VERT_ODD)) {
4395 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
4396 if (flip & HORI_ODD) {
4397 ShearObj(*ObjPtr, CORNER_LEFT, dz, dz, dm1, d1, <x, <y);
4398 }
4399 if (flip & VERT_ODD) {
4400 ShearObj(*ObjPtr, CORNER_TOP, dz, dz, d1, dm1, <x, <y);
4401 }
4402 RotateObj(*ObjPtr, CORNER_LT, COUNTER90, <x, <y);
4403 }
4404 } else {
4405 switch (rotate) {
4406 case ROTATE90:
4407 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
4408 if (flip & HORI_ODD) {
4409 ShearObj(*ObjPtr, CORNER_LEFT, dz, dz, dm1, d1, <x, <y);
4410 }
4411 if (flip & VERT_ODD) {
4412 ShearObj(*ObjPtr, CORNER_TOP, dz, dz, d1, dm1, <x, <y);
4413 }
4414 break;
4415 case ROTATE180:
4416 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
4417 if (flip & HORI_ODD) {
4418 ShearObj(*ObjPtr, CORNER_LEFT, dz, dz, dm1, d1, <x, <y);
4419 }
4420 if (flip & VERT_ODD) {
4421 ShearObj(*ObjPtr, CORNER_TOP, dz, dz, d1, dm1, <x, <y);
4422 }
4423 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
4424 break;
4425 case ROTATE270:
4426 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
4427 if (flip & HORI_ODD) {
4428 ShearObj(*ObjPtr, CORNER_LEFT, dz, dz, dm1, d1, <x, <y);
4429 }
4430 if (flip & VERT_ODD) {
4431 ShearObj(*ObjPtr, CORNER_TOP, dz, dz, d1, dm1, <x, <y);
4432 }
4433 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
4434 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
4435 break;
4436 }
4437 }
4438 xpm_ptr->flip = NO_FLIP;
4439 }
4440 }
4441
4442 static
MyReadJpegFileSkipData(jpeg_filename,expected_image_w,expected_image_h)4443 struct ObjRec *MyReadJpegFileSkipData(jpeg_filename, expected_image_w,
4444 expected_image_h)
4445 char *jpeg_filename;
4446 int expected_image_w, expected_image_h;
4447 {
4448 FILE *ppm_fp=NULL;
4449 char tmp_fname[MAXPATHLENGTH+1];
4450 int rc=0, format=0, image_w=0, image_h=0, max_val=0;
4451 struct ObjRec *obj_ptr=NULL;
4452
4453 SetWatchCursor(drawWindow);
4454 SetWatchCursor(mainWindow);
4455 SaveStatusStrings();
4456 rc = ConvertJpegToPpm6(jpeg_filename, tmp_fname, sizeof(tmp_fname));
4457 RestoreStatusStrings();
4458 SetDefaultCursor(mainWindow);
4459 ShowCursor();
4460 if (!rc) {
4461 return NULL;
4462 }
4463 ppm_fp = fopen(tmp_fname, "r");
4464 if (ppm_fp == NULL) {
4465 FailToOpenMessage(tmp_fname, "r", NULL);
4466 return NULL;
4467 }
4468 if (!ReadPpmHeader(ppm_fp, tmp_fname, &format, &image_w, &image_h,
4469 &max_val)) {
4470 fclose(ppm_fp);
4471 return NULL;
4472 }
4473 fclose(ppm_fp);
4474
4475 if (expected_image_w != (-1) && expected_image_h != (-1) &&
4476 (image_w != expected_image_w || image_h != expected_image_h)) {
4477 sprintf(gszMsgBox, TgLoadString(STID_JPEG_DIM_NOT_MATCH_DELETED), image_w,
4478 image_h, jpeg_filename, expected_image_w, expected_image_h);
4479 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4480 return NULL;
4481 }
4482 obj_ptr = CreateXPmObj(image_w, image_h, image_w, image_h, None, NULL, None,
4483 NULL, (-1), 1, FALSE, NULL, NULL, NULL, NULL);
4484
4485 unlink(tmp_fname);
4486
4487 return obj_ptr;
4488 }
4489
4490 static
MyReadJpegFile(jpeg_filename,expected_image_w,expected_image_h)4491 struct ObjRec *MyReadJpegFile(jpeg_filename, expected_image_w, expected_image_h)
4492 char *jpeg_filename;
4493 int expected_image_w, expected_image_h;
4494 {
4495 char tmp_fname[MAXPATHLENGTH+1];
4496 int rc=0, ncolors=0, chars_per_pixel=0, *pixels=NULL;
4497 int first_pixel_is_bg=FALSE, image_w=0, image_h=0, w=0, h=0;
4498 Pixmap pixmap=None, bitmap=None;
4499 XImage *image=NULL, *bitmap_image=NULL;
4500 char *color_char, **color_str=NULL, *xpm_data=NULL;
4501 struct ObjRec *obj_ptr=NULL;
4502
4503 if (fullTrueColorMode && HasZlibSupport()) {
4504 struct XPmRec *xpm_ptr=NULL;
4505 char ppm6_fname[MAXPATHLENGTH+1];
4506
4507 rc = ConvertJpegToPpm6(jpeg_filename, ppm6_fname, sizeof(ppm6_fname));
4508 if (!rc) return NULL;
4509
4510 ResetPngHeaderInfo(&gPngHeaderInfo);
4511 obj_ptr = CreatePpmTrueObjFromFile(ppm6_fname);
4512 unlink(ppm6_fname);
4513
4514 if (obj_ptr == NULL) return NULL;
4515
4516 xpm_ptr = obj_ptr->detail.xpm;
4517 xpm_ptr->real_type = PPM_TRUE;
4518 xpm_ptr->ppm_data_compress = PPM_JPEG_COMPRESS;
4519 xpm_ptr->ppm_data = ReadFileIntoBuf( jpeg_filename,
4520 &xpm_ptr->ppm_data_size);
4521 xpm_ptr->ppm_mask_data = NULL;
4522 xpm_ptr->ppm_mask_size = 0;
4523
4524 if (expected_image_w != (-1) && expected_image_h != (-1) &&
4525 (xpm_ptr->image_w != expected_image_w ||
4526 xpm_ptr->image_h != expected_image_h)) {
4527 sprintf(gszMsgBox, TgLoadString(STID_JPEG_DIM_NOT_MATCH_DELETED),
4528 xpm_ptr->image_w, xpm_ptr->image_h, jpeg_filename,
4529 expected_image_w, expected_image_h);
4530 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4531 return NULL;
4532 }
4533 return obj_ptr;
4534 }
4535 SetWatchCursor(drawWindow);
4536 SetWatchCursor(mainWindow);
4537 SaveStatusStrings();
4538 *tmp_fname = '\0';
4539 rc = ConvertJpegToXpm(jpeg_filename, tmp_fname, sizeof(tmp_fname));
4540 RestoreStatusStrings();
4541 SetDefaultCursor(mainWindow);
4542 ShowCursor();
4543 if (!rc) {
4544 return NULL;
4545 }
4546 SetWatchCursor(drawWindow);
4547 SetWatchCursor(mainWindow);
4548 rc = MyReadPixmapFile(tmp_fname,
4549 &image_w, &image_h, &w, &h, &pixmap, &image, &bitmap, &bitmap_image,
4550 &ncolors, &chars_per_pixel, &first_pixel_is_bg, &color_char,
4551 &color_str, &pixels, &xpm_data);
4552 SetDefaultCursor(mainWindow);
4553 ShowCursor();
4554
4555 if (rc != BitmapSuccess) {
4556 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_IMPORT_XPM_FILE), tmp_fname);
4557 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4558 return NULL;
4559 }
4560 if (expected_image_w != (-1) && expected_image_h != (-1) &&
4561 (image_w != expected_image_w || image_h != expected_image_h)) {
4562 sprintf(gszMsgBox, TgLoadString(STID_JPEG_DIM_NOT_MATCH_DELETED), image_w,
4563 image_h, jpeg_filename, expected_image_w, expected_image_h);
4564 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4565 return NULL;
4566 }
4567 obj_ptr = CreateXPmObj(image_w, image_h, w, h, pixmap, image, bitmap,
4568 bitmap_image, ncolors, chars_per_pixel, first_pixel_is_bg, color_char,
4569 color_str, pixels, xpm_data);
4570
4571 unlink(tmp_fname);
4572
4573 return obj_ptr;
4574 }
4575
ReadJpegObj(FP,Inbuf,ObjPtr)4576 void ReadJpegObj(FP, Inbuf, ObjPtr)
4577 FILE *FP;
4578 char *Inbuf;
4579 struct ObjRec **ObjPtr;
4580 {
4581 struct XPmRec *xpm_ptr=NULL;
4582 char color_s[40], trans_color_s[40], *s=NULL, inbuf[MAXSTRING];
4583 char *jpeg_filename=NULL;
4584 int ltx, lty, rbx, rby, image_w=0, image_h=0;
4585 int ncolors, fill, color_index;
4586 int rotation, chars_per_pixel;
4587 int first_pixel_is_bg, first_pixel_maybe_bg, new_alloc;
4588 int id=0, rotate=ROTATE0, flip=NO_FLIP, locked=FALSE;
4589 int compressed=FALSE, real_x=0, real_y=0, real_type=0, linked_jpeg=FALSE;
4590 int transformed=FALSE, invisible=FALSE;
4591 struct XfrmMtrxRec *ctm=NULL;
4592 struct BBRec orig_obbox;
4593 struct ObjRec *new_obj_ptr=NULL;
4594
4595 *ObjPtr = NULL;
4596
4597 s = FindChar((int)'(', Inbuf);
4598 s = ParseStr(s, (int)',', color_s, sizeof(color_s));
4599 if (fileVersion >= 37) {
4600 s = ParseStr(s, (int)',', trans_color_s, sizeof(trans_color_s));
4601 }
4602 InitScan(s, "\t\n, ");
4603
4604 rotation = 0;
4605 chars_per_pixel = 1;
4606 first_pixel_maybe_bg = TRUE;
4607 first_pixel_is_bg = TRUE;
4608 if (fileVersion < 37) {
4609 sprintf(gszMsgBox,
4610 TgLoadCachedString(CSTID_INVALID_FILEVER_FOR_LINK_JPEG),
4611 fileVersion);
4612 if (PRTGIF) {
4613 fprintf(stderr, "%s\n", gszMsgBox);
4614 } else {
4615 Msg(gszMsgBox);
4616 }
4617 return;
4618 } else {
4619 if (GETINT("jpeg", ltx, "ltx") == INVALID ||
4620 GETINT("jpeg", lty, "lty") == INVALID ||
4621 GETINT("jpeg", rbx, "rbx") == INVALID ||
4622 GETINT("jpeg", rby, "rby") == INVALID ||
4623 GETINT("jpeg", fill, "fill") == INVALID ||
4624 GETINT("jpeg", ncolors, "ncolors") == INVALID ||
4625 GETINT("jpeg", chars_per_pixel, "chars_per_pixel") == INVALID ||
4626 GETINT("jpeg", first_pixel_is_bg,"first_pixel_is_bg") == INVALID ||
4627 GETINT("jpeg", id, "id") == INVALID ||
4628 GETINT("jpeg", rotation, "rotation") == INVALID ||
4629 GETINT("jpeg", image_w, "image_w") == INVALID ||
4630 GETINT("jpeg", image_h, "image_h") == INVALID ||
4631 GETINT("jpeg", rotate, "rotate") == INVALID ||
4632 GETINT("jpeg", flip, "flip") == INVALID ||
4633 GETINT("jpeg", locked, "locked") == INVALID ||
4634 GETINT("jpeg", compressed, "compressed") == INVALID ||
4635 GETINT("jpeg", transformed, "transformed") == INVALID ||
4636 GETINT("jpeg", invisible, "invisible") == INVALID ||
4637 GETINT("jpeg", real_type, "real_type") == INVALID ||
4638 GETINT("jpeg", linked_jpeg, "linked_jpeg") == INVALID) {
4639 return;
4640 }
4641 if (id >= objId) objId = id+1;
4642 first_pixel_maybe_bg = FALSE;
4643 }
4644 if (real_type == XPM_JPEG && linked_jpeg) {
4645 char *tmp_str=NULL;
4646
4647 (void)fgets(inbuf, MAXSTRING, FP);
4648 scanLineNum++;
4649
4650 tmp_str = FindChar((int)'"', inbuf);
4651 s = ReadString(tmp_str);
4652 *(--s) = '\0';
4653 jpeg_filename = UtilStrDup(tmp_str);
4654 if (jpeg_filename == NULL) FailAllocMessage();
4655 } else {
4656 strcpy(gszMsgBox, TgLoadString(STID_INVALID_PARAM_LINKED_JPEG));
4657 if (PRTGIF) {
4658 fprintf(stderr, "%s\n", gszMsgBox);
4659 } else {
4660 Msg(gszMsgBox);
4661 }
4662 return;
4663 }
4664 if (transformed) {
4665 (void)fgets(inbuf, MAXSTRING, FP);
4666 scanLineNum++;
4667 InitScan(inbuf, "\t\n, ");
4668
4669 ctm = (struct XfrmMtrxRec *)malloc(sizeof(struct XfrmMtrxRec));
4670 if (ctm == NULL) FailAllocMessage();
4671 if (GETINT("xpixmap", real_x, "real_x") == INVALID ||
4672 GETINT("xpixmap", real_y, "real_y") == INVALID ||
4673 GETINT("xpixmap", orig_obbox.ltx, "orig_obbox.ltx") == INVALID ||
4674 GETINT("xpixmap", orig_obbox.lty, "orig_obbox.lty") == INVALID ||
4675 GETINT("xpixmap", orig_obbox.rbx, "orig_obbox.rbx") == INVALID ||
4676 GETINT("xpixmap", orig_obbox.rby, "orig_obbox.rby") == INVALID ||
4677 GETDBL("xpixmap", ctm->m[CTM_SX], "CTM_SX") == INVALID ||
4678 GETDBL("xpixmap", ctm->m[CTM_SIN], "CTM_SIN") == INVALID ||
4679 GETDBL("xpixmap", ctm->m[CTM_MSIN], "CTM_MSIN") == INVALID ||
4680 GETDBL("xpixmap", ctm->m[CTM_SY], "CTM_SY") == INVALID ||
4681 GETINT("xpixmap", ctm->t[CTM_TX], "CTM_TX") == INVALID ||
4682 GETINT("xpixmap", ctm->t[CTM_TY], "CTM_TY") == INVALID) {
4683 return;
4684 }
4685 }
4686 fill = UpgradePenFill(fill);
4687
4688 if (!UtilPathExists(jpeg_filename)) {
4689 sprintf(gszMsgBox, TgLoadString(STID_INVALID_PATH_WHILE_READ_JPEG),
4690 jpeg_filename);
4691 if (PRTGIF) {
4692 fprintf(stderr, "%s\n", gszMsgBox);
4693 } else {
4694 Msg(gszMsgBox);
4695 }
4696 if (ctm != NULL) free(ctm);
4697 UtilFree(jpeg_filename);
4698 return;
4699 }
4700 if (PRTGIF && !cmdLineOpenDisplay) {
4701 new_obj_ptr = MyReadJpegFileSkipData(jpeg_filename, image_w, image_h);
4702 } else {
4703 new_obj_ptr = MyReadJpegFile(jpeg_filename, image_w, image_h);
4704 }
4705 if (new_obj_ptr == NULL) return;
4706
4707 new_obj_ptr->id = id;
4708 MoveObj(new_obj_ptr, ltx, lty);
4709 if (ctm != NULL) {
4710 new_obj_ptr->obbox.ltx = new_obj_ptr->bbox.ltx = new_obj_ptr->x = ltx;
4711 new_obj_ptr->obbox.lty = new_obj_ptr->bbox.lty = new_obj_ptr->y = lty;
4712 new_obj_ptr->obbox.rbx = new_obj_ptr->bbox.rbx = rbx;
4713 new_obj_ptr->obbox.rby = new_obj_ptr->bbox.rby = rby;
4714 new_obj_ptr->ctm = ctm;
4715
4716 memcpy(&new_obj_ptr->orig_obbox, &orig_obbox, sizeof(struct BBRec));
4717 new_obj_ptr->x = real_x;
4718 new_obj_ptr->y = real_y;
4719 GetTransformedOBBoxOffsetVs(new_obj_ptr, new_obj_ptr->rotated_obbox);
4720 }
4721 xpm_ptr = new_obj_ptr->detail.xpm;
4722
4723 xpm_ptr->real_type = real_type;
4724 xpm_ptr->linked_jpeg = linked_jpeg;
4725 xpm_ptr->filename = jpeg_filename;
4726
4727 color_index = QuickFindColorIndex(new_obj_ptr, color_s, &new_alloc, TRUE);
4728 new_obj_ptr->color = color_index;
4729 UtilStrCpyN(new_obj_ptr->color_str, sizeof(new_obj_ptr->color_str), color_s);
4730
4731 *ObjPtr = new_obj_ptr;
4732 }
4733
4734 static
MyReadPpmTrueFileSkipData(ppm_fname,expected_image_w,expected_image_h)4735 struct ObjRec *MyReadPpmTrueFileSkipData(ppm_fname, expected_image_w,
4736 expected_image_h)
4737 char *ppm_fname;
4738 int expected_image_w, expected_image_h;
4739 {
4740 FILE *ppm_fp=NULL;
4741 int format=0, image_w=0, image_h=0, max_val=0;
4742 struct ObjRec *obj_ptr=NULL;
4743 struct XPmRec *xpm_ptr=NULL;
4744
4745 ppm_fp = fopen(ppm_fname, "r");
4746 if (ppm_fp == NULL) {
4747 FailToOpenMessage(ppm_fname, "r", NULL);
4748 return NULL;
4749 }
4750 if (!ReadPpmHeader(ppm_fp, ppm_fname, &format, &image_w, &image_h,
4751 &max_val)) {
4752 fclose(ppm_fp);
4753 return NULL;
4754 }
4755 fclose(ppm_fp);
4756
4757 if (expected_image_w != (-1) && expected_image_h != (-1) &&
4758 (image_w != expected_image_w || image_h != expected_image_h)) {
4759 sprintf(gszMsgBox, TgLoadString(STID_PPM6_DIM_NOT_MATCH), image_w,
4760 image_h, ppm_fname, expected_image_w, expected_image_h);
4761 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4762 return NULL;
4763 }
4764 obj_ptr = CreateXPmObj(image_w, image_h, image_w, image_h, None, NULL, None,
4765 NULL, (-1), 1, FALSE, NULL, NULL, NULL, NULL);
4766 if (obj_ptr == NULL) return NULL;
4767
4768 xpm_ptr = obj_ptr->detail.xpm;
4769 UtilStrCpyN(xpm_ptr->tmp_ppm6_fname, sizeof(xpm_ptr->tmp_ppm6_fname),
4770 ppm_fname);
4771 xpm_ptr->real_type = PPM_TRUE;
4772
4773 return obj_ptr;
4774 }
4775
4776 static
MyReadPpmFile(ppm_fname,expected_image_w,expected_image_h)4777 struct ObjRec *MyReadPpmFile(ppm_fname, expected_image_w, expected_image_h)
4778 char *ppm_fname;
4779 int expected_image_w, expected_image_h;
4780 {
4781 char tmp_fname[MAXPATHLENGTH+1];
4782 int rc=0, ncolors=0, chars_per_pixel=0, *pixels=NULL;
4783 int first_pixel_is_bg=FALSE, image_w=0, image_h=0, w=0, h=0;
4784 Pixmap pixmap=None, bitmap=None;
4785 XImage *image=NULL, *bitmap_image=NULL;
4786 char *color_char, **color_str=NULL, *xpm_data=NULL;
4787 struct ObjRec *obj_ptr=NULL;
4788
4789 SetWatchCursor(drawWindow);
4790 SetWatchCursor(mainWindow);
4791 SaveStatusStrings();
4792 rc = ConvertPpmToXpm(ppm_fname, tmp_fname, sizeof(tmp_fname));
4793 RestoreStatusStrings();
4794 SetDefaultCursor(mainWindow);
4795 ShowCursor();
4796 if (!rc) {
4797 return NULL;
4798 }
4799 SetWatchCursor(drawWindow);
4800 SetWatchCursor(mainWindow);
4801 rc = MyReadPixmapFile(tmp_fname,
4802 &image_w, &image_h, &w, &h, &pixmap, &image, &bitmap, &bitmap_image,
4803 &ncolors, &chars_per_pixel, &first_pixel_is_bg, &color_char,
4804 &color_str, &pixels, &xpm_data);
4805 SetDefaultCursor(mainWindow);
4806 ShowCursor();
4807
4808 if (rc != BitmapSuccess) {
4809 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_IMPORT_XPM_FILE), tmp_fname);
4810 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4811 return NULL;
4812 }
4813 if (expected_image_w != (-1) && expected_image_h != (-1) &&
4814 (image_w != expected_image_w || image_h != expected_image_h)) {
4815 sprintf(gszMsgBox, TgLoadString(STID_PPM6_DIM_NOT_MATCH), image_w,
4816 image_h, ppm_fname, expected_image_w, expected_image_h);
4817 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4818 return NULL;
4819 }
4820 obj_ptr = CreateXPmObj(image_w, image_h, w, h, pixmap, image, bitmap,
4821 bitmap_image, ncolors, chars_per_pixel, first_pixel_is_bg, color_char,
4822 color_str, pixels, xpm_data);
4823
4824 unlink(tmp_fname);
4825
4826 return obj_ptr;
4827 }
4828
SetupTrueColorInfo(ptci)4829 int SetupTrueColorInfo(ptci)
4830 TrueColorInfo *ptci;
4831 {
4832 unsigned int r_mask=0, g_mask=0, b_mask=0;
4833 unsigned int r_maxval=0, g_maxval=0, b_maxval=0;
4834 unsigned int r_bits=0, g_bits=0, b_bits=0;
4835 int r_shift=(-1), g_shift=(-1), b_shift=(-1);
4836 unsigned int shifts=0;
4837
4838 ptci->r_mask = r_mask = mainVisual->red_mask;
4839 ptci->g_mask = g_mask = mainVisual->green_mask;
4840 ptci->b_mask = b_mask = mainVisual->blue_mask;
4841 for (shifts=0; r_mask|g_mask|b_mask; shifts++) {
4842 if (r_mask & 0x1) {
4843 if (r_shift == (-1)) {
4844 r_shift = shifts;
4845 r_maxval = r_mask;
4846 }
4847 r_bits++;
4848 }
4849 if (g_mask & 0x1) {
4850 if (g_shift == (-1)) {
4851 g_shift = shifts;
4852 g_maxval = g_mask;
4853 }
4854 g_bits++;
4855 }
4856 if (b_mask & 0x1) {
4857 if (b_shift == (-1)) {
4858 b_shift = shifts;
4859 b_maxval = b_mask;
4860 }
4861 b_bits++;
4862 }
4863 r_mask >>= 1;
4864 g_mask >>= 1;
4865 b_mask >>= 1;
4866 }
4867 ptci->r_shift = (unsigned int)r_shift;
4868 ptci->g_shift = (unsigned int)g_shift;
4869 ptci->b_shift = (unsigned int)b_shift;
4870 ptci->dr_maxval = (double)r_maxval;
4871 ptci->dg_maxval = (double)g_maxval;
4872 ptci->db_maxval = (double)b_maxval;
4873 ptci->dr_maxval_div255 = ptci->dr_maxval / ((double)255);
4874 ptci->dg_maxval_div255 = ptci->dg_maxval / ((double)255);
4875 ptci->db_maxval_div255 = ptci->db_maxval / ((double)255);
4876 ptci->num_r_bits = r_bits;
4877 ptci->num_g_bits = g_bits;
4878 ptci->num_b_bits = b_bits;
4879
4880 if (r_shift==(-1) || g_shift==(-1) || b_shift==(-1)) {
4881 #ifdef _TGIF_DBG /* debug, do not translate */
4882 TgAssert(FALSE, "unexpected error in SetupTrueColorInfo()", NULL);
4883 #endif /* _TGIF_DBG */
4884 return FALSE;
4885 }
4886 return TRUE;
4887 }
4888
4889 static
MyReadPpmTrueFile2(ppm_fname,expected_image_w,expected_image_h)4890 struct ObjRec *MyReadPpmTrueFile2(ppm_fname, expected_image_w, expected_image_h)
4891 char *ppm_fname;
4892 int expected_image_w, expected_image_h;
4893 {
4894 FILE *ppm_fp=NULL;
4895 int row=0, format=0, image_w=0, image_h=0, max_val=0;
4896 struct ObjRec *obj_ptr=NULL;
4897 struct XPmRec *xpm_ptr=NULL;
4898 Pixmap pixmap=None, bitmap=None;
4899 XImage *image=NULL, *bitmap_image=NULL;
4900 TrueColorInfo tci;
4901 double dmaxval=(double)0;
4902 int can_have_trans_pixel=FALSE, has_trans_pixel=FALSE;
4903 unsigned int trans_pixel_r=0, trans_pixel_g=0, trans_pixel_b=0;
4904
4905 memset(&tci, 0, sizeof(TrueColorInfo));
4906 if (!SetupTrueColorInfo(&tci)) return NULL;
4907
4908 ppm_fp = fopen(ppm_fname, "r");
4909 if (ppm_fp == NULL) {
4910 FailToOpenMessage(ppm_fname, "r", NULL);
4911 return NULL;
4912 }
4913 if (!ReadPpmHeader(ppm_fp, ppm_fname, &format, &image_w, &image_h,
4914 &max_val)) {
4915 fclose(ppm_fp);
4916 return NULL;
4917 }
4918 if (max_val != 255 && max_val != 65535) {
4919 sprintf(gszMsgBox, TgLoadString(STID_UNSUP_PPM6_MAX_VAL), max_val,
4920 ppm_fname);
4921 if (PRTGIF) {
4922 fprintf(stderr, "%s\n", gszMsgBox);
4923 } else {
4924 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4925 }
4926 fclose(ppm_fp);
4927 return NULL;
4928 }
4929 if (expected_image_w != (-1) && expected_image_h != (-1) &&
4930 (image_w != expected_image_w || image_h != expected_image_h)) {
4931 sprintf(gszMsgBox, TgLoadString(STID_PPM6_DIM_NOT_MATCH), image_w,
4932 image_h, ppm_fname, expected_image_w, expected_image_h);
4933 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4934 fclose(ppm_fp);
4935 return NULL;
4936 }
4937 dmaxval = (double)255;
4938
4939 pixmap = XCreatePixmap(mainDisplay, mainWindow, image_w, image_h, mainDepth);
4940 bitmap = XCreatePixmap(mainDisplay, dummyBitmap, image_w, image_h, 1);
4941 if (pixmap == None || bitmap == None) {
4942 if (pixmap != None) XFreePixmap(mainDisplay, pixmap);
4943 if (bitmap != None) XFreePixmap(mainDisplay, bitmap);
4944 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_ALLOC_PIXMAP_OF_SIZE),
4945 image_w, image_h);
4946 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4947 fclose(ppm_fp);
4948 return NULL;
4949 }
4950 XFillRectangle(mainDisplay, pixmap, xpmGC, 0, 0, image_w, image_h);
4951
4952 XSetForeground(mainDisplay, xbmGC, 1);
4953 XFillRectangle(mainDisplay, bitmap, xbmGC, 0, 0, image_w, image_h);
4954 XSetForeground(mainDisplay, xbmGC, 0);
4955 bitmap_image = XGetImage(mainDisplay, bitmap, 0, 0, image_w, image_h, 1,
4956 ZPixmap);
4957 image = XGetImage(mainDisplay, pixmap, 0, 0, image_w, image_h, AllPlanes,
4958 ZPixmap);
4959 if (image == NULL || bitmap_image == NULL) {
4960 XFreePixmap(mainDisplay, pixmap);
4961 XFreePixmap(mainDisplay, bitmap);
4962 if (image != NULL) XDestroyImage(image);
4963 if (bitmap_image != NULL) XDestroyImage(bitmap_image);
4964 MsgBox(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM), TOOL_NAME, INFO_MB);
4965 return NULL;
4966 }
4967 if (gPngHeaderInfo.valid && gPngHeaderInfo.trans_color_pixel_found) {
4968 can_have_trans_pixel = TRUE;
4969 trans_pixel_r = (unsigned int)gPngHeaderInfo.trans_color_pixel_red;
4970 trans_pixel_g = (unsigned int)gPngHeaderInfo.trans_color_pixel_green;
4971 trans_pixel_b = (unsigned int)gPngHeaderInfo.trans_color_pixel_blue;
4972 if (max_val == 65535) {
4973 trans_pixel_r = trans_pixel_r | ((trans_pixel_r<<8)&0x0ff00);
4974 trans_pixel_g = trans_pixel_g | ((trans_pixel_g<<8)&0x0ff00);
4975 trans_pixel_b = trans_pixel_b | ((trans_pixel_b<<8)&0x0ff00);
4976 }
4977 }
4978 for (row=0; row < image_h; row++) {
4979 int col=0;
4980
4981 for (col=0; col < image_w; col++) {
4982 unsigned char buf[3];
4983 unsigned int r=0, g=0, b=0;
4984 double dr=(double)0, dg=(double)0, db=(double)0;
4985 int bytes_read=0;
4986 uint32_t pixel=0;
4987
4988 if (format == TYPE_PPM6) {
4989 if (max_val == 65535) {
4990 unsigned char r_buf[2], g_buf[2], b_buf[2];
4991
4992 if (fread(r_buf, sizeof(char), 2, ppm_fp) != 2 ||
4993 fread(g_buf, sizeof(char), 2, ppm_fp) != 2 ||
4994 fread(b_buf, sizeof(char), 2, ppm_fp) != 2) {
4995 XFreePixmap(mainDisplay, pixmap);
4996 XFreePixmap(mainDisplay, bitmap);
4997 sprintf(gszMsgBox,
4998 TgLoadString(STID_CANNOT_ALLOC_PIXMAP_OF_SIZE),
4999 image_w, image_h);
5000 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
5001 fclose(ppm_fp);
5002 return NULL;
5003 }
5004 if (littleEndianPpm6) {
5005 buf[0] = r_buf[1];
5006 buf[1] = g_buf[1];
5007 buf[2] = b_buf[1];
5008 } else {
5009 buf[0] = r_buf[0];
5010 buf[1] = g_buf[0];
5011 buf[2] = b_buf[0];
5012 }
5013 } else {
5014 if ((bytes_read=fread(buf, sizeof(char), 3, ppm_fp)) != 3) {
5015 XFreePixmap(mainDisplay, pixmap);
5016 XFreePixmap(mainDisplay, bitmap);
5017 sprintf(gszMsgBox,
5018 TgLoadString(STID_CANNOT_ALLOC_PIXMAP_OF_SIZE),
5019 image_w, image_h);
5020 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
5021 fclose(ppm_fp);
5022 return NULL;
5023 }
5024 }
5025 } else if (format == TYPE_PPM5) {
5026 if (max_val == 65535) {
5027 unsigned char g_buf[2];
5028
5029 if (fread(g_buf, sizeof(char), 2, ppm_fp) != 2) {
5030 XFreePixmap(mainDisplay, pixmap);
5031 XFreePixmap(mainDisplay, bitmap);
5032 sprintf(gszMsgBox,
5033 TgLoadString(STID_CANNOT_ALLOC_PIXMAP_OF_SIZE),
5034 image_w, image_h);
5035 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
5036 fclose(ppm_fp);
5037 return NULL;
5038 }
5039 if (littleEndianPpm6) {
5040 buf[0] = buf[1] = buf[2] = g_buf[1];
5041 } else {
5042 buf[0] = buf[1] = buf[2] = g_buf[0];
5043 }
5044 } else {
5045 if ((bytes_read=fread(buf, sizeof(char), 1, ppm_fp)) != 1) {
5046 XFreePixmap(mainDisplay, pixmap);
5047 XFreePixmap(mainDisplay, bitmap);
5048 sprintf(gszMsgBox,
5049 TgLoadString(STID_CANNOT_ALLOC_PIXMAP_OF_SIZE),
5050 image_w, image_h);
5051 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
5052 fclose(ppm_fp);
5053 return NULL;
5054 }
5055 buf[1] = buf[2] = buf[0];
5056 }
5057 } else {
5058 int red=0, green=0, blue=0;
5059
5060 if (fscanf(ppm_fp, "%d %d %d", &red, &green, &blue) != 3) {
5061 XFreePixmap(mainDisplay, pixmap);
5062 XFreePixmap(mainDisplay, bitmap);
5063 sprintf(gszMsgBox,
5064 TgLoadString(STID_CANNOT_ALLOC_PIXMAP_OF_SIZE),
5065 image_w, image_h);
5066 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
5067 fclose(ppm_fp);
5068 return NULL;
5069 }
5070 buf[0] = (unsigned char)(red & 0x0ff);
5071 buf[1] = (unsigned char)(green & 0x0ff);
5072 buf[2] = (unsigned char)(blue & 0x0ff);
5073 }
5074 r = (unsigned int)buf[0];
5075 g = (unsigned int)buf[1];
5076 b = (unsigned int)buf[2];
5077 dr = ((double)r) / dmaxval * tci.dr_maxval;
5078 dg = ((double)g) / dmaxval * tci.dg_maxval;
5079 db = ((double)b) / dmaxval * tci.db_maxval;
5080 r = round(dr);
5081 g = round(dg);
5082 b = round(db);
5083 pixel = ((r << tci.r_shift) & mainVisual->red_mask) |
5084 ((g << tci.g_shift) & mainVisual->green_mask) |
5085 ((b << tci.b_shift) & mainVisual->blue_mask) ;
5086 XPutPixel(image, col, row, pixel);
5087 if (can_have_trans_pixel && trans_pixel_r == r &&
5088 trans_pixel_g == g && trans_pixel_b == b) {
5089 XPutPixel(bitmap_image, col, row, 0);
5090 has_trans_pixel = TRUE;
5091 }
5092 }
5093 }
5094 fclose(ppm_fp);
5095
5096 XPutImage(mainDisplay, pixmap, xpmGC, image, 0, 0, 0, 0, image_w, image_h);
5097 if (has_trans_pixel) {
5098 XPutImage(mainDisplay, bitmap, xbmGC, bitmap_image, 0, 0, 0, 0,
5099 image_w, image_h);
5100 } else {
5101 /*
5102 * It seems to be a waste not to do the following. But it's done
5103 * this way so that other code (such as in "dup.c") do not
5104 * have to be changed.
5105 *
5106 * XDestroyImage(bitmap_image);
5107 * XFreePixmap(mainDisplay, bitmap);
5108 * bitmap_image = NULL;
5109 * bitmap = None;
5110 */
5111 }
5112 obj_ptr = CreateXPmObj(image_w, image_h, image_w, image_h, pixmap, image,
5113 bitmap, bitmap_image, 0, 0, FALSE, NULL, NULL, NULL, NULL);
5114 xpm_ptr = obj_ptr->detail.xpm;
5115 xpm_ptr->real_type = PPM_TRUE;
5116 if (obj_ptr == NULL) return NULL;
5117
5118 return obj_ptr;
5119 }
5120
5121 static
MyReadPpmTrueFile(ppm_fname,expected_image_w,expected_image_h)5122 struct ObjRec *MyReadPpmTrueFile(ppm_fname, expected_image_w, expected_image_h)
5123 char *ppm_fname;
5124 int expected_image_w, expected_image_h;
5125 {
5126 struct ObjRec *obj_ptr=NULL;
5127 struct XPmRec *xpm_ptr=NULL;
5128
5129 if (PRTGIF && !cmdLineOpenDisplay) {
5130 obj_ptr = MyReadPpmTrueFileSkipData(ppm_fname, expected_image_w,
5131 expected_image_h);
5132 } else {
5133 if (fullTrueColorMode && HasZlibSupport()) {
5134 obj_ptr = MyReadPpmTrueFile2(ppm_fname, expected_image_w,
5135 expected_image_h);
5136 if (obj_ptr != NULL) {
5137 MoveObj(obj_ptr, -drawOrigX, -drawOrigY);
5138
5139 return obj_ptr;
5140 } else {
5141 return NULL;
5142 }
5143 }
5144 obj_ptr = MyReadPpmFile(ppm_fname, expected_image_w, expected_image_h);
5145 if (obj_ptr == NULL) {
5146 return NULL;
5147 }
5148 xpm_ptr = obj_ptr->detail.xpm;
5149 xpm_ptr->real_type = XPM_XPM;
5150 }
5151 MoveObj(obj_ptr, -drawOrigX, -drawOrigY);
5152
5153 return obj_ptr;
5154 }
5155
CreatePpmTrueObjFromFile(ppm_fname)5156 struct ObjRec *CreatePpmTrueObjFromFile(ppm_fname)
5157 char *ppm_fname;
5158 {
5159 return MyReadPpmTrueFile(ppm_fname, (-1), (-1));
5160 }
5161
ReadPpmTrueObj(FP,Inbuf,ObjPtr)5162 void ReadPpmTrueObj(FP, Inbuf, ObjPtr)
5163 FILE *FP;
5164 char *Inbuf;
5165 struct ObjRec **ObjPtr;
5166 {
5167 struct XPmRec *xpm_ptr=NULL;
5168 char *s=NULL, inbuf[MAXSTRING], *ppm_data=NULL, *ppm_mask_data=NULL;
5169 char color_s[40], trans_color_s[40], tmp_fname[MAXPATHLENGTH];
5170 int ltx=0, lty=0, rbx=0, rby=0, image_w=0, image_h=0, color_index=(-1);
5171 int rotation=0, new_alloc=FALSE, id=0, rotate=ROTATE0, flip=NO_FLIP;
5172 int locked=FALSE, has_transp_color=FALSE, real_x=0, real_y=0;
5173 int transformed=FALSE, invisible=FALSE;
5174 int ppm_data_compress=FALSE, ppm_data_size=0, ppm_mask_size=0;
5175 struct XfrmMtrxRec *ctm=NULL;
5176 struct BBRec orig_obbox;
5177 struct ObjRec *new_obj_ptr=NULL;
5178 unsigned char trans_color_pixel_r='\0', trans_color_pixel_g='\0', trans_color_pixel_b='\0';
5179
5180 *ObjPtr = NULL;
5181
5182 s = FindChar((int)'(', Inbuf);
5183 s = ParseStr(s, (int)',', color_s, sizeof(color_s));
5184 s = ParseStr(s, (int)',', trans_color_s, sizeof(trans_color_s));
5185 InitScan(s, "\t\n, ");
5186
5187 rotation = 0;
5188 if (fileVersion < 37) {
5189 sprintf(gszMsgBox,
5190 TgLoadCachedString(CSTID_INVALID_FILEVER_FOR_LINK_JPEG),
5191 fileVersion);
5192 if (PRTGIF) {
5193 fprintf(stderr, "%s\n", gszMsgBox);
5194 } else {
5195 Msg(gszMsgBox);
5196 }
5197 return;
5198 } else {
5199 if (GETINT("ppm_true", has_transp_color, "has_transparent_color") == INVALID ||
5200 GETINT("ppm_true", ltx, "ltx") == INVALID ||
5201 GETINT("ppm_true", lty, "lty") == INVALID ||
5202 GETINT("ppm_true", rbx, "rbx") == INVALID ||
5203 GETINT("ppm_true", rby, "rby") == INVALID ||
5204 GETINT("ppm_true", id, "id") == INVALID ||
5205 GETINT("ppm_true", rotation, "rotation") == INVALID ||
5206 GETINT("ppm_true", image_w, "image_w") == INVALID ||
5207 GETINT("ppm_true", image_h, "image_h") == INVALID ||
5208 GETINT("ppm_true", rotate, "rotate") == INVALID ||
5209 GETINT("ppm_true", flip, "flip") == INVALID ||
5210 GETINT("ppm_true", locked, "locked") == INVALID ||
5211 GETINT("ppm_true", transformed, "transformed") == INVALID ||
5212 GETINT("ppm_true", invisible, "invisible") == INVALID ||
5213 GETINT("ppm_true", ppm_data_compress,"ppm_data_compress") == INVALID ||
5214 GETINT("ppm_true", ppm_data_size, "ppm_data_size") == INVALID ||
5215 GETINT("ppm_true", ppm_mask_size, "ppm_mask_size") == INVALID) {
5216 return;
5217 }
5218 if (id >= objId) objId = id+1;
5219 }
5220 if (ppm_data_compress == PPM_JPEG_COMPRESS) {
5221 /* this is fine */
5222 } else if (ppm_data_compress == PPM_DATA_DEFLATED) {
5223 if (!HasZlibSupport()) {
5224 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_INFLATE_GIVEN_OBJ),
5225 "ppm_true", TOOL_NAME);
5226 if (PRTGIF) {
5227 fprintf(stderr, "%s\n", gszMsgBox);
5228 } else {
5229 Msg(gszMsgBox);
5230 }
5231 return;
5232 }
5233 } else {
5234 /* including PPM_DATA_RAW -- not supported, must be an error */
5235 sprintf(gszMsgBox, TgLoadString(STID_INVALID_GIVEN_PARAM_GIVEN_OBJ),
5236 "ppm_data_compress", "ppm_true");
5237 if (PRTGIF) {
5238 fprintf(stderr, "%s\n", gszMsgBox);
5239 } else {
5240 Msg(gszMsgBox);
5241 }
5242 return;
5243 }
5244 if (transformed) {
5245 (void)fgets(inbuf, MAXSTRING, FP);
5246 scanLineNum++;
5247 InitScan(inbuf, "\t\n, ");
5248
5249 ctm = (struct XfrmMtrxRec *)malloc(sizeof(struct XfrmMtrxRec));
5250 if (ctm == NULL) FailAllocMessage();
5251 if (GETINT("xpixmap", real_x, "real_x") == INVALID ||
5252 GETINT("xpixmap", real_y, "real_y") == INVALID ||
5253 GETINT("xpixmap", orig_obbox.ltx, "orig_obbox.ltx") == INVALID ||
5254 GETINT("xpixmap", orig_obbox.lty, "orig_obbox.lty") == INVALID ||
5255 GETINT("xpixmap", orig_obbox.rbx, "orig_obbox.rbx") == INVALID ||
5256 GETINT("xpixmap", orig_obbox.rby, "orig_obbox.rby") == INVALID ||
5257 GETDBL("xpixmap", ctm->m[CTM_SX], "CTM_SX") == INVALID ||
5258 GETDBL("xpixmap", ctm->m[CTM_SIN], "CTM_SIN") == INVALID ||
5259 GETDBL("xpixmap", ctm->m[CTM_MSIN], "CTM_MSIN") == INVALID ||
5260 GETDBL("xpixmap", ctm->m[CTM_SY], "CTM_SY") == INVALID ||
5261 GETINT("xpixmap", ctm->t[CTM_TX], "CTM_TX") == INVALID ||
5262 GETINT("xpixmap", ctm->t[CTM_TY], "CTM_TY") == INVALID) {
5263 return;
5264 }
5265 }
5266 ppm_data = ReadPpmTrueData(FP, ppm_data_size);
5267 ppm_mask_data = ReadPpmTrueMask(FP, ppm_mask_size);
5268 if (ppm_data == NULL) return;
5269
5270 *tmp_fname = '\0';
5271 if (IsPpmTrueObj(PPM_TRUE, ppm_data_compress, ppm_data)) {
5272 if (!ConvertPpmTrueToPpm6(ppm_data, ppm_data_size, ppm_data_compress,
5273 tmp_fname, sizeof(tmp_fname))) {
5274 UtilFree(ppm_data);
5275 return;
5276 }
5277 } else {
5278 #ifdef _TGIF_DBG /* debug, do not translate */
5279 TgAssert(FALSE, "unsupported format in ReadPpmTrueObj()", NULL);
5280 #endif /* _TGIF_DBG */
5281 }
5282 if (has_transp_color) {
5283 if (!ParseTransColor(trans_color_s, &trans_color_pixel_r,
5284 &trans_color_pixel_g, &trans_color_pixel_b)) {
5285 strcpy(gszMsgBox, TgLoadString(STID_BAD_TRANS_COLOR_NO_TRANS));
5286 if (PRTGIF && !cmdLineOpenDisplay) {
5287 fprintf(stderr, "%s\n", gszMsgBox);
5288 } else {
5289 Msg(gszMsgBox);
5290 }
5291 has_transp_color = FALSE;
5292 }
5293 }
5294 ResetPngHeaderInfo(&gPngHeaderInfo);
5295 if (has_transp_color) {
5296 SetPngHeaderInfoForTransColor(&gPngHeaderInfo, trans_color_pixel_r,
5297 trans_color_pixel_g, trans_color_pixel_b);
5298 }
5299 new_obj_ptr = MyReadPpmTrueFile(tmp_fname, image_w, image_h);
5300 ResetPngHeaderInfo(&gPngHeaderInfo);
5301 if (new_obj_ptr == NULL) {
5302 unlink(tmp_fname);
5303 UtilFree(ppm_data);
5304 return;
5305 }
5306 unlink(tmp_fname);
5307 /* must set real_type set in MyReadPpmTrueFile() */
5308
5309 color_index = QuickFindColorIndex(new_obj_ptr, color_s, &new_alloc, TRUE);
5310 new_obj_ptr->color = color_index;
5311 UtilStrCpyN(new_obj_ptr->color_str, sizeof(new_obj_ptr->color_str), color_s);
5312 new_obj_ptr->id = id;
5313 MoveObj(new_obj_ptr, ltx, lty);
5314 if (ctm != NULL) {
5315 new_obj_ptr->obbox.ltx = new_obj_ptr->bbox.ltx = new_obj_ptr->x = ltx;
5316 new_obj_ptr->obbox.lty = new_obj_ptr->bbox.lty = new_obj_ptr->y = lty;
5317 new_obj_ptr->obbox.rbx = new_obj_ptr->bbox.rbx = rbx;
5318 new_obj_ptr->obbox.rby = new_obj_ptr->bbox.rby = rby;
5319 new_obj_ptr->ctm = ctm;
5320
5321 memcpy(&new_obj_ptr->orig_obbox, &orig_obbox, sizeof(struct BBRec));
5322 new_obj_ptr->x = real_x;
5323 new_obj_ptr->y = real_y;
5324 GetTransformedOBBoxOffsetVs(new_obj_ptr, new_obj_ptr->rotated_obbox);
5325 }
5326 xpm_ptr = new_obj_ptr->detail.xpm;
5327
5328 if (xpm_ptr->real_type == PPM_TRUE) {
5329 xpm_ptr->ppm_data_compress = ppm_data_compress;
5330 xpm_ptr->ppm_data = ppm_data;
5331 xpm_ptr->ppm_mask_data = NULL;
5332 xpm_ptr->ppm_mask_size = 0;
5333 xpm_ptr->ppm_data_size = ppm_data_size;
5334 xpm_ptr->has_transparent_color = has_transp_color;
5335 if (xpm_ptr->has_transparent_color) {
5336 xpm_ptr->transparent_color[0] = trans_color_pixel_r;
5337 xpm_ptr->transparent_color[1] = trans_color_pixel_g;
5338 xpm_ptr->transparent_color[2] = trans_color_pixel_b;
5339 }
5340 } else {
5341 /* something didn't work, revert back to a regular XPM object */
5342 if (!PRTGIF || cmdLineOpenDisplay) {
5343 UtilStrCpyN(gszMsgBox, sizeof(gszMsgBox),
5344 TgLoadString(STID_PPM_TRUE_LOSSY_CONV_TO_XPM));
5345 Msg(gszMsgBox);
5346 SetFileModified(TRUE);
5347 }
5348 UtilFree(ppm_data);
5349 }
5350 *ObjPtr = new_obj_ptr;
5351 }
5352
SetXPmPropMask(ObjPtr,plMask,plSkip,pProp)5353 void SetXPmPropMask(ObjPtr, plMask, plSkip, pProp)
5354 struct ObjRec *ObjPtr;
5355 long *plMask, *plSkip;
5356 struct PropertiesRec *pProp;
5357 {
5358 SetCTMPropertyMask(ObjPtr->ctm, plMask, plSkip, pProp);
5359 }
5360
FreeXPmObj(ObjPtr)5361 void FreeXPmObj(ObjPtr)
5362 struct ObjRec *ObjPtr;
5363 {
5364 register int i, ncolors;
5365 struct XPmRec *xpm_ptr=ObjPtr->detail.xpm;
5366
5367 if (xpm_ptr->pixmap != None) {
5368 if (xpm_ptr->pixels != NULL) free(xpm_ptr->pixels);
5369 if (xpm_ptr->red != NULL) free(xpm_ptr->red);
5370 if (xpm_ptr->green != NULL) free(xpm_ptr->green);
5371 if (xpm_ptr->blue != NULL) free(xpm_ptr->blue);
5372 if (xpm_ptr->color_char != NULL) free(xpm_ptr->color_char);
5373 if (xpm_ptr->color_str != NULL) {
5374 ncolors = xpm_ptr->ncolors;
5375 for (i = 0; i < ncolors; i++) free(xpm_ptr->color_str[i]);
5376 free(xpm_ptr->color_str);
5377 }
5378 XFreePixmap(mainDisplay, xpm_ptr->pixmap);
5379 }
5380 if (xpm_ptr->bitmap != None) XFreePixmap(mainDisplay, xpm_ptr->bitmap);
5381 if (xpm_ptr->image != NULL) XDestroyImage(xpm_ptr->image);
5382 if (xpm_ptr->bitmap_image != NULL) XDestroyImage(xpm_ptr->bitmap_image);
5383 if (xpm_ptr->cached_pixmap != None) {
5384 XFreePixmap(mainDisplay, xpm_ptr->cached_pixmap);
5385 }
5386 if (xpm_ptr->cached_bitmap != None) {
5387 XFreePixmap(mainDisplay, xpm_ptr->cached_bitmap);
5388 }
5389 if (xpm_ptr->clip_mask != None) {
5390 XFreePixmap(mainDisplay, xpm_ptr->clip_mask);
5391 }
5392 if (xpm_ptr->data != NULL) free(xpm_ptr->data);
5393 if (xpm_ptr->filename != NULL) free(xpm_ptr->filename);
5394 if (xpm_ptr->ppm_data != NULL) free(xpm_ptr->ppm_data);
5395 if (xpm_ptr->ppm_mask_data != NULL) free(xpm_ptr->ppm_mask_data);
5396 free(xpm_ptr);
5397 free(ObjPtr);
5398 }
5399