Graphviz 13.0.0~dev.20241220.2304
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 <assert.h>
15#include <gvc/gvplugin_device.h>
16#include <gvc/gvio.h>
17#include <limits.h>
18
19#include <gd.h>
20#include <stdbool.h>
21#include <stddef.h>
22#include <string.h>
23
24int gvdevice_gd_putBuf (gdIOCtx *context, const void *buffer, int len)
25{
26 gd_context_t *gd_context = get_containing_context(context);
27 assert(len >= 0);
28 const size_t result = gvwrite(gd_context->job, buffer, (size_t)len);
29 assert(result <= (size_t)len);
30 return (int)result;
31}
32
33void gvdevice_gd_putC (gdIOCtx *context, int C)
34{
35 gd_context_t *gd_context = get_containing_context(context);
36 char c = (char)C;
37
38 gvwrite(gd_context->job, &c, 1);
39}
40
41#ifdef HAVE_PANGOCAIRO
42typedef enum {
51
52static void gd_format(GVJ_t * job)
53{
54 gdImagePtr im;
55 unsigned int x, y;
56 const unsigned char *data = job->imagedata;
57 unsigned int width = job->width;
58 unsigned int height = job->height;
59 gd_context_t gd_context;
60 memset(&gd_context, 0, sizeof(gd_context));
61
62 gd_context.ctx.putBuf = gvdevice_gd_putBuf;
63 gd_context.ctx.putC = gvdevice_gd_putC;
64 gd_context.job = job;
65
66 assert(width <= INT_MAX);
67 assert(height <= INT_MAX);
68 im = gdImageCreateTrueColor((int)width, (int)height);
69 switch (job->device.id) {
70#ifdef HAVE_GD_PNG
71 case FORMAT_PNG:
72 for (y = 0; y < height; y++) {
73 for (x = 0; x < width; x++) {
74 const int r = *data++;
75 const int g = *data++;
76 const int b = *data++;
77 // gd’s alpha is 7-bit, so scale down ÷2 from our 8-bit
78 const int alpha = *data++ >> 1;
79 const int color = r | (g << 8) | (b << 16) | ((0x7f - alpha) << 24);
80 im->tpixels[y][x] = color;
81 }
82 }
83 break;
84#endif
85 default:
86/* pick an off-white color, so that transparent backgrounds look white in jpgs */
87#define TRANSPARENT 0x7ffffffe
88
89 gdImageColorTransparent(im, TRANSPARENT);
90 gdImageAlphaBlending(im, false);
91 for (y = 0; y < height; y++) {
92 for (x = 0; x < width; x++) {
93 const int r = *data++;
94 const int g = *data++;
95 const int b = *data++;
96 // gd’s alpha is 7-bit, so scale down ÷2 from our 8-bit
97 const int alpha = *data++ >> 1;
98 const int color = r | (g << 8) | (b << 16) | ((0x7f - alpha) << 24);
99 if (alpha >= 0x20)
100 /* if not > 75% transparent */
101 im->tpixels[y][x] = color;
102 else
103 im->tpixels[y][x] = TRANSPARENT;
104 }
105 }
106 break;
107 }
108
109 switch (job->device.id) {
110#ifdef HAVE_GD_GIF
111 case FORMAT_GIF:
112 gdImageTrueColorToPalette(im, 0, 256);
113 gdImageGifCtx(im, &gd_context.ctx);
114 break;
115#endif
116
117#ifdef HAVE_GD_JPEG
118 case FORMAT_JPEG:
119 /*
120 * Write IM to OUTFILE as a JFIF-formatted JPEG image, using
121 * quality JPEG_QUALITY. If JPEG_QUALITY is in the range
122 * 0-100, increasing values represent higher quality but also
123 * larger image size. If JPEG_QUALITY is negative, the
124 * IJG JPEG library's default quality is used (which should
125 * be near optimal for many applications). See the IJG JPEG
126 * library documentation for more details.
127 */
128#define JPEG_QUALITY -1
129 gdImageJpegCtx(im, &gd_context.ctx, JPEG_QUALITY);
130 break;
131#endif
132
133#ifdef HAVE_GD_PNG
134 case FORMAT_PNG:
135 gdImageTrueColorToPalette(im, 0, 256);
136 gdImagePngCtx(im, &gd_context.ctx);
137 break;
138#endif
139
140 case FORMAT_GD:
141 gdImageGd(im, job->output_file);
142 break;
143
144 case FORMAT_GD2:
145#define GD2_CHUNKSIZE 128
146#define GD2_RAW 1
147#define GD2_COMPRESSED 2
148 gdImageGd2(im, job->output_file, GD2_CHUNKSIZE, GD2_COMPRESSED);
149 break;
150
151#ifdef HAVE_GD_GIF
152 case FORMAT_WBMP:
153 {
154 /* Use black for the foreground color for the B&W wbmp image. */
155 int black = gdImageColorResolveAlpha(im, 0, 0, 0, gdAlphaOpaque);
156 gdImageWBMPCtx(im, black, &gd_context.ctx);
157 }
158 break;
159#endif
160
161 break;
162 default:
163 break;
164 }
165
166 gdImageDestroy(im);
167}
168
169static gvdevice_engine_t gd_engine = {
170 NULL, /* gd_initialize */
171 gd_format,
172 NULL, /* gd_finalize */
173};
174
175static gvdevice_features_t device_features_gd = {
177 | GVDEVICE_DOES_TRUECOLOR,/* flags */
178 {0.,0.}, /* default margin - points */
179 {0.,0.}, /* default page width, height - points */
180 {96.,96.}, /* dpi */
181};
182
183static gvdevice_features_t device_features_gd_no_writer = {
186 | GVDEVICE_DOES_TRUECOLOR,/* flags */
187 {0.,0.}, /* default margin - points */
188 {0.,0.}, /* default page width, height - points */
189 {96.,96.}, /* dpi */
190};
191#endif
192
194#ifdef HAVE_PANGOCAIRO
195
196#ifdef HAVE_GD_GIF
197 {FORMAT_GIF, "gif:cairo", 10, &gd_engine, &device_features_gd},
198 {FORMAT_WBMP, "wbmp:cairo", 5, &gd_engine, &device_features_gd},
199#endif
200
201#ifdef HAVE_GD_JPEG
202 {FORMAT_JPEG, "jpe:cairo", 5, &gd_engine, &device_features_gd},
203 {FORMAT_JPEG, "jpeg:cairo", 5, &gd_engine, &device_features_gd},
204 {FORMAT_JPEG, "jpg:cairo", 5, &gd_engine, &device_features_gd},
205#endif
206
207#ifdef HAVE_GD_PNG
208 {FORMAT_PNG, "png:cairo", 5, &gd_engine, &device_features_gd},
209#endif
210
211 {FORMAT_GD, "gd:cairo", 5, &gd_engine, &device_features_gd_no_writer},
212 {FORMAT_GD2, "gd2:cairo", 5, &gd_engine, &device_features_gd_no_writer},
213
214#endif
215 {0, NULL, 0, NULL, NULL}
216};
static gd_context_t * get_containing_context(gdIOCtx *ctx)
static double len(glCompPoint p)
Definition glutils.c:150
node NULL
Definition grammar.y:163
#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:129
size_t gvwrite(GVJ_t *job, const char *s, size_t len)
Definition gvdevice.c:180
int gvdevice_gd_putBuf(gdIOCtx *context, const void *buffer, int len)
Definition gvdevice_gd.c:24
void gvdevice_gd_putC(gdIOCtx *context, int C)
Definition gvdevice_gd.c:33
gvplugin_installed_t gvdevice_gd_types[]
format_type
static const char black[]
@ FORMAT_JPEG
Definition gvrender_gd.c:37
@ FORMAT_GD
Definition gvrender_gd.c:40
@ FORMAT_GD2
Definition gvrender_gd.c:41
@ FORMAT_WBMP
Definition gvrender_gd.c:39
@ FORMAT_GIF
Definition gvrender_gd.c:36
@ FORMAT_XBM
Definition gvrender_gd.c:42
@ FORMAT_PNG
Definition gvrender_gd.c:38
#define C
Definition pack.c:29
#define alpha
Definition shapes.c:4058
gvplugin_active_device_t device
Definition gvcjob.h:286
unsigned char * imagedata
location of imagedata
Definition gvcjob.h:297
FILE * output_file
Definition gvcjob.h:277
unsigned int width
Definition gvcjob.h:327
unsigned int height
Definition gvcjob.h:328
Definition legal.c:50
ingroup plugin_api
Definition gvplugin.h:35