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

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