filters/gp_filter_resize_alloc: Check w and h
[gfxprim.git] / demos / c_simple / loaders_register.c
blobe03e3a56395a37afbe1557df034a6bda128bbffc
1 /*****************************************************************************
2 * This file is part of gfxprim library. *
3 * *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
8 * *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
18 * *
19 * Copyright (C) 2009-2014 Cyril Hrubis <metan@ucw.cz> *
20 * *
21 *****************************************************************************/
25 Shows how to register custom image loader/saver.
27 Feed it with small image (cca 60x60 pixels) to produce ASCII art version.
31 #include <stdio.h>
32 #include <string.h>
33 #include <errno.h>
35 #include <gfxprim.h>
38 * Saves 2 bpp grayscale image as ASCII Art
40 static int write_data(const gp_pixmap *img, gp_io *io,
41 gp_progress_cb *callback)
43 gp_io *bio;
44 int err;
46 if (img->pixel_type != GP_PIXEL_G4) {
47 errno = ENOSYS;
48 return 1;
51 /* Create buffered I/O */
52 bio = gp_io_wbuffer(io, 0);
54 if (!bio)
55 return 1;
57 unsigned int i, j;
58 const char *const table[] = {" ", ".", ",", "-", "=", "#", "O", "$"};
60 for (j = 0; j < img->h; j++) {
61 for (i = 0; i < img->w; i++) {
62 gp_pixel p = gp_getpixel_raw(img, i, j);
63 const char *c = table[p>>1];
65 err = gp_io_flush(bio, c, 1);
66 if (err)
67 return 1;
70 if (gp_io_flush(bio, "\n", 1))
71 return 1;
73 if (gp_progress_cb_report(callback, j, img->h, img->w)) {
74 errno = ECANCELED;
75 return 1;
79 gp_io_close(bio);
80 gp_progress_cb_done(callback);
81 return 0;
84 static gp_pixel_type save_ptypes[] = {
85 GP_PIXEL_G4,
86 GP_PIXEL_UNKNOWN,
89 const gp_loader loader = {
90 .Write = write_data,
91 .save_ptypes = save_ptypes,
92 .fmt_name = "ASCII Art",
93 .extensions = {"txt", NULL},
96 int main(int argc, char *argv[])
98 gp_pixmap *c, *gc, *sc;
100 gp_loader_register(&loader);
102 /* List all loaders */
103 gp_loaders_lists();
104 printf("\n\n");
106 if (argc != 2) {
107 fprintf(stderr, "ERROR: Takes image as an argument\n");
108 return 1;
111 /* Now load image and save it using our loader */
112 c = gp_load_image(argv[1], NULL);
113 if (c == NULL) {
114 fprintf(stderr, "Failed to load image: %s\n", strerror(errno));
115 return 1;
119 * Font letters are not square resize the image so that it's twice it
120 * original width.
122 gp_size w = 120;
123 gp_size h = (w/2 * c->h + c->w/2)/c->w;
125 sc = gp_filter_resize_alloc(c, w, h, GP_INTERP_LINEAR_LF_INT, NULL);
126 gc = gp_filter_floyd_steinberg_alloc(sc, GP_PIXEL_G4, NULL);
128 if (gc == NULL) {
129 fprintf(stderr, "FloydSteinberg: %s\n", strerror(errno));
130 return 1;
133 printf("Saving to test.txt\n");
135 if (gp_save_image(gc, "test.txt", NULL)) {
136 fprintf(stderr, "Failed to save image: %s\n", strerror(errno));
137 return 1;
140 return 0;