9fans archive / 1998 / 03 / 20 /    prev next

From: arisawa@pla... arisawa@pla...
Subject: No subject
Date: Sat, 21 Mar 1998 02:11:37 GMT

Hello 9fans!

The following is a tool to convert dump image file to pic format.
I hope this is more useful than dumppic.

Kenji Arisawa
E-mail: arisawa@aic...

--------------------------- dump2pic.c ----------------------
/*
*   dump2pic
*
*   Dump2pic converts dumpfile to picfile
*
*   usage: dump2pic [-m] dumpfile
*   option m produces monochrome output
*   picfile is written to stdout
*
*   Plan9 has similar tool named dumppic,
*   However dumppic does not read headers in dumpfile,
*   and what is worse, dumppic does not put cmap to the output.
*
*   Dump2pic read headers of dumpfile and cmap of
*   current screen, and put these informations to the output.
*
*   1998/03/20
*   Kenji Arisawa
*   E-mail: arisawa@aic...
*/

#include <u.h>
#include <libc.h>
#include <libg.h>
#include <fb.h>

/*
*   dump2pic convert dumpfile to picfile
*   reading dumpfile headers
*   putting screen-cmap
*
*   opt:
*       1 for 256 color output
*       0 for monochrome output
*/
void    dump2pic(char *input, char *output, int opt){
    PICFILE *pf;
    Bitmap *b;
    Rectangle r;
    RGB map[256]; /* see: rgbpix(2) */
    uchar cmap[256*3];
    int fd;
    int v;
    
    binit(0,0,0);
    fd = open(input,OREAD);
    if(!fd){
        fprint(2, "%s: file not open", input);
        exits(0);
    }
    b = rdbitmapfile(fd);
    if(!b){
        perror("rdbitmapfile error");
        exits(0);
    }
    close(fd);

    /* we use screen cmap */
    rdcolmap(&screen, map);
    /*
    *   Translate it to cmap
    *   Note that map[v].X is ulong (32 bits)
    *   where X is red, green and blue.
    *   see: /sys/src/fb/getmap.c
    */
    if(opt){/* we use screen-cmap */
        for(v = 0; v < 256; v++){
            cmap[3*v + 0] = (map[255 - v].red >> 24);
            cmap[3*v + 1] = (map[255 - v].green >> 24);
            cmap[3*v + 2] = (map[255 - v].blue >> 24);
        }
    }else {/* we create monochrome cmap */
        uchar lmap[256];
        ulong x, xr, xg, xb;
        /* be careful in overflow */
        for(v=0;v < 256;v++){
            xr = map[v].red >> 16;
            xg = map[v].green >> 16;
            xb = map[v].blue >> 16;
            x = (xr*299+xg*587+xb*114)/1000;
            /* 
            *   I found these weighting parameters
            *   in /sys/src/fb/pic2gif
            */
            lmap[v] = x >> 8;
        }
        for(v = 0; v < 256; v++){
            cmap[3*v + 0] = lmap[255 - v];
            cmap[3*v + 1] = lmap[255 - v];
            cmap[3*v + 2] = lmap[255 - v];
        }
    }

    r = b->r;
    pf=picopen_w(output, "runcode", screen.r.min.x,
        screen.r.min.y, Dx(r), Dy(r), "m", 0, (char*)cmap);
    if(pf==0){
        fprint(2,"can't create %s\n", output);
        exits("create");
    }
    if(wrpicfile(pf, b)<0){
        fprint(2, "%s: can't save\n", output);
        exits("output error");
    }
    picclose(pf);
    bfree(b);
    bclose();
}

void main(int argc, char *argv[]) {
    int opt;
    opt = 1;
    argc = getflags(argc, argv, "m:0");
    if(flag['m']) opt = 0;
    if(argc != 2) usage("dumpfile");
    dump2pic(argv[1], "OUT", opt);
}