Subversion Repositories display

Rev

Rev 285 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (C) 2011.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */

package test.display;

import uk.me.parabola.imgfmt.app.BitReader;

/**
 * @author Steve Ratcliffe
 */

public class TypSectionDisplayer {
    static int printBitmap(Displayer d, int width, int height) {
                int ncolours = d.byteValue("Number of colours %d") & 0xff;
                int colourMode = d.byteValue("Colour mode %d");

                if (colourMode == 0x20) {
                        // In this colour mode there is an alpha channel for the colours, which
                        // is 4bits wide.
                        int nbytes = ncolours * 3; // For rgb
                        nbytes += (ncolours+1) / 2; // For the alpha channel

                        // Grab the bytes we need and then use a bit reader to decode the
                        // colours.
                        DisplayItem item = d.rawItem(nbytes);

                        BitReader br = new BitReader(item.getBytes());
                        for (int c = 0; c < ncolours; c++) {
                                int col = br.get(24);
                                int alpha = br.get(4);
                                // in the typ file 0=opaque, f=transparent so convert to normal
                                // 00=transparent, ff=opaque
                                alpha = 15-alpha;
                                alpha = (alpha<<4) + alpha;

                                item.addText("Colour #%06x%x%x", col, alpha&0xf, alpha&0xf);
                        }
                } else {
                        for (int c = 0; c < ncolours; c++) {
                                d.int3Value("Colour #%06x");
                        }
                }

                if (ncolours == 0 && colourMode == 0x10)
                        d.int3Value("transparent: %06x");

                int bpp = bitsPerPixel(ncolours, colourMode);

                int adjwidth = width;
                while (((adjwidth * bpp) & 0x7 ) != 0)
                        adjwidth++;
                d.rawValue(adjwidth*height*bpp/8, "Pixmap data");

                int bits = 0;

                bits += width * height * bpp;
                bits += ncolours * 3 * 8;
                if (colourMode == 0x10 && ncolours == 0)
                        bits += 3*8; // for transparent byte
                bits += 0x2c;
                return bits/2;
        }

    static int bitsPerPixel(int ncolours, int colourMode) {
                int nbits = 8;
                if (colourMode == 0) {
            if (ncolours == 0)
                nbits = 24;
            else if (ncolours < 2)
                                nbits = 1;
                        else if (ncolours < 4)
                                nbits = 2;
                        else if (ncolours < 16)
                                nbits = 4;

                } else if (colourMode == 0x10) {
            if (ncolours == 0)
                nbits = 24;
            else if (ncolours < 3)
                                nbits = 2;
                        else if (ncolours < 15) {
                                nbits = 4;
                        }
                } else if (colourMode == 0x20) {
            if (ncolours == 0)
                nbits = 28;
                        else if (ncolours < 2)
                                nbits = 1;
                        else if (ncolours < 4)
                                nbits = 2;
                        else if (ncolours < 16)
                                nbits = 4;
                }

                return nbits;
        }

    protected void printLabels(Displayer d) {

        DisplayItem item = d.intItem(1);
        int len = item.getValue();

        // Variable length integer with the length indicated by a suffix
        if ((len & 1) == 1) {
            len >>= 1;
        } else if ((len & 3) == 2) {
            len >>= 2;
            item = d.intItem(1);
            len += item.getValue() << 6;
        } else
            assert false; // I'm assuming labels are never more than 64k

        item.addText("Length of strings %d", len);

        while (len > 0) {
            d.byteValue("Lang %d");
            String s = d.zstringValue("String: %s");
            len -= s.length() + 2;
        }
    }

    protected void printColourScheme(Displayer d, int colourScheme) {
        boolean hasNight = (colourScheme & 1) != 0;

        switch (colourScheme & ~0x9) {
        case 0:
            d.int3Value("Day #%06x");
            d.int3Value("Day #%06x");
            if (hasNight) {
                d.int3Value("Night #%06x");
                d.int3Value("Night #%06x");
            }
            break;
        case 2:
            d.int3Value("Day #%06x");
            if (hasNight) {
                d.int3Value("Night #%06x");
                d.int3Value("Night #%06x");
            }
            break;
        case 4:
            d.int3Value("Day #%06x");
            d.int3Value("Day #%06x");
            if (hasNight) {
                d.int3Value("Night #%06x");
            }
            break;
        case 6:
            d.int3Value("Day #%06x");
            if (hasNight) {
                d.int3Value("Night #%06x");
            }
            break;
        default:
            assert false : colourScheme;
        }
    }

    protected void printFontInfo(Displayer d) {
        int fontExt = d.byteValue("Font %x");
        if ((fontExt & 0x8) != 0) {
            d.int3Value("Day colour #%06x");
        }
        if ((fontExt & 0x10) != 0)
            d.int3Value("Night colour #%06x");
    }
}