source: libcaca/trunk/examples/view.c @ 235

Last change on this file since 235 was 235, checked in by Sam Hocevar, 17 years ago
  • src/caca.c src/caca.h: + Added caca_get_dithering_name().
  • src/bitmap.c: + Created a new dithering method with an 8x8 ordered matrix. + Replaced the char list with a string for better readability. + Dithering functions now return a value between 0 and 255.
  • examples/demo.c examples/view.c: + Adapted to use caca_get_dithering_name().
  • Property svn:keywords set to Id
File size: 9.0 KB
Line 
1/*
2 *   view          image viewer for libcaca
3 *   Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
4 *                 All Rights Reserved
5 *
6 *   $Id: view.c 235 2003-11-29 19:35:07Z sam $
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU Lesser General Public
10 *   License as published by the Free Software Foundation; either
11 *   version 2 of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 *   Lesser General Public License for more details.
17 *
18 *   You should have received a copy of the GNU Lesser General Public
19 *   License along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 *   02111-1307  USA
22 */
23
24#include "config.h"
25
26#include <stdio.h>
27#include <string.h>
28#include <malloc.h>
29
30#define X_DISPLAY_MISSING 1
31#include <Imlib2.h>
32
33#include "caca.h"
34
35Imlib_Image image = NULL;
36char *pixels = NULL;
37struct caca_bitmap *bitmap = NULL;
38int x, y, w, h;
39
40int dithering = CACA_DITHERING_ORDERED4;
41
42static void load_image(const char *);
43
44int main(int argc, char **argv)
45{
46    int quit = 0, update = 1, help = 0, reload = 0;
47    int i, zoom = 0;
48
49    char **list = NULL;
50    int current = 0, items = 0, opts = 1;
51
52    /* Initialise libcaca */
53    if(caca_init())
54    {
55        fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]);
56        return 1;
57    }
58
59    /* Load items into playlist */
60    for(i = 1; i < argc; i++)
61    {
62        /* Skip options except after `--' */
63        if(opts && argv[i][0] == '-')
64        {
65            if(argv[i][1] == '-' && argv[i][2] == '\0')
66                opts = 0;
67            continue;
68        }
69
70        /* Add argv[i] to the list */
71        if(items)
72            list = realloc(list, (items + 1) * sizeof(char *));
73        else
74            list = malloc(sizeof(char *));
75        list[items] = argv[i];
76        items++;
77
78        reload = 1;
79    }
80
81    /* Go ! */
82    while(!quit)
83    {
84        int ww = caca_get_width();
85        int wh = caca_get_height();
86
87        int event;
88
89        while((event = caca_get_event()))
90        {
91            switch(event)
92            {
93            case CACA_EVENT_KEY_PRESS | 'n':
94            case CACA_EVENT_KEY_PRESS | 'N':
95                if(items) current = (current + 1) % items;
96                reload = 1;
97                break;
98            case CACA_EVENT_KEY_PRESS | 'p':
99            case CACA_EVENT_KEY_PRESS | 'P':
100                if(items) current = (items + current - 1) % items;
101                reload = 1;
102                break;
103            case CACA_EVENT_KEY_PRESS | 'd':
104            case CACA_EVENT_KEY_PRESS | 'D':
105                dithering = (dithering + 1) % 4;
106                update = 1;
107                break;
108            case CACA_EVENT_KEY_PRESS | '+':
109                zoom++;
110                if(zoom > 48) zoom = 48; else update = 1;
111                break;
112            case CACA_EVENT_KEY_PRESS | '-':
113                zoom--;
114                if(zoom < -48) zoom = -48; else update = 1;
115                break;
116            case CACA_EVENT_KEY_PRESS | 'x':
117            case CACA_EVENT_KEY_PRESS | 'X':
118                zoom = 0;
119                update = 1;
120                break;
121            case CACA_EVENT_KEY_PRESS | 'k':
122            case CACA_EVENT_KEY_PRESS | 'K':
123            case CACA_EVENT_KEY_PRESS | CACA_KEY_UP:
124                if(zoom > 0) y -= 1 + h / (2 + zoom) / 8;
125                update = 1;
126                break;
127            case CACA_EVENT_KEY_PRESS | 'j':
128            case CACA_EVENT_KEY_PRESS | 'J':
129            case CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN:
130                if(zoom > 0) y += 1 + h / (2 + zoom) / 8;
131                update = 1;
132                break;
133            case CACA_EVENT_KEY_PRESS | 'h':
134            case CACA_EVENT_KEY_PRESS | 'H':
135            case CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT:
136                if(zoom > 0) x -= 1 + w / (2 + zoom) / 8;
137                update = 1;
138                break;
139            case CACA_EVENT_KEY_PRESS | 'l':
140            case CACA_EVENT_KEY_PRESS | 'L':
141            case CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT:
142                if(zoom > 0) x += 1 + w / (2 + zoom) / 8;
143                update = 1;
144                break;
145            case CACA_EVENT_KEY_PRESS | '?':
146                help = !help;
147                update = 1;
148                break;
149            case CACA_EVENT_KEY_PRESS | 'q':
150            case CACA_EVENT_KEY_PRESS | 'Q':
151                quit = 1;
152                break;
153            }
154        }
155
156        if(items && reload)
157        {
158            char *buffer = malloc(ww + 1);
159
160            /* Reset image-specific runtime variables */
161            zoom = 0;
162
163            snprintf(buffer, ww, " Loading `%s'... ", list[current]);
164            buffer[ww] = '\0';
165            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
166            caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
167            caca_refresh();
168
169            load_image(list[current]);
170            reload = 0;
171            update = 1;
172
173            free(buffer);
174        }
175
176        if(update)
177        {
178            caca_clear();
179            caca_set_dithering(dithering);
180            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
181
182            if(!items)
183                caca_printf(ww / 2 - 5, wh / 2, " No image. ");
184            else if(!image)
185            {
186                char *buffer = malloc(ww + 1);
187                snprintf(buffer, ww, " Error loading `%s'. ", list[current]);
188                buffer[ww] = '\0';
189                caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
190                free(buffer);
191            }
192            else if(zoom < 0)
193            {
194                int xo = (ww - 1) / 2;
195                int yo = (wh - 1) / 2;
196                int xn = (ww - 1) / (2 - zoom);
197                int yn = (wh - 1) / (2 - zoom);
198                caca_draw_bitmap(xo - xn, yo - yn, xo + xn, yo + yn,
199                                 bitmap, pixels);
200            }
201            else if(zoom > 0)
202            {
203                struct caca_bitmap *newbitmap;
204                int xn = w / (2 + zoom);
205                int yn = h / (2 + zoom);
206                if(x < xn) x = xn;
207                if(y < yn) y = yn;
208                if(xn + x > w) x = w - xn;
209                if(yn + y > h) y = h - yn;
210                newbitmap = caca_create_bitmap(32, 2 * xn, 2 * yn, 4 * w,
211                                           0x00ff0000, 0x0000ff00, 0x000000ff);
212                caca_draw_bitmap(0, 0, ww - 1, wh - 1, newbitmap,
213                                 pixels + 4 * (x - xn) + 4 * w * (y - yn));
214                caca_free_bitmap(newbitmap);
215            }
216            else
217            {
218                caca_draw_bitmap(0, 0, ww - 1, wh - 1, bitmap, pixels);
219            }
220
221            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
222            caca_draw_line(0, 0, ww - 1, 0, ' ');
223            caca_draw_line(0, wh - 1, ww - 1, wh - 1, '-');
224            caca_putstr(0, 0, "q:Quit  +/-/x:Zoom  h/j/k/l: Move  "
225                              "d:Dithering  ?:Help");
226            caca_printf(3, wh - 1, "cacaview %s", VERSION);
227            caca_printf(ww / 2 - 5, wh - 1, "(dithering: %s)",
228                        caca_get_dithering_name(dithering));
229            caca_printf(ww - 14, wh - 1,
230                        "(zoom: %s%i)", zoom > 0 ? "+" : "", zoom);
231
232            if(help)
233            {
234                caca_putstr(2, 2,  " +: zoom in          ");
235                caca_putstr(2, 3,  " -: zoom out         ");
236                caca_putstr(2, 4,  " x: reset zoom       ");
237                caca_putstr(2, 5,  " ------------------- ");
238                caca_putstr(2, 6,  " hjkl: move view     ");
239                caca_putstr(2, 7,  " arrows: move view   ");
240                caca_putstr(2, 8,  " ------------------- ");
241                caca_putstr(2, 9,  " d: dithering method ");
242                caca_putstr(2, 10, " ------------------- ");
243                caca_putstr(2, 11, " ?: help             ");
244                caca_putstr(2, 12, " q: quit             ");
245
246                help = 0;
247            }
248
249            caca_refresh();
250            update = 0;
251        }
252    }
253
254    if(bitmap)
255        caca_free_bitmap(bitmap);
256    if(image)
257        imlib_free_image();
258
259    /* Clean up */
260    caca_end();
261
262    return 0;
263}
264
265static void load_image(const char *name)
266{
267    /* Empty previous data */
268    if(image)
269        imlib_free_image();
270
271    if(bitmap)
272        caca_free_bitmap(bitmap);
273
274    image = NULL;
275    bitmap = NULL;
276
277    /* Load the new image */
278    image = imlib_load_image(name);
279
280    if(!image)
281    {
282        return;
283    }
284
285    imlib_context_set_image(image);
286    pixels = (char *)imlib_image_get_data_for_reading_only();
287    w = imlib_image_get_width();
288    h = imlib_image_get_height();
289    x = w / 2;
290    y = h / 2;
291
292    /* Create the libcaca bitmap */
293    bitmap = caca_create_bitmap(32, w, h, 4 * w,
294                                0x00ff0000, 0x0000ff00, 0x000000ff);
295    if(!bitmap)
296    {
297        imlib_free_image();
298        image = NULL;
299    }
300}
301
Note: See TracBrowser for help on using the repository browser.