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