1
/* ``The contents of this file are subject to the Erlang Public License,
2
* Version 1.1, (the "License"); you may not use this file except in
3
* compliance with the License. You should have received a copy of the
4
* Erlang Public License along with this software. If not, it can be
5
* retrieved via the world wide web at http://www.erlang.org/.
7
* Software distributed under the License is distributed on an "AS IS"
8
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
* the License for the specific language governing rights and limitations
12
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
14
* AB. All Rights Reserved.''
25
#include <erl_driver.h>
28
#include "egd_image.h"
29
#include "egd_coding.h"
31
int egd_options_to_gd_arc_style(int options);
33
void send_result(egd_data *d, unsigned int result) {
34
unsigned char buffer[4];
35
driver_output(d->port, (char *)encode((char *)buffer, result), 4);
38
void image_create(egd_data *d, char *buffer, int l){
42
d->im = gdImageCreateTrueColor(w, h);
46
void image_destroy(egd_data *d) {
47
if (d != NULL && d->im != NULL) gdImageDestroy(d->im);
51
void image_pixel(egd_data *d, char *buffer, int l) {
52
int x = decode(&buffer);
53
int y = decode(&buffer);
54
int c = decode_color(&buffer);
55
gdImageSetPixel(d->im, x, y, c);
59
/* X1, Y1, X2, Y2, Color */
60
void image_line(egd_data *d, char *buffer, int l) {
61
int x1 = decode(&buffer);
62
int y1 = decode(&buffer);
63
int x2 = decode(&buffer);
64
int y2 = decode(&buffer);
65
int c = decode_color(&buffer);
66
gdImageLine(d->im, x1, y1, x2, y2, c);
71
void image_color(egd_data *d, char *buffer, int l) {
72
int r = decode(&buffer);
73
int g = decode(&buffer);
74
int b = decode(&buffer);
75
int color = gdImageColorAllocate(d->im, r,g,b);
76
send_result(d, color);
79
void image_rectangle(egd_data *d, char *buffer, int l) {
80
int x1 = decode(&buffer);
81
int y1 = decode(&buffer);
82
int x2 = decode(&buffer);
83
int y2 = decode(&buffer);
84
int c = decode_color(&buffer);
85
gdImageRectangle(d->im, x1, y1, x2, y2, c);
89
void image_filled_rectangle(egd_data *d, char *buffer, int l) {
90
int x1 = decode(&buffer);
91
int y1 = decode(&buffer);
92
int x2 = decode(&buffer);
93
int y2 = decode(&buffer);
94
int c = decode_color(&buffer);
95
gdImageFilledRectangle(d->im, x1, y1, x2, y2, c);
100
void image_polygon(egd_data *d, char *buffer, int l) {
101
int color = decode_color(&buffer);
102
int n = decode(&buffer);
103
gdPoint *pts = image_alloc_points(buffer, n);
105
gdImagePolygon(d->im, pts, n, color);
106
image_free_points(pts);
110
void image_filled_polygon(egd_data *d, char *buffer, int l) {
111
int color = decode_color(&buffer);
112
int n = decode(&buffer);
113
gdPoint *pts = image_alloc_points(buffer, n);
115
gdImageFilledPolygon(d->im, pts, n, color);
116
image_free_points(pts);
121
/* cx, cy, w, h, s, e. color*/
122
void image_arc(egd_data *d, char *buffer, int l) {
123
int cx = decode(&buffer);
124
int cy = decode(&buffer);
125
int w = decode(&buffer);
126
int h = decode(&buffer);
127
int s = decode(&buffer);
128
int e = decode(&buffer);
129
int c = decode_color(&buffer);
130
gdImageArc(d->im, cx, cy, w, h, s, e, c);
135
/* cx, cy, w, h, s, e. color, style_options */
136
void image_filled_arc(egd_data *d, char *buffer, int l) {
137
int cx = decode(&buffer);
138
int cy = decode(&buffer);
139
int w = decode(&buffer);
140
int h = decode(&buffer);
141
int s = decode(&buffer);
142
int e = decode(&buffer);
143
int c = decode_color(&buffer);
144
int options = decode(&buffer);
145
int style = egd_options_to_gd_arc_style(options);
146
gdImageFilledArc(d->im, cx, cy, w, h, s, e, c, style);
151
void image_filled_ellipse(egd_data *d, char *buffer , int l) {
152
int cx = decode(&buffer);
153
int cy = decode(&buffer);
154
int w = decode(&buffer);
155
int h = decode(&buffer);
156
int c = decode_color(&buffer);
157
gdImageFilledEllipse(d->im, cx, cy, w, h, c);
164
void image_text(egd_data *d, char *buffer, int l) {
165
int x = decode(&buffer);
166
int y = decode(&buffer);
167
int size = decode(&buffer);
168
int c = decode_color(&buffer);
169
int str_len = decode(&buffer);
170
unsigned char *str = (unsigned char*)image_alloc_string((char*)buffer, str_len);
171
gdImageString(d->im, image_font(size), x,y, str, c);
172
image_free_string((char *)str);
176
void image_text_up(egd_data *d, char *buffer, int l) {
177
int x = decode(&buffer);
178
int y = decode(&buffer);
179
int size = decode(&buffer);
180
int c = decode_color(&buffer);
181
int str_len = decode(&buffer);
182
unsigned char *str = (unsigned char*)image_alloc_string((char *)buffer, str_len);
183
gdImageStringUp(d->im, image_font(size), x,y, str, c);
184
image_free_string((char *)str);
188
void image_font_size(egd_data *d, char *buffer, int l) {
189
int size = decode(&buffer);
190
unsigned char output[8];
191
gdFontPtr font = image_font(size);
195
encode((char*)output, w);
196
encode((char*)output + 4, h);
197
driver_output(d->port, output, 8);
200
void image_fill(egd_data *d, char *buffer, int l) {
201
int x = decode(&buffer);
202
int y = decode(&buffer);
203
int c = decode_color(&buffer);
204
gdImageFill(d->im, x, y, c);
208
/* rotate and resample */
212
* egd_data *d, image pointer, port data
213
* char *buffer, incoming data from erlang
214
* int l, length of data
216
* The buffer only contains the angle of rotation.
219
void image_rotate(egd_data *d, char *buffer, int l){
220
int angle = decode(&buffer);
221
float alpha = angle * .0174532925f;
222
int w = fabs((d->im->sx)*cos(alpha)) + fabs((d->im->sy)*sin(alpha));
223
int h = fabs((d->im->sx)*sin(alpha)) + fabs((d->im->sy)*cos(alpha));
224
gdImagePtr im = gdImageCreateTrueColor(w,h);
225
gdImageCopyRotated(im, d->im, w/2.0, h/2.0, 0,0, d->im->sx, d->im->sy, angle);
226
gdImageDestroy(d->im);
231
void image_resample(egd_data *d, char *buffer, int l){
232
int new_w = decode(&buffer);
233
int new_h = decode(&buffer);
234
gdImagePtr im = gdImageCreateTrueColor(new_w, new_h);
235
gdImageCopyResampled(im, d->im, 0, 0, 0, 0, new_w, new_h, d->im->sx, d->im->sy);
236
gdImageDestroy(d->im);
244
void image_gif(egd_data *d, char *buffer, int l){
248
if ( (gif = gdImageGifPtr(d->im, &size)) == NULL) {
249
fprintf(stderr, "Gif fetch error\n");
254
driver_output(d->port, (char*)gif, size);
258
void image_jpeg(egd_data *d, char *buffer, int l){
261
int quality = decode(&buffer);
263
if ( (jpeg = gdImageJpegPtr(d->im, &size, quality)) == NULL) {
264
fprintf(stderr, "Jpeg fetch error\n");
269
driver_output(d->port, (char*)jpeg, size);
273
void image_png(egd_data *d, char *buffer, int l){
277
if ( (png = gdImagePngPtr(d->im, &size)) == NULL) {
278
fprintf(stderr, "Png fetch error\n");
282
driver_output(d->port, (char*)png, size);
289
gdFontPtr image_font(int size) {
291
return gdFontGetTiny();
292
} else if (size == 2) {
293
return gdFontGetSmall();
294
} else if (size == 3) {
295
return gdFontGetMediumBold();
296
} else if (size == 4) {
297
return gdFontGetLarge();
298
} else if (size == 5) {
299
return gdFontGetGiant();
301
return gdFontGetSmall();
304
int egd_options_to_gd_arc_style(int options) {
307
if (options & EGD_ARC_STYLE_ARC) style |= gdArc;
308
if (options & EGD_ARC_STYLE_CHORD) style |= gdChord;
309
if (options & EGD_ARC_STYLE_NO_FILL) style |= gdNoFill;
310
if (options & EGD_ARC_STYLE_EDGED) style |= gdEdged;
316
gdPoint *image_alloc_points(char *buffer, int n) {
318
gdPoint *pts = (gdPoint*)driver_alloc(sizeof(gdPoint)*n);
320
for (i = 0; i < n; i++) {
321
pts[i].x = decode(&buffer);
322
pts[i].y = decode(&buffer);
327
void image_free_points(gdPoint *pts) {
331
char *image_alloc_string(char *buffer, int n) {
333
char *str = (char *)driver_alloc(sizeof(char)*(n + 1));
334
for (i = 0; i < n; i++) {
335
str[i] = (char)decode(&buffer);
341
void image_free_string(char *str) {