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

Last change on this file since 237 was 237, checked in by Sam Hocevar, 18 years ago
  • src/bitmap.c examples/view.c: + Fixed an endianness issue in caca_draw_bitmap(). + Code cleanup.
  • 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 237 2003-11-30 02:11:37Z 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;
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                dithering = (dithering + 1) % 4;
105                update = 1;
106                break;
107            case CACA_EVENT_KEY_PRESS | 'D':
108                dithering = (dithering - 1) % 4;
109                update = 1;
110                break;
111            case CACA_EVENT_KEY_PRESS | '+':
112                zoom++;
113                if(zoom > 48) zoom = 48; else update = 1;
114                break;
115            case CACA_EVENT_KEY_PRESS | '-':
116                zoom--;
117                if(zoom < -48) zoom = -48; else update = 1;
118                break;
119            case CACA_EVENT_KEY_PRESS | 'x':
120            case CACA_EVENT_KEY_PRESS | 'X':
121                zoom = 0;
122                update = 1;
123                break;
124            case CACA_EVENT_KEY_PRESS | 'k':
125            case CACA_EVENT_KEY_PRESS | 'K':
126            case CACA_EVENT_KEY_PRESS | CACA_KEY_UP:
127                if(zoom > 0) y -= 1 + h / (2 + zoom) / 8;
128                update = 1;
129                break;
130            case CACA_EVENT_KEY_PRESS | 'j':
131            case CACA_EVENT_KEY_PRESS | 'J':
132            case CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN:
133                if(zoom > 0) y += 1 + h / (2 + zoom) / 8;
134                update = 1;
135                break;
136            case CACA_EVENT_KEY_PRESS | 'h':
137            case CACA_EVENT_KEY_PRESS | 'H':
138            case CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT:
139                if(zoom > 0) x -= 1 + w / (2 + zoom) / 8;
140                update = 1;
141                break;
142            case CACA_EVENT_KEY_PRESS | 'l':
143            case CACA_EVENT_KEY_PRESS | 'L':
144            case CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT:
145                if(zoom > 0) x += 1 + w / (2 + zoom) / 8;
146                update = 1;
147                break;
148            case CACA_EVENT_KEY_PRESS | '?':
149                help = 1;
150                update = 1;
151                break;
152            case CACA_EVENT_KEY_PRESS | 'q':
153            case CACA_EVENT_KEY_PRESS | 'Q':
154                quit = 1;
155                break;
156            }
157        }
158
159        if(items && reload)
160        {
161            char *buffer = malloc(ww + 1);
162
163            /* Reset image-specific runtime variables */
164            zoom = 0;
165
166            snprintf(buffer, ww, " Loading `%s'... ", list[current]);
167            buffer[ww] = '\0';
168            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
169            caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
170            caca_refresh();
171
172            load_image(list[current]);
173            reload = 0;
174            update = 1;
175
176            free(buffer);
177        }
178
179        if(!update)
180        {
181            usleep(10000);
182            continue;
183        }
184
185        caca_clear();
186        caca_set_dithering(dithering);
187        caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
188
189        if(!items)
190            caca_printf(ww / 2 - 5, wh / 2, " No image. ");
191        else if(!image)
192        {
193            char *buffer = malloc(ww + 1);
194            snprintf(buffer, ww, " Error loading `%s'. ", list[current]);
195            buffer[ww] = '\0';
196            caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
197            free(buffer);
198        }
199        else if(zoom < 0)
200        {
201            int xo = (ww - 1) / 2;
202            int yo = (wh - 1) / 2;
203            int xn = (ww - 1) / (2 - zoom);
204            int yn = (wh - 1) / (2 - zoom);
205            caca_draw_bitmap(xo - xn, yo - yn, xo + xn, yo + yn,
206                             bitmap, pixels);
207        }
208        else if(zoom > 0)
209        {
210            struct caca_bitmap *newbitmap;
211            int xn = w / (2 + zoom);
212            int yn = h / (2 + zoom);
213            if(x < xn) x = xn;
214            if(y < yn) y = yn;
215            if(xn + x > w) x = w - xn;
216            if(yn + y > h) y = h - yn;
217            newbitmap = caca_create_bitmap(32, 2 * xn, 2 * yn, 4 * w,
218                                       0x0000ff00, 0x00ff0000, 0xff000000);
219            caca_draw_bitmap(0, 0, ww - 1, wh - 1, newbitmap,
220                             pixels + 4 * (x - xn) + 4 * w * (y - yn));
221            caca_free_bitmap(newbitmap);
222        }
223        else
224        {
225            caca_draw_bitmap(0, 0, ww - 1, wh - 1, bitmap, pixels);
226        }
227
228        caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
229        caca_draw_line(0, 0, ww - 1, 0, ' ');
230        caca_draw_line(0, wh - 1, ww - 1, wh - 1, '-');
231        caca_putstr(0, 0, "q:Quit  n/p:Next/Prev  +/-/x:Zoom  "
232                          "h/j/k/l: Move  d:Dithering");
233        caca_putstr(ww - strlen("?:Help"), 0, "?:Help");
234        caca_printf(3, wh - 1, "cacaview %s", VERSION);
235        caca_printf(ww / 2 - 5, wh - 1, "(%s dithering)",
236                    caca_get_dithering_name(dithering));
237        caca_printf(ww - 14, wh - 1,
238                    "(zoom: %s%i)", zoom > 0 ? "+" : "", zoom);
239
240        if(help)
241        {
242            caca_putstr(ww - 22, 2,  " +: zoom in          ");
243            caca_putstr(ww - 22, 3,  " -: zoom out         ");
244            caca_putstr(ww - 22, 4,  " x: reset zoom       ");
245            caca_putstr(ww - 22, 5,  " ------------------- ");
246            caca_putstr(ww - 22, 6,  " hjkl: move view     ");
247            caca_putstr(ww - 22, 7,  " arrows: move view   ");
248            caca_putstr(ww - 22, 8,  " ------------------- ");
249            caca_putstr(ww - 22, 9,  " d: dithering method ");
250            caca_putstr(ww - 22, 10, " ------------------- ");
251            caca_putstr(ww - 22, 11, " ?: help             ");
252            caca_putstr(ww - 22, 12, " q: quit             ");
253
254            help = 0;
255        }
256
257        caca_refresh();
258        update = 0;
259    }
260
261    if(bitmap)
262        caca_free_bitmap(bitmap);
263    if(image)
264        imlib_free_image();
265
266    /* Clean up */
267    caca_end();
268
269    return 0;
270}
271
272static void load_image(const char *name)
273{
274    /* Empty previous data */
275    if(image)
276        imlib_free_image();
277
278    if(bitmap)
279        caca_free_bitmap(bitmap);
280
281    image = NULL;
282    bitmap = NULL;
283
284    /* Load the new image */
285    image = imlib_load_image(name);
286
287    if(!image)
288    {
289        return;
290    }
291
292    imlib_context_set_image(image);
293    pixels = (char *)imlib_image_get_data_for_reading_only();
294    w = imlib_image_get_width();
295    h = imlib_image_get_height();
296    x = w / 2;
297    y = h / 2;
298
299    /* Create the libcaca bitmap */
300    bitmap = caca_create_bitmap(32, w, h, 4 * w,
301                                0x0000ff00, 0x00ff0000, 0xff000000);
302    if(!bitmap)
303    {
304        imlib_free_image();
305        image = NULL;
306    }
307}
308
Note: See TracBrowser for help on using the repository browser.