Graphviz  2.41.20171026.1811
gvdevice_gd.c
Go to the documentation of this file.
1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 #include "config.h"
15 
16 #include "gvplugin_device.h"
17 #include "gvio.h"
18 
19 #include "gd.h"
20 
21 int gvdevice_gd_putBuf (gdIOCtx *context, const void *buffer, int len)
22 {
23  return gvwrite((GVJ_t *)(context->tell), buffer, len);
24 }
25 
26 /* used by gif output */
27 void gvdevice_gd_putC (gdIOCtx *context, int C)
28 {
29  char c = C;
30 
31  gvwrite((GVJ_t *)(context->tell), &c, 1);
32 }
33 
34 #ifdef HAVE_PANGOCAIRO
35 typedef enum {
36  FORMAT_GIF,
38  FORMAT_PNG,
40  FORMAT_GD,
41  FORMAT_GD2,
42  FORMAT_XBM,
43 } format_type;
44 
45 static void gd_format(GVJ_t * job)
46 {
47  gdImagePtr im;
48  unsigned int x, y, color, alpha;
49  unsigned int *data = (unsigned int*)(job->imagedata);
50  unsigned int width = job->width;
51  unsigned int height = job->height;
52  gdIOCtx ctx;
53 
54  ctx.putBuf = gvdevice_gd_putBuf;
55  ctx.putC = gvdevice_gd_putC;
56  ctx.tell = (void*)job; /* hide *job here */
57 
58  im = gdImageCreateTrueColor(width, height);
59  switch (job->device.id) {
60 #ifdef HAVE_GD_PNG
61  case FORMAT_PNG:
62  for (y = 0; y < height; y++) {
63  for (x = 0; x < width; x++) {
64  color = *data++;
65  /* gd's max alpha is 127 */
66  /* so right-shift 25 to lose lsb of alpha */
67  alpha = (color >> 25) & 0x7f;
68  im->tpixels[y][x] = (color & 0xffffff) | ((0x7f - alpha) << 24);
69  }
70  }
71  break;
72 #endif
73  default:
74 /* pick an off-white color, so that transparent backgrounds look white in jpgs */
75 #define TRANSPARENT 0x7ffffffe
76 
77  gdImageColorTransparent(im, TRANSPARENT);
78  gdImageAlphaBlending(im, FALSE);
79  for (y = 0; y < height; y++) {
80  for (x = 0; x < width; x++) {
81  color = *data++;
82  /* gd's max alpha is 127 */
83  /* so right-shift 25 to lose lsb of alpha */
84  if ((alpha = (color >> 25) & 0x7f) >= 0x20)
85  /* if not > 75% transparent */
86  im->tpixels[y][x] = (color & 0xffffff) | ((0x7f - alpha) << 24);
87  else
88  im->tpixels[y][x] = TRANSPARENT;
89  }
90  }
91  break;
92  }
93 
94  switch (job->device.id) {
95 #ifdef HAVE_GD_GIF
96  case FORMAT_GIF:
97  gdImageTrueColorToPalette(im, 0, 256);
98  gdImageGifCtx(im, &ctx);
99  break;
100 #endif
101 
102 #ifdef HAVE_GD_JPEG
103  case FORMAT_JPEG:
104  /*
105  * Write IM to OUTFILE as a JFIF-formatted JPEG image, using
106  * quality JPEG_QUALITY. If JPEG_QUALITY is in the range
107  * 0-100, increasing values represent higher quality but also
108  * larger image size. If JPEG_QUALITY is negative, the
109  * IJG JPEG library's default quality is used (which should
110  * be near optimal for many applications). See the IJG JPEG
111  * library documentation for more details.
112  */
113 #define JPEG_QUALITY -1
114  gdImageJpegCtx(im, &ctx, JPEG_QUALITY);
115  break;
116 #endif
117 
118 #ifdef HAVE_GD_PNG
119  case FORMAT_PNG:
120  gdImageTrueColorToPalette(im, 0, 256);
121  gdImagePngCtx(im, &ctx);
122  break;
123 #endif
124 
125  case FORMAT_GD:
126  gdImageGd(im, job->output_file);
127  break;
128 
129  case FORMAT_GD2:
130 #define GD2_CHUNKSIZE 128
131 #define GD2_RAW 1
132 #define GD2_COMPRESSED 2
133  gdImageGd2(im, job->output_file, GD2_CHUNKSIZE, GD2_COMPRESSED);
134  break;
135 
136 #ifdef HAVE_GD_GIF
137  case FORMAT_WBMP:
138  {
139  /* Use black for the foreground color for the B&W wbmp image. */
140  int black = gdImageColorResolveAlpha(im, 0, 0, 0, gdAlphaOpaque);
141  gdImageWBMPCtx(im, black, &ctx);
142  }
143  break;
144 #endif
145 
146 #if 0
147 /* libgd only supports reading of xpm files */
148 #ifdef HAVE_GD_XPM
149  case FORMAT_XBM:
150  gdImageXbm(im, job->output_file);
151 #endif
152 #endif
153  break;
154  default:
155  break;
156  }
157 
158  gdImageDestroy(im);
159 }
160 
161 static gvdevice_engine_t gd_engine = {
162  NULL, /* gd_initialize */
163  gd_format,
164  NULL, /* gd_finalize */
165 };
166 
167 static gvdevice_features_t device_features_gd = {
169  | GVDEVICE_DOES_TRUECOLOR,/* flags */
170  {0.,0.}, /* default margin - points */
171  {0.,0.}, /* default page width, height - points */
172  {96.,96.}, /* dpi */
173 };
174 
175 static gvdevice_features_t device_features_gd_no_writer = {
178  | GVDEVICE_DOES_TRUECOLOR,/* flags */
179  {0.,0.}, /* default margin - points */
180  {0.,0.}, /* default page width, height - points */
181  {96.,96.}, /* dpi */
182 };
183 #endif
184 
186 #ifdef HAVE_PANGOCAIRO
187 
188 #ifdef HAVE_GD_GIF
189  {FORMAT_GIF, "gif:cairo", 10, &gd_engine, &device_features_gd},
190  {FORMAT_WBMP, "wbmp:cairo", 5, &gd_engine, &device_features_gd},
191 #endif
192 
193 #ifdef HAVE_GD_JPEG
194  {FORMAT_JPEG, "jpe:cairo", 5, &gd_engine, &device_features_gd},
195  {FORMAT_JPEG, "jpeg:cairo", 5, &gd_engine, &device_features_gd},
196  {FORMAT_JPEG, "jpg:cairo", 5, &gd_engine, &device_features_gd},
197 #endif
198 
199 #ifdef HAVE_GD_PNG
200  {FORMAT_PNG, "png:cairo", 5, &gd_engine, &device_features_gd},
201 #endif
202 
203  {FORMAT_GD, "gd:cairo", 5, &gd_engine, &device_features_gd_no_writer},
204  {FORMAT_GD2, "gd2:cairo", 5, &gd_engine, &device_features_gd_no_writer},
205 
206 #if 0
207 /* libgd only supports reading of xpm files */
208 #ifdef HAVE_GD_XPM
209  {FORMAT_XBM, "xbm:cairo", 5, &gd_engine, &device_features_gd},
210 #endif
211 #endif
212 
213 #endif
214  {0, NULL, 0, NULL, NULL}
215 };
char * imagedata
Definition: gvcjob.h:306
#define GVDEVICE_BINARY_FORMAT
Definition: gvcjob.h:93
#define C
Definition: pack.c:29
unsigned int width
Definition: gvcjob.h:336
Definition: gvcjob.h:271
gvplugin_active_device_t device
Definition: gvcjob.h:295
#define GVDEVICE_NO_WRITER
Definition: gvcjob.h:95
format_type
#define NULL
Definition: logic.h:39
void gvdevice_gd_putC(gdIOCtx *context, int C)
Definition: gvdevice_gd.c:27
#define alpha
Definition: shapes.c:3902
int gvdevice_gd_putBuf(gdIOCtx *context, const void *buffer, int len)
Definition: gvdevice_gd.c:21
gvplugin_installed_t gvdevice_gd_types[]
Definition: gvdevice_gd.c:185
FILE * output_file
Definition: gvcjob.h:286
unsigned int height
Definition: gvcjob.h:337
#define FALSE
Definition: cgraph.h:35
Definition: legal.c:60
size_t gvwrite(GVJ_t *job, const char *s, size_t len)
Definition: gvdevice.c:190
#define GVDEVICE_DOES_TRUECOLOR
Definition: gvcjob.h:92