Ignore:
Timestamp:
Dec 17, 2003, 12:06:54 AM (16 years ago)
Author:
Sam Hocevar
Message:
  • examples/view.c: + If Imlib2 is not available, use a custom simple BMP loader. + Draw the bottom bar one line higher to leave room for a status line. + '?' now properly toggles help.
  • examples/Makefile.am: + Always build cacaview.
Location:
libcaca/trunk/examples
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/examples/Makefile.am

    r244 r254  
    2121caca_spritedit_CPPFLAGS = -I$(top_srcdir)/src
    2222
    23 if USE_IMLIB2
    2423cacaview = cacaview
    2524cacaview_SOURCES = view.c
    2625cacaview_LDADD = ../src/libcaca.a @CACA_LIBS@
    2726cacaview_CPPFLAGS = -I$(top_srcdir)/src -DX_DISPLAY_MISSING=1
     27if USE_IMLIB2
    2828cacaview_CFLAGS = `imlib2-config --cflags`
    2929cacaview_LDFLAGS = `imlib2-config --libs`
     30else
     31cacaview_CFLAGS =
     32cacaview_LDFLAGS =
    3033endif
    3134
  • libcaca/trunk/examples/view.c

    r249 r254  
    2929#include <unistd.h>
    3030
    31 #include <Imlib2.h>
     31#if defined(HAVE_IMLIB2_H)
     32#   include <Imlib2.h>
     33#else
     34#   include <stdio.h>
     35#endif
    3236
    3337#include "caca.h"
     38
     39/* Local macros */
     40#define STATUS_DITHERING 1
     41#define STATUS_ANTIALIASING 2
     42#define STATUS_BACKGROUND 3
    3443
    3544/* Local functions */
    3645static void load_image(const char *);
     46static void unload_image(void);
    3747static void draw_checkers(unsigned int, unsigned int,
    3848                          unsigned int, unsigned int);
     49#if !defined(HAVE_IMLIB2_H)
     50static int freadint(FILE *);
     51static int freadshort(FILE *);
     52static int freadchar(FILE *);
     53#endif
    3954
    4055/* Local variables */
     56#if defined(HAVE_IMLIB2_H)
    4157Imlib_Image image = NULL;
     58#endif
    4259char *pixels = NULL;
    4360struct caca_bitmap *bitmap = NULL;
    44 int x, y, w, h;
     61int x, y;
     62unsigned int w, h, depth, bpp, rmask, gmask, bmask, amask;
     63unsigned int red[256], green[256], blue[256], alpha[256];
    4564
    4665int main(int argc, char **argv)
    4766{
    48     int quit = 0, update = 1, help = 0, reload = 0, fullscreen = 0, zoom = 0;
     67    int quit = 0, update = 1, help = 0, fullscreen = 0, status = 0;
     68    int reload = 0, zoom = 0;
    4969
    5070    char **list = NULL;
     
    87107        int wh = caca_get_height();
    88108
    89         int event;
     109        int event, new_status = 0, new_help = 0;
    90110
    91111        while((event = caca_get_event()))
     
    112132                if(i > CACA_BACKGROUND_MAX) i = CACA_BACKGROUND_MIN;
    113133                caca_set_feature(i);
     134                new_status = STATUS_BACKGROUND;
    114135                update = 1;
    115136                break;
     
    118139                if(i < CACA_BACKGROUND_MIN) i = CACA_BACKGROUND_MAX;
    119140                caca_set_feature(i);
     141                new_status = STATUS_BACKGROUND;
    120142                update = 1;
    121143                break;
     
    124146                if(i > CACA_ANTIALIASING_MAX) i = CACA_ANTIALIASING_MIN;
    125147                caca_set_feature(i);
     148                new_status = STATUS_ANTIALIASING;
    126149                update = 1;
    127150                break;
     
    130153                if(i < CACA_ANTIALIASING_MIN) i = CACA_ANTIALIASING_MAX;
    131154                caca_set_feature(i);
     155                new_status = STATUS_ANTIALIASING;
    132156                update = 1;
    133157                break;
     
    136160                if(i > CACA_DITHERING_MAX) i = CACA_DITHERING_MIN;
    137161                caca_set_feature(i);
     162                new_status = STATUS_DITHERING;
    138163                update = 1;
    139164                break;
     
    142167                if(i < CACA_DITHERING_MIN) i = CACA_DITHERING_MAX;
    143168                caca_set_feature(i);
     169                new_status = STATUS_DITHERING;
    144170                update = 1;
    145171                break;
     
    182208                break;
    183209            case CACA_EVENT_KEY_PRESS | '?':
    184                 help = 1;
     210                new_help = !help;
    185211                update = 1;
    186212                break;
     
    190216                break;
    191217            }
     218
     219            if(status || new_status)
     220                status = new_status;
     221
     222            if(help || new_help)
     223                help = new_help;
    192224        }
    193225
     
    205237            caca_refresh();
    206238
     239            unload_image();
    207240            load_image(list[current]);
    208241            reload = 0;
     
    219252
    220253        caca_clear();
    221         caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
    222254
    223255        if(!items)
     256        {
     257            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
    224258            caca_printf(ww / 2 - 5, wh / 2, " No image. ");
    225         else if(!image)
     259        }
     260        else if(!pixels)
    226261        {
    227262            char *buffer = malloc(ww + 1);
    228263            snprintf(buffer, ww, " Error loading `%s'. ", list[current]);
    229264            buffer[ww] = '\0';
     265            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
    230266            caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
    231267            free(buffer);
     
    248284            if(x < xn) x = xn;
    249285            if(y < yn) y = yn;
    250             if(xn + x > w) x = w - xn;
    251             if(yn + y > h) y = h - yn;
    252             newbitmap = caca_create_bitmap(32, 2 * xn, 2 * yn, 4 * w,
    253                                            0x00ff0000, 0x0000ff00, 0x000000ff,
    254                                            0xff000000);
     286            if(xn + x > (int)w) x = w - xn;
     287            if(yn + y > (int)h) y = h - yn;
     288            newbitmap = caca_create_bitmap(bpp, 2 * xn, 2 * yn, depth * w,
     289                                           rmask, gmask, bmask, amask);
     290            if(bpp == 8)
     291                caca_set_bitmap_palette(newbitmap, red, green, blue, alpha);
    255292            draw_checkers(0, fullscreen ? 0 : 1,
    256                           ww - 1, fullscreen ? wh - 1 : wh - 2);
     293                          ww - 1, fullscreen ? wh - 1 : wh - 3);
    257294            caca_draw_bitmap(0, fullscreen ? 0 : 1,
    258                              ww - 1, fullscreen ? wh - 1 : wh - 2,
     295                             ww - 1, fullscreen ? wh - 1 : wh - 3,
    259296                             newbitmap,
    260                              pixels + 4 * (x - xn) + 4 * w * (y - yn));
     297                             pixels + depth * (x - xn) + depth * w * (y - yn));
    261298            caca_free_bitmap(newbitmap);
    262299        }
     
    264301        {
    265302            draw_checkers(0, fullscreen ? 0 : 1,
    266                           ww - 1, fullscreen ? wh - 1 : wh - 2);
     303                          ww - 1, fullscreen ? wh - 1 : wh - 3);
    267304            caca_draw_bitmap(0, fullscreen ? 0 : 1,
    268                              ww - 1, fullscreen ? wh - 1 : wh - 2,
     305                             ww - 1, fullscreen ? wh - 1 : wh - 3,
    269306                             bitmap, pixels);
    270307        }
    271308
    272         caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
    273 
    274309        if(!fullscreen)
    275310        {
     311            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
    276312            caca_draw_line(0, 0, ww - 1, 0, ' ');
    277             caca_draw_line(0, wh - 1, ww - 1, wh - 1, '-');
     313            caca_draw_line(0, wh - 2, ww - 1, wh - 2, '-');
    278314            caca_putstr(0, 0, "q:Quit  np:Next/Prev  +-x:Zoom  "
    279315                              "hjkl:Move  d:Dithering  a:Antialias");
    280316            caca_putstr(ww - strlen("?:Help"), 0, "?:Help");
    281             caca_printf(3, wh - 1, "cacaview %s (%s, %s)", VERSION,
    282                 caca_get_feature_name(caca_get_feature(CACA_DITHERING)),
    283                 caca_get_feature_name(caca_get_feature(CACA_ANTIALIASING)));
    284             caca_printf(ww - 14, wh - 1,
     317            caca_printf(3, wh - 2, "cacaview %s", VERSION);
     318            caca_printf(ww - 14, wh - 2,
    285319                        "(zoom: %s%i)", zoom > 0 ? "+" : "", zoom);
     320
     321            caca_set_color(CACA_COLOR_LIGHTRED, CACA_COLOR_BLACK);
     322            caca_draw_line(0, wh - 1, ww - 1, wh - 1, ' ');
     323            switch(status)
     324            {
     325                case STATUS_ANTIALIASING:
     326                    caca_printf(0, wh - 1, "Antialiasing: %s",
     327                  caca_get_feature_name(caca_get_feature(CACA_ANTIALIASING)));
     328                    break;
     329                case STATUS_DITHERING:
     330                    caca_printf(0, wh - 1, "Dithering: %s",
     331                  caca_get_feature_name(caca_get_feature(CACA_DITHERING)));
     332                    break;
     333                case STATUS_BACKGROUND:
     334                    caca_printf(0, wh - 1, "Background: %s",
     335                  caca_get_feature_name(caca_get_feature(CACA_BACKGROUND)));
     336                    break;
     337            }
    286338        }
    287339
    288340        if(help)
    289341        {
    290             caca_putstr(ww - 22, 2,  " +: zoom in             ");
    291             caca_putstr(ww - 22, 3,  " -: zoom out            ");
    292             caca_putstr(ww - 22, 4,  " x: reset zoom          ");
    293             caca_putstr(ww - 22, 5,  " ---------------------- ");
    294             caca_putstr(ww - 22, 6,  " hjkl: move view        ");
    295             caca_putstr(ww - 22, 7,  " arrows: move view      ");
    296             caca_putstr(ww - 22, 8,  " ---------------------- ");
    297             caca_putstr(ww - 22, 9,  " a: antialiasing method ");
    298             caca_putstr(ww - 22, 9,  " d: dithering method    ");
    299             caca_putstr(ww - 22, 10, " ---------------------- ");
    300             caca_putstr(ww - 22, 11, " ?: help                ");
    301             caca_putstr(ww - 22, 12, " q: quit                ");
    302 
    303             help = 0;
     342            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
     343            caca_putstr(ww - 25, 2,  " +: zoom in             ");
     344            caca_putstr(ww - 25, 3,  " -: zoom out            ");
     345            caca_putstr(ww - 25, 4,  " x: reset zoom          ");
     346            caca_putstr(ww - 25, 5,  " ---------------------- ");
     347            caca_putstr(ww - 25, 6,  " hjkl: move view        ");
     348            caca_putstr(ww - 25, 7,  " arrows: move view      ");
     349            caca_putstr(ww - 25, 8,  " ---------------------- ");
     350            caca_putstr(ww - 25, 9,  " a: antialiasing method ");
     351            caca_putstr(ww - 25, 10, " d: dithering method    ");
     352            caca_putstr(ww - 25, 11, " b: background mode     ");
     353            caca_putstr(ww - 25, 12, " ---------------------- ");
     354            caca_putstr(ww - 25, 13, " ?: help                ");
     355            caca_putstr(ww - 25, 14, " q: quit                ");
    304356        }
    305357
     
    308360    }
    309361
     362    /* Clean up */
     363    unload_image();
     364    caca_end();
     365
     366    return 0;
     367}
     368
     369static void unload_image(void)
     370{
     371#ifdef HAVE_IMLIB2_H
     372    if(image)
     373        imlib_free_image();
     374    image = NULL;
     375    pixels = NULL;
     376#else
     377    if(pixels)
     378        free(pixels);
     379    pixels = NULL;
     380#endif
    310381    if(bitmap)
    311382        caca_free_bitmap(bitmap);
    312     if(image)
    313         imlib_free_image();
    314 
    315     /* Clean up */
    316     caca_end();
    317 
    318     return 0;
     383    bitmap = NULL;
    319384}
    320385
    321386static void load_image(const char *name)
    322387{
    323     /* Empty previous data */
    324     if(image)
    325         imlib_free_image();
    326 
    327     if(bitmap)
    328         caca_free_bitmap(bitmap);
    329 
    330     image = NULL;
    331     bitmap = NULL;
    332 
     388#ifdef HAVE_IMLIB2_H
    333389    /* Load the new image */
    334390    image = imlib_load_image(name);
    335391
    336392    if(!image)
    337     {
    338393        return;
    339     }
    340394
    341395    imlib_context_set_image(image);
     
    343397    w = imlib_image_get_width();
    344398    h = imlib_image_get_height();
     399    rmask = 0x00ff0000;
     400    gmask = 0x0000ff00;
     401    bmask = 0x000000ff;
     402    amask = 0xff000000;
     403    bpp = 32;
     404    depth = 4;
     405
     406    /* Create the libcaca bitmap */
     407    bitmap = caca_create_bitmap(bpp, w, h, depth * w,
     408                                rmask, gmask, bmask, amask);
     409    if(!bitmap)
     410    {
     411        imlib_free_image();
     412        image = NULL;
     413    }
     414
     415#else
     416    /* Try to load a BMP file */
     417    FILE *fp;
     418    unsigned int i, colors, offset, tmp, planes;
     419
     420    fp = fopen(name, "rb");
     421    if(!fp)
     422        return;
     423
     424    if(freadshort(fp) != 0x4d42)
     425    {
     426        fclose(fp);
     427        return;
     428    }
     429
     430    freadint(fp); /* size */
     431    freadshort(fp); /* reserved 1 */
     432    freadshort(fp); /* reserved 2 */
     433
     434    offset = freadint(fp);
     435
     436    tmp = freadint(fp); /* header size */
     437    if(tmp == 40)
     438    {
     439        w = freadint(fp);
     440        h = freadint(fp);
     441        planes = freadshort(fp);
     442        bpp = freadshort(fp);
     443
     444        tmp = freadint(fp); /* compression */
     445        if(tmp != 0)
     446        {
     447            fclose(fp);
     448            return;
     449        }
     450
     451        freadint(fp); /* sizeimage */
     452        freadint(fp); /* xpelspermeter */
     453        freadint(fp); /* ypelspermeter */
     454        freadint(fp); /* biclrused */
     455        freadint(fp); /* biclrimportantn */
     456
     457        colors = (offset - 54) / 4;
     458        for(i = 0; i < colors && i < 256; i++)
     459        {
     460            blue[i] = freadchar(fp) * 16;
     461            green[i] = freadchar(fp) * 16;
     462            red[i] = freadchar(fp) * 16;
     463            alpha[i] = 0;
     464            freadchar(fp);
     465        }
     466    }
     467    else if(tmp == 12)
     468    {
     469        w = freadint(fp);
     470        h = freadint(fp);
     471        planes = freadshort(fp);
     472        bpp = freadshort(fp);
     473
     474        colors = (offset - 26) / 3;
     475        for(i = 0; i < colors && i < 256; i++)
     476        {
     477            blue[i] = freadchar(fp);
     478            green[i] = freadchar(fp);
     479            red[i] = freadchar(fp);
     480            alpha[i] = 0;
     481        }
     482    }
     483    else
     484    {
     485        fclose(fp);
     486        return;
     487    }
     488
     489    /* Fill the rest of the palette */
     490    for(i = colors; i < 256; i++)
     491        blue[i] = green[i] = red[i] = alpha[i] = 0;
     492
     493    depth = (bpp + 7) / 8;
     494
     495    /* Sanity check */
     496    if(!w || w > 0x10000 || !h || h > 0x10000 || planes != 1 /*|| bpp != 24*/)
     497    {
     498        fclose(fp);
     499        return;
     500    }
     501
     502    /* Allocate the pixel buffer */
     503    pixels = malloc(w * h * depth);
     504    if(!pixels)
     505    {
     506        fclose(fp);
     507        return;
     508    }
     509
     510    memset(pixels, 0, w * h * depth);
     511
     512    /* Read the bitmap data */
     513    for(i = h; i--; )
     514    {
     515        unsigned int j, k, bits = 0;
     516
     517        switch(bpp)
     518        {
     519            case 1:
     520                for(j = 0; j < w; j++)
     521                {
     522                    k = j % 32;
     523                    if(k == 0)
     524                        bits = freadint(fp);
     525                    pixels[w * i * depth + j] =
     526                        (bits >> ((k & ~0xf) + 0xf - (k & 0xf))) & 0xf;
     527                }
     528                break;
     529            case 4:
     530                for(j = 0; j < w; j++)
     531                {
     532                    k = j % 8;
     533                    if(k == 0)
     534                        bits = freadint(fp);
     535                    pixels[w * i * depth + j] =
     536                        (bits >> (4 * ((k & ~0x1) + 0x1 - (k & 0x1)))) & 0xf;
     537                }
     538                break;
     539            default:
     540                fread(pixels + w * i * depth, w * depth, 1, fp);
     541                /* Pad reads to 4 bytes */
     542                tmp = (4 - (w * depth) % 4) % 4;
     543                while(tmp--)
     544                    freadchar(fp);
     545                break;
     546        }
     547    }
     548
     549    switch(depth)
     550    {
     551    case 3:
     552        rmask = 0xff0000;
     553        gmask = 0x00ff00;
     554        bmask = 0x0000ff;
     555        amask = 0x000000;
     556        break;
     557    case 2: /* XXX: those are the 16 bits values */
     558        rmask = 0x7c00;
     559        gmask = 0x03e0;
     560        bmask = 0x001f;
     561        amask = 0x0000;
     562        break;
     563    case 1:
     564    default:
     565        bpp = 8;
     566        rmask = gmask = bmask = amask = 0;
     567        break;
     568    }
     569
     570    fclose(fp);
     571
     572    /* Create the libcaca bitmap */
     573    bitmap = caca_create_bitmap(bpp, w, h, depth * w,
     574                                rmask, gmask, bmask, amask);
     575    if(!bitmap)
     576    {
     577        free(pixels);
     578        pixels = NULL;
     579        return;
     580    }
     581
     582    if(bpp == 8)
     583        caca_set_bitmap_palette(bitmap, red, green, blue, alpha);
     584#endif
     585
    345586    x = w / 2;
    346587    y = h / 2;
    347 
    348     /* Create the libcaca bitmap */
    349     bitmap = caca_create_bitmap(32, w, h, 4 * w, 0x00ff0000, 0x0000ff00,
    350                                 0x000000ff, 0xff000000);
    351     if(!bitmap)
    352     {
    353         imlib_free_image();
    354         image = NULL;
    355     }
    356588}
    357589
     
    364596        for(xn = x1; xn <= x2; xn++)
    365597    {
    366         if(((xn / 4) ^ (yn / 2)) & 1)
     598        if((((xn - x1) / 5) ^ ((yn - y1) / 3)) & 1)
    367599            caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_DARKGRAY);
    368600        else
     
    372604}
    373605
     606#if !defined(HAVE_IMLIB2_H)
     607static int freadint(FILE *fp)
     608{
     609    unsigned char buffer[4];
     610    fread(buffer, 4, 1, fp);
     611    return ((int)buffer[3] << 24) | ((int)buffer[2] << 16)
     612             | ((int)buffer[1] << 8) | ((int)buffer[0]);
     613}
     614
     615static int freadshort(FILE *fp)
     616{
     617    unsigned char buffer[2];
     618    fread(buffer, 2, 1, fp);
     619    return ((int)buffer[1] << 8) | ((int)buffer[0]);
     620}
     621
     622static int freadchar(FILE *fp)
     623{
     624    unsigned char buffer;
     625    fread(&buffer, 1, 1, fp);
     626    return (int)buffer;
     627}
     628#endif
     629
Note: See TracChangeset for help on using the changeset viewer.