~ubuntu-branches/ubuntu/gutsy/libcaca/gutsy

« back to all changes in this revision

Viewing changes to examples/cacaview.c

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hocevar (Debian packages)
  • Date: 2006-12-03 02:05:11 UTC
  • mfrom: (3.1.6 feisty)
  • Revision ID: james.westby@ubuntu.com-20061203020511-h5nzqgf8nov7ns3z
Tags: 0.99.beta11.debian-2
Remove toilet from caca-utils now that it has entered testing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  cacaview      image viewer for libcaca
3
 
 *  Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
4
 
 *                All Rights Reserved
5
 
 *
6
 
 *  $Id: cacaview.c 257 2004-01-23 09:20:39Z 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 <stdlib.h>
29
 
 
30
 
#if defined(HAVE_IMLIB2_H)
31
 
#   include <Imlib2.h>
32
 
#else
33
 
#   include <stdio.h>
34
 
#endif
35
 
 
36
 
#if defined(HAVE_SLEEP)
37
 
#   include <windows.h>
38
 
#endif
39
 
 
40
 
#include "caca.h"
41
 
 
42
 
/* Local macros */
43
 
#define MODE_IMAGE 1
44
 
#define MODE_FILES 2
45
 
 
46
 
#define STATUS_DITHERING 1
47
 
#define STATUS_ANTIALIASING 2
48
 
#define STATUS_BACKGROUND 3
49
 
 
50
 
#define ZOOM_FACTOR 1.08f
51
 
#define ZOOM_MAX 50
52
 
#define PAD_STEP 0.15
53
 
 
54
 
/* Local functions */
55
 
static void print_status(void);
56
 
static void print_help(int, int);
57
 
static void set_zoom(int);
58
 
static void load_image(char const *);
59
 
static void unload_image(void);
60
 
static void draw_checkers(int, int, int, int);
61
 
#if !defined(HAVE_IMLIB2_H)
62
 
static int freadint(FILE *);
63
 
static int freadshort(FILE *);
64
 
static int freadchar(FILE *);
65
 
#endif
66
 
 
67
 
/* Local variables */
68
 
#if defined(HAVE_IMLIB2_H)
69
 
Imlib_Image image = NULL;
70
 
#endif
71
 
char *pixels = NULL;
72
 
struct caca_bitmap *bitmap = NULL;
73
 
unsigned int w, h, depth, bpp, rmask, gmask, bmask, amask;
74
 
#if !defined(HAVE_IMLIB2_H)
75
 
unsigned int red[256], green[256], blue[256], alpha[256];
76
 
#endif
77
 
 
78
 
float zoomtab[ZOOM_MAX + 1];
79
 
float xfactor = 1.0, yfactor = 1.0, dx = 0.5, dy = 0.5;
80
 
int zoom = 0, fullscreen = 0, mode, ww, wh;
81
 
 
82
 
int main(int argc, char **argv)
83
 
{
84
 
    int quit = 0, update = 1, help = 0, status = 0;
85
 
    int reload = 0;
86
 
 
87
 
    char **list = NULL;
88
 
    int current = 0, items = 0, opts = 1;
89
 
    int i;
90
 
 
91
 
    /* Initialise libcaca */
92
 
    if(caca_init())
93
 
    {
94
 
        fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]);
95
 
        return 1;
96
 
    }
97
 
 
98
 
    /* Set the window title */
99
 
    caca_set_window_title("cacaview");
100
 
 
101
 
    ww = caca_get_width();
102
 
    wh = caca_get_height();
103
 
 
104
 
    /* Fill the zoom table */
105
 
    zoomtab[0] = 1.0;
106
 
    for(i = 0; i < ZOOM_MAX; i++)
107
 
        zoomtab[i + 1] = zoomtab[i] * 1.08;
108
 
 
109
 
    /* Load items into playlist */
110
 
    for(i = 1; i < argc; i++)
111
 
    {
112
 
        /* Skip options except after `--' */
113
 
        if(opts && argv[i][0] == '-')
114
 
        {
115
 
            if(argv[i][1] == '-' && argv[i][2] == '\0')
116
 
                opts = 0;
117
 
            continue;
118
 
        }
119
 
 
120
 
        /* Add argv[i] to the list */
121
 
        if(items)
122
 
            list = realloc(list, (items + 1) * sizeof(char *));
123
 
        else
124
 
            list = malloc(sizeof(char *));
125
 
        list[items] = argv[i];
126
 
        items++;
127
 
 
128
 
        reload = 1;
129
 
    }
130
 
 
131
 
    /* Go ! */
132
 
    while(!quit)
133
 
    {
134
 
        unsigned int const event_mask = CACA_EVENT_KEY_PRESS
135
 
                                      | CACA_EVENT_RESIZE
136
 
                                      | CACA_EVENT_MOUSE_PRESS;
137
 
        unsigned int event, new_status = 0, new_help = 0;
138
 
 
139
 
        if(update)
140
 
            event = caca_get_event(event_mask);
141
 
        else
142
 
            event = caca_wait_event(event_mask);
143
 
 
144
 
        while(event)
145
 
        {
146
 
            if(event & CACA_EVENT_MOUSE_PRESS)
147
 
            {
148
 
                if((event & 0x00ffffff) == 1)
149
 
                {
150
 
                    if(items) current = (current + 1) % items;
151
 
                    reload = 1;
152
 
                }
153
 
                else if((event & 0x00ffffff) == 2)
154
 
                {
155
 
                    if(items) current = (items + current - 1) % items;
156
 
                    reload = 1;
157
 
                }
158
 
            }
159
 
            else if(event & CACA_EVENT_KEY_PRESS) switch(event & 0x00ffffff)
160
 
            {
161
 
            case 'n':
162
 
            case 'N':
163
 
                if(items) current = (current + 1) % items;
164
 
                reload = 1;
165
 
                break;
166
 
            case 'p':
167
 
            case 'P':
168
 
                if(items) current = (items + current - 1) % items;
169
 
                reload = 1;
170
 
                break;
171
 
            case 'f':
172
 
            case 'F':
173
 
                fullscreen = ~fullscreen;
174
 
                update = 1;
175
 
                set_zoom(zoom);
176
 
                break;
177
 
            case 'b':
178
 
                i = 1 + caca_get_feature(CACA_BACKGROUND);
179
 
                if(i > CACA_BACKGROUND_MAX) i = CACA_BACKGROUND_MIN;
180
 
                caca_set_feature(i);
181
 
                new_status = STATUS_BACKGROUND;
182
 
                update = 1;
183
 
                break;
184
 
            case 'B':
185
 
                i = -1 + caca_get_feature(CACA_BACKGROUND);
186
 
                if(i < CACA_BACKGROUND_MIN) i = CACA_BACKGROUND_MAX;
187
 
                caca_set_feature(i);
188
 
                new_status = STATUS_BACKGROUND;
189
 
                update = 1;
190
 
                break;
191
 
            case 'a':
192
 
                i = 1 + caca_get_feature(CACA_ANTIALIASING);
193
 
                if(i > CACA_ANTIALIASING_MAX) i = CACA_ANTIALIASING_MIN;
194
 
                caca_set_feature(i);
195
 
                new_status = STATUS_ANTIALIASING;
196
 
                update = 1;
197
 
                break;
198
 
            case 'A':
199
 
                i = -1 + caca_get_feature(CACA_ANTIALIASING);
200
 
                if(i < CACA_ANTIALIASING_MIN) i = CACA_ANTIALIASING_MAX;
201
 
                caca_set_feature(i);
202
 
                new_status = STATUS_ANTIALIASING;
203
 
                update = 1;
204
 
                break;
205
 
            case 'd':
206
 
                i = 1 + caca_get_feature(CACA_DITHERING);
207
 
                if(i > CACA_DITHERING_MAX) i = CACA_DITHERING_MIN;
208
 
                caca_set_feature(i);
209
 
                new_status = STATUS_DITHERING;
210
 
                update = 1;
211
 
                break;
212
 
            case 'D':
213
 
                i = -1 + caca_get_feature(CACA_DITHERING);
214
 
                if(i < CACA_DITHERING_MIN) i = CACA_DITHERING_MAX;
215
 
                caca_set_feature(i);
216
 
                new_status = STATUS_DITHERING;
217
 
                update = 1;
218
 
                break;
219
 
            case '+':
220
 
                update = 1;
221
 
                set_zoom(zoom + 1);
222
 
                break;
223
 
            case '-':
224
 
                update = 1;
225
 
                set_zoom(zoom - 1);
226
 
                break;
227
 
            case 'x':
228
 
            case 'X':
229
 
                update = 1;
230
 
                set_zoom(0);
231
 
                break;
232
 
            case 'k':
233
 
            case 'K':
234
 
            case CACA_KEY_UP:
235
 
                if(yfactor > 1.0) dy -= PAD_STEP / yfactor;
236
 
                if(dy < 0.0) dy = 0.0;
237
 
                update = 1;
238
 
                break;
239
 
            case 'j':
240
 
            case 'J':
241
 
            case CACA_KEY_DOWN:
242
 
                if(yfactor > 1.0) dy += PAD_STEP / yfactor;
243
 
                if(dy > 1.0) dy = 1.0;
244
 
                update = 1;
245
 
                break;
246
 
            case 'h':
247
 
            case 'H':
248
 
            case CACA_KEY_LEFT:
249
 
                if(xfactor > 1.0) dx -= PAD_STEP / xfactor;
250
 
                if(dx < 0.0) dx = 0.0;
251
 
                update = 1;
252
 
                break;
253
 
            case 'l':
254
 
            case 'L':
255
 
            case CACA_KEY_RIGHT:
256
 
                if(xfactor > 1.0) dx += PAD_STEP / xfactor;
257
 
                if(dx > 1.0) dx = 1.0;
258
 
                update = 1;
259
 
                break;
260
 
            case '?':
261
 
                new_help = !help;
262
 
                update = 1;
263
 
                break;
264
 
            case 'q':
265
 
            case 'Q':
266
 
                quit = 1;
267
 
                break;
268
 
            }
269
 
            else if(event == CACA_EVENT_RESIZE)
270
 
            {
271
 
                caca_refresh();
272
 
                ww = caca_get_width();
273
 
                wh = caca_get_height();
274
 
                update = 1;
275
 
                set_zoom(zoom);
276
 
            }
277
 
 
278
 
            if(status || new_status)
279
 
                status = new_status;
280
 
 
281
 
            if(help || new_help)
282
 
                help = new_help;
283
 
 
284
 
            event = caca_get_event(CACA_EVENT_KEY_PRESS);
285
 
        }
286
 
 
287
 
        if(items && reload)
288
 
        {
289
 
            char *buffer;
290
 
            int len = strlen(" Loading `%s'... ") + strlen(list[current]);
291
 
 
292
 
            if(len < ww + 1)
293
 
                len = ww + 1;
294
 
 
295
 
            buffer = malloc(len);
296
 
 
297
 
            sprintf(buffer, " Loading `%s'... ", list[current]);
298
 
            buffer[ww] = '\0';
299
 
            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
300
 
            caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
301
 
            caca_refresh();
302
 
            ww = caca_get_width();
303
 
            wh = caca_get_height();
304
 
 
305
 
            unload_image();
306
 
            load_image(list[current]);
307
 
            reload = 0;
308
 
 
309
 
            /* Reset image-specific runtime variables */
310
 
            dx = dy = 0.5;
311
 
            update = 1;
312
 
            set_zoom(0);
313
 
 
314
 
            free(buffer);
315
 
        }
316
 
 
317
 
        caca_clear();
318
 
 
319
 
        if(!items)
320
 
        {
321
 
            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
322
 
            caca_printf(ww / 2 - 5, wh / 2, " No image. ");
323
 
        }
324
 
        else if(!pixels)
325
 
        {
326
 
#if defined(HAVE_IMLIB2_H)
327
 
#   define ERROR_STRING " Error loading `%s'. "
328
 
#else
329
 
#   define ERROR_STRING " Error loading `%s'. Only BMP is supported. "
330
 
#endif
331
 
            char *buffer;
332
 
            int len = strlen(ERROR_STRING) + strlen(list[current]);
333
 
 
334
 
            if(len < ww + 1)
335
 
                len = ww + 1;
336
 
 
337
 
            buffer = malloc(len);
338
 
 
339
 
            sprintf(buffer, ERROR_STRING, list[current]);
340
 
            buffer[ww] = '\0';
341
 
            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
342
 
            caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
343
 
            free(buffer);
344
 
        }
345
 
        else
346
 
        {
347
 
            float xdelta, ydelta;
348
 
            int y, height;
349
 
 
350
 
            y = fullscreen ? 0 : 1;
351
 
            height = fullscreen ? wh : wh - 3;
352
 
 
353
 
            xdelta = (xfactor > 1.0) ? dx : 0.5;
354
 
            ydelta = (yfactor > 1.0) ? dy : 0.5;
355
 
 
356
 
            draw_checkers(ww * (1.0 - xfactor) / 2,
357
 
                          y + height * (1.0 - yfactor) / 2,
358
 
                          ww * (1.0 + xfactor) / 2,
359
 
                          y + height * (1.0 + yfactor) / 2);
360
 
 
361
 
            caca_draw_bitmap(ww * (1.0 - xfactor) * xdelta,
362
 
                             y + height * (1.0 - yfactor) * ydelta,
363
 
                             ww * (xdelta + (1.0 - xdelta) * xfactor),
364
 
                             y + height * (ydelta + (1.0 - ydelta) * yfactor),
365
 
                             bitmap, pixels);
366
 
        }
367
 
 
368
 
        if(!fullscreen)
369
 
        {
370
 
            print_status();
371
 
 
372
 
            caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLACK);
373
 
            switch(status)
374
 
            {
375
 
                case STATUS_ANTIALIASING:
376
 
                    caca_printf(0, wh - 1, "Antialiasing: %s",
377
 
                  caca_get_feature_name(caca_get_feature(CACA_ANTIALIASING)));
378
 
                    break;
379
 
                case STATUS_DITHERING:
380
 
                    caca_printf(0, wh - 1, "Dithering: %s",
381
 
                  caca_get_feature_name(caca_get_feature(CACA_DITHERING)));
382
 
                    break;
383
 
                case STATUS_BACKGROUND:
384
 
                    caca_printf(0, wh - 1, "Background: %s",
385
 
                  caca_get_feature_name(caca_get_feature(CACA_BACKGROUND)));
386
 
                    break;
387
 
            }
388
 
        }
389
 
 
390
 
        if(help)
391
 
        {
392
 
            print_help(ww - 25, 2);
393
 
        }
394
 
 
395
 
        caca_refresh();
396
 
        update = 0;
397
 
    }
398
 
 
399
 
    /* Clean up */
400
 
    unload_image();
401
 
    caca_end();
402
 
 
403
 
    return 0;
404
 
}
405
 
 
406
 
static void print_status(void)
407
 
{
408
 
    caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
409
 
    caca_draw_line(0, 0, ww - 1, 0, ' ');
410
 
    caca_draw_line(0, wh - 2, ww - 1, wh - 2, '-');
411
 
    caca_putstr(0, 0, "q:Quit  np:Next/Prev  +-x:Zoom  "
412
 
                      "hjkl:Move  d:Dithering  a:Antialias");
413
 
    caca_putstr(ww - strlen("?:Help"), 0, "?:Help");
414
 
    caca_printf(3, wh - 2, "cacaview %s", VERSION);
415
 
    caca_printf(ww - 14, wh - 2, "(zoom: %s%i)", zoom > 0 ? "+" : "", zoom);
416
 
 
417
 
    caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLACK);
418
 
    caca_draw_line(0, wh - 1, ww - 1, wh - 1, ' ');
419
 
}
420
 
 
421
 
static void print_help(int x, int y)
422
 
{
423
 
    static char const *help[] =
424
 
    {
425
 
        " +: zoom in             ",
426
 
        " -: zoom out            ",
427
 
        " x: reset zoom          ",
428
 
        " ---------------------- ",
429
 
        " hjkl: move view        ",
430
 
        " arrows: move view      ",
431
 
        " ---------------------- ",
432
 
        " a: antialiasing method ",
433
 
        " d: dithering method    ",
434
 
        " b: background mode     ",
435
 
        " ---------------------- ",
436
 
        " ?: help                ",
437
 
        " q: quit                ",
438
 
        NULL
439
 
    };
440
 
 
441
 
    int i;
442
 
 
443
 
    caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
444
 
 
445
 
    for(i = 0; help[i]; i++)
446
 
        caca_putstr(x, y + i, help[i]);
447
 
}
448
 
 
449
 
static void set_zoom(int new_zoom)
450
 
{
451
 
    int height;
452
 
 
453
 
    zoom = new_zoom;
454
 
 
455
 
    if(zoom > ZOOM_MAX) zoom = ZOOM_MAX;
456
 
    if(zoom < -ZOOM_MAX) zoom = -ZOOM_MAX;
457
 
 
458
 
    ww = caca_get_width();
459
 
    height = fullscreen ? wh : wh - 3;
460
 
 
461
 
    xfactor = (zoom < 0) ? 1.0 / zoomtab[-zoom] : zoomtab[zoom];
462
 
    yfactor = xfactor * ww / height * h / w
463
 
               * caca_get_height() / caca_get_width()
464
 
               * caca_get_window_width() / caca_get_window_height();
465
 
 
466
 
    if(yfactor > xfactor)
467
 
    {
468
 
        float tmp = xfactor;
469
 
        xfactor = tmp * tmp / yfactor;
470
 
        yfactor = tmp;
471
 
    }
472
 
}
473
 
 
474
 
static void unload_image(void)
475
 
{
476
 
#if defined(HAVE_IMLIB2_H)
477
 
    if(image)
478
 
        imlib_free_image();
479
 
    image = NULL;
480
 
    pixels = NULL;
481
 
#else
482
 
    if(pixels)
483
 
        free(pixels);
484
 
    pixels = NULL;
485
 
#endif
486
 
    if(bitmap)
487
 
        caca_free_bitmap(bitmap);
488
 
    bitmap = NULL;
489
 
}
490
 
 
491
 
static void load_image(char const *name)
492
 
{
493
 
#if defined(HAVE_IMLIB2_H)
494
 
    /* Load the new image */
495
 
    image = imlib_load_image(name);
496
 
 
497
 
    if(!image)
498
 
        return;
499
 
 
500
 
    imlib_context_set_image(image);
501
 
    pixels = (char *)imlib_image_get_data_for_reading_only();
502
 
    w = imlib_image_get_width();
503
 
    h = imlib_image_get_height();
504
 
    rmask = 0x00ff0000;
505
 
    gmask = 0x0000ff00;
506
 
    bmask = 0x000000ff;
507
 
    amask = 0xff000000;
508
 
    bpp = 32;
509
 
    depth = 4;
510
 
 
511
 
    /* Create the libcaca bitmap */
512
 
    bitmap = caca_create_bitmap(bpp, w, h, depth * w,
513
 
                                rmask, gmask, bmask, amask);
514
 
    if(!bitmap)
515
 
    {
516
 
        imlib_free_image();
517
 
        image = NULL;
518
 
    }
519
 
 
520
 
#else
521
 
    /* Try to load a BMP file */
522
 
    FILE *fp;
523
 
    unsigned int i, colors, offset, tmp, planes;
524
 
 
525
 
    fp = fopen(name, "rb");
526
 
    if(!fp)
527
 
        return;
528
 
 
529
 
    if(freadshort(fp) != 0x4d42)
530
 
    {
531
 
        fclose(fp);
532
 
        return;
533
 
    }
534
 
 
535
 
    freadint(fp); /* size */
536
 
    freadshort(fp); /* reserved 1 */
537
 
    freadshort(fp); /* reserved 2 */
538
 
 
539
 
    offset = freadint(fp);
540
 
 
541
 
    tmp = freadint(fp); /* header size */
542
 
    if(tmp == 40)
543
 
    {
544
 
        w = freadint(fp);
545
 
        h = freadint(fp);
546
 
        planes = freadshort(fp);
547
 
        bpp = freadshort(fp);
548
 
 
549
 
        tmp = freadint(fp); /* compression */
550
 
        if(tmp != 0)
551
 
        {
552
 
            fclose(fp);
553
 
            return;
554
 
        }
555
 
 
556
 
        freadint(fp); /* sizeimage */
557
 
        freadint(fp); /* xpelspermeter */
558
 
        freadint(fp); /* ypelspermeter */
559
 
        freadint(fp); /* biclrused */
560
 
        freadint(fp); /* biclrimportantn */
561
 
 
562
 
        colors = (offset - 54) / 4;
563
 
        for(i = 0; i < colors && i < 256; i++)
564
 
        {
565
 
            blue[i] = freadchar(fp) * 16;
566
 
            green[i] = freadchar(fp) * 16;
567
 
            red[i] = freadchar(fp) * 16;
568
 
            alpha[i] = 0;
569
 
            freadchar(fp);
570
 
        }
571
 
    }
572
 
    else if(tmp == 12)
573
 
    {
574
 
        w = freadint(fp);
575
 
        h = freadint(fp);
576
 
        planes = freadshort(fp);
577
 
        bpp = freadshort(fp);
578
 
 
579
 
        colors = (offset - 26) / 3;
580
 
        for(i = 0; i < colors && i < 256; i++)
581
 
        {
582
 
            blue[i] = freadchar(fp);
583
 
            green[i] = freadchar(fp);
584
 
            red[i] = freadchar(fp);
585
 
            alpha[i] = 0;
586
 
        }
587
 
    }
588
 
    else
589
 
    {
590
 
        fclose(fp);
591
 
        return;
592
 
    }
593
 
 
594
 
    /* Fill the rest of the palette */
595
 
    for(i = colors; i < 256; i++)
596
 
        blue[i] = green[i] = red[i] = alpha[i] = 0;
597
 
 
598
 
    depth = (bpp + 7) / 8;
599
 
 
600
 
    /* Sanity check */
601
 
    if(!w || w > 0x10000 || !h || h > 0x10000 || planes != 1 /*|| bpp != 24*/)
602
 
    {
603
 
        fclose(fp);
604
 
        return;
605
 
    }
606
 
 
607
 
    /* Allocate the pixel buffer */
608
 
    pixels = malloc(w * h * depth);
609
 
    if(!pixels)
610
 
    {
611
 
        fclose(fp);
612
 
        return;
613
 
    }
614
 
 
615
 
    memset(pixels, 0, w * h * depth);
616
 
 
617
 
    /* Read the bitmap data */
618
 
    for(i = h; i--; )
619
 
    {
620
 
        unsigned int j, k, bits = 0;
621
 
 
622
 
        switch(bpp)
623
 
        {
624
 
            case 1:
625
 
                for(j = 0; j < w; j++)
626
 
                {
627
 
                    k = j % 32;
628
 
                    if(k == 0)
629
 
                        bits = freadint(fp);
630
 
                    pixels[w * i * depth + j] =
631
 
                        (bits >> ((k & ~0xf) + 0xf - (k & 0xf))) & 0x1;
632
 
                }
633
 
                break;
634
 
            case 4:
635
 
                for(j = 0; j < w; j++)
636
 
                {
637
 
                    k = j % 8;
638
 
                    if(k == 0)
639
 
                        bits = freadint(fp);
640
 
                    pixels[w * i * depth + j] =
641
 
                        (bits >> (4 * ((k & ~0x1) + 0x1 - (k & 0x1)))) & 0xf;
642
 
                }
643
 
                break;
644
 
            default:
645
 
                /* Works for 8bpp, but also for 16, 24 etc. */
646
 
                fread(pixels + w * i * depth, w * depth, 1, fp);
647
 
                /* Pad reads to 4 bytes */
648
 
                tmp = (w * depth) % 4;
649
 
                tmp = (4 - tmp) % 4;
650
 
                while(tmp--)
651
 
                    freadchar(fp);
652
 
                break;
653
 
        }
654
 
    }
655
 
 
656
 
    switch(depth)
657
 
    {
658
 
    case 3:
659
 
        rmask = 0xff0000;
660
 
        gmask = 0x00ff00;
661
 
        bmask = 0x0000ff;
662
 
        amask = 0x000000;
663
 
        break;
664
 
    case 2: /* XXX: those are the 16 bits values */
665
 
        rmask = 0x7c00;
666
 
        gmask = 0x03e0;
667
 
        bmask = 0x001f;
668
 
        amask = 0x0000;
669
 
        break;
670
 
    case 1:
671
 
    default:
672
 
        bpp = 8;
673
 
        rmask = gmask = bmask = amask = 0;
674
 
        break;
675
 
    }
676
 
 
677
 
    fclose(fp);
678
 
 
679
 
    /* Create the libcaca bitmap */
680
 
    bitmap = caca_create_bitmap(bpp, w, h, depth * w,
681
 
                                rmask, gmask, bmask, amask);
682
 
    if(!bitmap)
683
 
    {
684
 
        free(pixels);
685
 
        pixels = NULL;
686
 
        return;
687
 
    }
688
 
 
689
 
    if(bpp == 8)
690
 
        caca_set_bitmap_palette(bitmap, red, green, blue, alpha);
691
 
#endif
692
 
}
693
 
 
694
 
static void draw_checkers(int x1, int y1, int x2, int y2)
695
 
{
696
 
    int xn, yn;
697
 
 
698
 
    if(x2 + 1 > (int)caca_get_width()) x2 = caca_get_width() - 1;
699
 
    if(y2 + 1 > (int)caca_get_height()) y2 = caca_get_height() - 1;
700
 
 
701
 
    for(yn = y1 > 0 ? y1 : 0; yn <= y2; yn++)
702
 
        for(xn = x1 > 0 ? x1 : 0; xn <= x2; xn++)
703
 
    {
704
 
        if((((xn - x1) / 5) ^ ((yn - y1) / 3)) & 1)
705
 
            caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_DARKGRAY);
706
 
        else
707
 
            caca_set_color(CACA_COLOR_DARKGRAY, CACA_COLOR_LIGHTGRAY);
708
 
        caca_putchar(xn, yn, ' ');
709
 
    }
710
 
}
711
 
 
712
 
#if !defined(HAVE_IMLIB2_H)
713
 
static int freadint(FILE *fp)
714
 
{
715
 
    unsigned char buffer[4];
716
 
    fread(buffer, 4, 1, fp);
717
 
    return ((int)buffer[3] << 24) | ((int)buffer[2] << 16)
718
 
             | ((int)buffer[1] << 8) | ((int)buffer[0]);
719
 
}
720
 
 
721
 
static int freadshort(FILE *fp)
722
 
{
723
 
    unsigned char buffer[2];
724
 
    fread(buffer, 2, 1, fp);
725
 
    return ((int)buffer[1] << 8) | ((int)buffer[0]);
726
 
}
727
 
 
728
 
static int freadchar(FILE *fp)
729
 
{
730
 
    unsigned char buffer;
731
 
    fread(&buffer, 1, 1, fp);
732
 
    return (int)buffer;
733
 
}
734
 
#endif
735