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

Last change on this file since 246 was 246, checked in by Sam Hocevar, 19 years ago
  • src/graphics.c: + Internally cache screen width and height.
  • src/bitmap.c: + Added alpha support to caca_draw_bitmap(). For now, we only treat 0%

alpha as fully transparent, and any other value as fully opaque.

+ Slightly tuned colour weights in the renderer.
+ caca_set_bitmap_palette() takes unsigned ints.

  • examples/demo.c: + Added a crap render demo.
  • examples/aafire.c: + Set a 20ms delay. + Added alpha values to the palette.
  • examples/view.c: + Draw a gray checkered grid below the image so that transparent images

look a lot nicer.

+ 'f' toggles "fullscreen" mode.

  • Property svn:keywords set to Id
File size: 10.5 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 246 2003-12-11 16:31:49Z 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#include <unistd.h>
30
31#include <Imlib2.h>
32
33#include "caca.h"
34
35/* Local functions */
36static void load_image(const char *);
37static void draw_checkers(unsigned int, unsigned int,
38                          unsigned int, unsigned int);
39
40/* Local variables */
41Imlib_Image image = NULL;
42char *pixels = NULL;
43struct caca_bitmap *bitmap = NULL;
44int x, y, w, h;
45
46int main(int argc, char **argv)
47{
48    int quit = 0, update = 1, help = 0, reload = 0, fullscreen = 0, zoom = 0;
49    int dithering = CACA_DITHERING_ORDERED4;
50
51    char **list = NULL;
52    int current = 0, items = 0, opts = 1;
53    int i;
54
55    /* Initialise libcaca */
56    if(caca_init())
57    {
58        fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]);
59        return 1;
60    }
61
62    /* Load items into playlist */
63    for(i = 1; i < argc; i++)
64    {
65        /* Skip options except after `--' */
66        if(opts && argv[i][0] == '-')
67        {
68            if(argv[i][1] == '-' && argv[i][2] == '\0')
69                opts = 0;
70            continue;
71        }
72
73        /* Add argv[i] to the list */
74        if(items)
75            list = realloc(list, (items + 1) * sizeof(char *));
76        else
77            list = malloc(sizeof(char *));
78        list[items] = argv[i];
79        items++;
80
81        reload = 1;
82    }
83
84    /* Go ! */
85    while(!quit)
86    {
87        int ww = caca_get_width();
88        int wh = caca_get_height();
89
90        int event;
91
92        while((event = caca_get_event()))
93        {
94            switch(event)
95            {
96            case CACA_EVENT_KEY_PRESS | 'n':
97            case CACA_EVENT_KEY_PRESS | 'N':
98                if(items) current = (current + 1) % items;
99                reload = 1;
100                break;
101            case CACA_EVENT_KEY_PRESS | 'p':
102            case CACA_EVENT_KEY_PRESS | 'P':
103                if(items) current = (items + current - 1) % items;
104                reload = 1;
105                break;
106            case CACA_EVENT_KEY_PRESS | 'f':
107            case CACA_EVENT_KEY_PRESS | 'F':
108                fullscreen = ~fullscreen;
109                update = 1;
110                break;
111            case CACA_EVENT_KEY_PRESS | 'd':
112                dithering = (dithering + 1) % 5;
113                update = 1;
114                break;
115            case CACA_EVENT_KEY_PRESS | 'D':
116                dithering = (dithering + 4) % 5;
117                update = 1;
118                break;
119            case CACA_EVENT_KEY_PRESS | '+':
120                zoom++;
121                if(zoom > 48) zoom = 48; else update = 1;
122                break;
123            case CACA_EVENT_KEY_PRESS | '-':
124                zoom--;
125                if(zoom < -48) zoom = -48; else update = 1;
126                break;
127            case CACA_EVENT_KEY_PRESS | 'x':
128            case CACA_EVENT_KEY_PRESS | 'X':
129                zoom = 0;
130                update = 1;
131                break;
132            case CACA_EVENT_KEY_PRESS | 'k':
133            case CACA_EVENT_KEY_PRESS | 'K':
134            case CACA_EVENT_KEY_PRESS | CACA_KEY_UP:
135                if(zoom > 0) y -= 1 + h / (2 + zoom) / 8;
136                update = 1;
137                break;
138            case CACA_EVENT_KEY_PRESS | 'j':
139            case CACA_EVENT_KEY_PRESS | 'J':
140            case CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN:
141                if(zoom > 0) y += 1 + h / (2 + zoom) / 8;
142                update = 1;
143                break;
144            case CACA_EVENT_KEY_PRESS | 'h':
145            case CACA_EVENT_KEY_PRESS | 'H':
146            case CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT:
147                if(zoom > 0) x -= 1 + w / (2 + zoom) / 8;
148                update = 1;
149                break;
150            case CACA_EVENT_KEY_PRESS | 'l':
151            case CACA_EVENT_KEY_PRESS | 'L':
152            case CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT:
153                if(zoom > 0) x += 1 + w / (2 + zoom) / 8;
154                update = 1;
155                break;
156            case CACA_EVENT_KEY_PRESS | '?':
157                help = 1;
158                update = 1;
159                break;
160            case CACA_EVENT_KEY_PRESS | 'q':
161            case CACA_EVENT_KEY_PRESS | 'Q':
162                quit = 1;
163                break;
164            }
165        }
166
167        if(items && reload)
168        {
169            char *buffer = malloc(ww + 1);
170
171            /* Reset image-specific runtime variables */
172            zoom = 0;
173
174            snprintf(buffer, ww, " Loading `%s'... ", list[current]);
175            buffer[ww] = '\0';
176            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
177            caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
178            caca_refresh();
179
180            load_image(list[current]);
181            reload = 0;
182            update = 1;
183
184            free(buffer);
185        }
186
187        if(!update)
188        {
189            usleep(10000);
190            continue;
191        }
192
193        caca_clear();
194        caca_set_dithering(dithering);
195        caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
196
197        if(!items)
198            caca_printf(ww / 2 - 5, wh / 2, " No image. ");
199        else if(!image)
200        {
201            char *buffer = malloc(ww + 1);
202            snprintf(buffer, ww, " Error loading `%s'. ", list[current]);
203            buffer[ww] = '\0';
204            caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
205            free(buffer);
206        }
207        else if(zoom < 0)
208        {
209            int xo = (ww - 1) / 2;
210            int yo = (wh - 1) / 2;
211            int xn = (ww - 1) / (2 - zoom);
212            int yn = (wh - 1) / (2 - zoom);
213            draw_checkers(xo - xn, yo - yn, xo + xn, yo + yn);
214            caca_draw_bitmap(xo - xn, yo - yn, xo + xn, yo + yn,
215                             bitmap, pixels);
216        }
217        else if(zoom > 0)
218        {
219            struct caca_bitmap *newbitmap;
220            int xn = w / (2 + zoom);
221            int yn = h / (2 + zoom);
222            if(x < xn) x = xn;
223            if(y < yn) y = yn;
224            if(xn + x > w) x = w - xn;
225            if(yn + y > h) y = h - yn;
226            newbitmap = caca_create_bitmap(32, 2 * xn, 2 * yn, 4 * w,
227                                           0x00ff0000, 0x0000ff00, 0x000000ff,
228                                           0xff000000);
229            draw_checkers(0, fullscreen ? 0 : 1,
230                          ww - 1, fullscreen ? wh - 1 : wh - 2);
231            caca_draw_bitmap(0, fullscreen ? 0 : 1,
232                             ww - 1, fullscreen ? wh - 1 : wh - 2,
233                             newbitmap,
234                             pixels + 4 * (x - xn) + 4 * w * (y - yn));
235            caca_free_bitmap(newbitmap);
236        }
237        else
238        {
239            draw_checkers(0, fullscreen ? 0 : 1,
240                          ww - 1, fullscreen ? wh - 1 : wh - 2);
241            caca_draw_bitmap(0, fullscreen ? 0 : 1,
242                             ww - 1, fullscreen ? wh - 1 : wh - 2,
243                             bitmap, pixels);
244        }
245
246        caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
247
248        if(!fullscreen)
249        {
250            caca_draw_line(0, 0, ww - 1, 0, ' ');
251            caca_draw_line(0, wh - 1, ww - 1, wh - 1, '-');
252            caca_putstr(0, 0, "q:Quit  n/p:Next/Prev  +/-/x:Zoom  "
253                              "h/j/k/l: Move  d:Dithering");
254            caca_putstr(ww - strlen("?:Help"), 0, "?:Help");
255            caca_printf(3, wh - 1, "cacaview %s", VERSION);
256            caca_printf(ww / 2 - 5, wh - 1, "(%s dithering)",
257                        caca_get_dithering_name(dithering));
258            caca_printf(ww - 14, wh - 1,
259                        "(zoom: %s%i)", zoom > 0 ? "+" : "", zoom);
260        }
261
262        if(help)
263        {
264            caca_putstr(ww - 22, 2,  " +: zoom in          ");
265            caca_putstr(ww - 22, 3,  " -: zoom out         ");
266            caca_putstr(ww - 22, 4,  " x: reset zoom       ");
267            caca_putstr(ww - 22, 5,  " ------------------- ");
268            caca_putstr(ww - 22, 6,  " hjkl: move view     ");
269            caca_putstr(ww - 22, 7,  " arrows: move view   ");
270            caca_putstr(ww - 22, 8,  " ------------------- ");
271            caca_putstr(ww - 22, 9,  " d: dithering method ");
272            caca_putstr(ww - 22, 10, " ------------------- ");
273            caca_putstr(ww - 22, 11, " ?: help             ");
274            caca_putstr(ww - 22, 12, " q: quit             ");
275
276            help = 0;
277        }
278
279        caca_refresh();
280        update = 0;
281    }
282
283    if(bitmap)
284        caca_free_bitmap(bitmap);
285    if(image)
286        imlib_free_image();
287
288    /* Clean up */
289    caca_end();
290
291    return 0;
292}
293
294static void load_image(const char *name)
295{
296    /* Empty previous data */
297    if(image)
298        imlib_free_image();
299
300    if(bitmap)
301        caca_free_bitmap(bitmap);
302
303    image = NULL;
304    bitmap = NULL;
305
306    /* Load the new image */
307    image = imlib_load_image(name);
308
309    if(!image)
310    {
311        return;
312    }
313
314    imlib_context_set_image(image);
315    pixels = (char *)imlib_image_get_data_for_reading_only();
316    w = imlib_image_get_width();
317    h = imlib_image_get_height();
318    x = w / 2;
319    y = h / 2;
320
321    /* Create the libcaca bitmap */
322    bitmap = caca_create_bitmap(32, w, h, 4 * w, 0x00ff0000, 0x0000ff00,
323                                0x000000ff, 0xff000000);
324    if(!bitmap)
325    {
326        imlib_free_image();
327        image = NULL;
328    }
329}
330
331static void draw_checkers(unsigned int x1, unsigned int y1,
332                          unsigned int x2, unsigned int y2)
333{
334    unsigned int xn, yn;
335
336    for(yn = y1; yn <= y2; yn++)
337        for(xn = x1; xn <= x2; xn++)
338    {
339        if(((xn / 4) ^ (yn / 2)) & 1)
340            caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_DARKGRAY);
341        else
342            caca_set_color(CACA_COLOR_DARKGRAY, CACA_COLOR_LIGHTGRAY);
343        caca_putchar(xn, yn, ' ');
344    }
345}
346
Note: See TracBrowser for help on using the repository browser.