view org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/internal/image/TIFFModifiedHuffmanCodec.d @ 120:536e43f63c81

Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661 ===D2=== * added [Try]Immutable/Const/Shared templates to work with differenses in D1/D2 instead of version statements used these templates to work with strict type storage rules of dmd-2.053 * com.ibm.icu now also compilable with D2, but not tested yet * small fixes Snippet288 - shared data is in TLS ===Phobos=== * fixed critical bugs in Phobos implemention completely incorrect segfault prone fromStringz (Linux's port ruthless killer) terrible, incorrect StringBuffer realization (StyledText killer) * fixed small bugs as well Snippet72 - misprint in the snippet * implemented missed functionality for Phobos ByteArrayOutputStream implemented (image loading available) formatting correctly works for all DWT's cases As a result, folowing snippets now works with Phobos (Snippet### - what is fixed): Snippet24, 42, 111, 115, 130, 235, 276 - bad string formatting Snippet48, 282 - crash on image loading Snippet163, 189, 211, 213, 217, 218, 222 - crash on copy/cut in StyledText Snippet244 - hang-up ===Tango=== * few changes for the latest Tango trunc-r5661 * few small performance improvments ===General=== * implMissing-s for only one version changed to implMissingInTango/InPhobos * incorrect calls to Format in toString-s fixed * fixed loading \uXXXX characters in ResourceBundle * added good UTF-8 support for StyledText, TextLayout (Win32) and friends UTF functions revised and tested. It is now in java.nonstandard.*Utf modules StyledText and TextLayout (Win32) modules revised for UTF-8 support * removed small diferences in most identical files in *.swt.* folders *.swt.internal.image, *.swt.events and *.swt.custom are identical in Win32/Linux32 now 179 of 576 (~31%) files in *.swt.* folders are fully identical * Win32: snippets now have right subsystem, pretty icons and native system style controls * small fixes in snippets Snippet44 - it's not Snippet44 Snippet212 - functions work with different images and offsets arrays Win32: Snippet282 - crash on close if the button has an image Snippet293 - setGrayed is commented and others Win32: As a result, folowing snippets now works Snippet68 - color doesn't change Snippet163, 189, 211, 213, 217, 218, 222 - UTF-8 issues (see above) Snippet193 - no tabel headers
author Denis Shelomovskij <verylonglogin.reg@gmail.com>
date Sat, 09 Jul 2011 15:50:20 +0300
parents 7a2dd761a8b2
children
line wrap: on
line source

/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 * Port to the D programming language:
 *     Frank Benoit <benoit@tionex.de>
 *******************************************************************************/
module org.eclipse.swt.internal.image.TIFFModifiedHuffmanCodec;

import org.eclipse.swt.SWT;
import java.lang.all;

/*
* Decoder for
* - CCITT Group 3 1-Dimensional Modified Huffman run length encoding
*   (TIFF compression type 2)
* - CCITT T.4 bi-level encoding 1D
*   (TIFF compression type 3 option 1D)
*/
final class TIFFModifiedHuffmanCodec {
    static const short[][][] BLACK_CODE = [
        /* 2 bits  */
        [[ cast(short)2, 3], [ cast(short)3, 2]],
        /* 3 bits  */
        [[ cast(short)2, 1], [ cast(short)3, 4]],
        /* 4 bits  */
        [[ cast(short)2, 6], [ cast(short)3, 5]],
        /* 5 bits  */
        [[ cast(short)3, 7]],
        /* 6 bits  */
        [[ cast(short)4, 9], [ cast(short)5, 8]],
        /* 7 bits  */
        [[ cast(short)4, 10], [ cast(short)5, 11], [ cast(short)7, 12]],
        /* 8 bits  */
        [[ cast(short)4, 13], [ cast(short)7, 14]],
        /* 9 bits  */
        [[ cast(short)24, 15]],
        /* 10 bits */
        [[ cast(short)8, 18], [ cast(short)15, 64], [ cast(short)23, 16], [ cast(short)24, 17], [ cast(short)55, 0]],
        /* 11 bits */
        [/* EOL */[ cast(short)0, -1], [ cast(short)8, 1792], [ cast(short)23, 24], [ cast(short)24, 25], [ cast(short)40, 23], [ cast(short)55, 22], [ cast(short)103, 19],
        [ cast(short)104, 20], [ cast(short)108, 21], [ cast(short)12, 1856], [ cast(short)13, 1920]],
        /* 12 bits */
        [[ cast(short)18, 1984], [ cast(short)19, 2048], [ cast(short)20, 2112], [ cast(short)21, 2176], [ cast(short)22, 2240], [ cast(short)23, 2304],
        [ cast(short)28, 2368], [ cast(short)29, 2432], [ cast(short)30, 2496], [ cast(short)31, 2560], [ cast(short)36, 52], [ cast(short)39, 55], [ cast(short)40, 56],
        [ cast(short)43, 59], [ cast(short)44, 60], [ cast(short)51, 320], [ cast(short)52, 384], [ cast(short)53, 448], [ cast(short)55, 53], [ cast(short)56, 54], [ cast(short)82, 50],
        [ cast(short)83, 51], [ cast(short)84, 44], [ cast(short)85, 45], [ cast(short)86, 46], [ cast(short)87, 47], [ cast(short)88, 57], [ cast(short)89, 58], [ cast(short)90, 61],
        [ cast(short)91, 256], [ cast(short)100, 48], [ cast(short)101, 49], [ cast(short)102, 62], [ cast(short)103, 63], [ cast(short)104, 30], [ cast(short)105, 31],
        [ cast(short)106, 32], [ cast(short)107, 33], [ cast(short)108, 40], [ cast(short)109, 41], [ cast(short)200, 128], [ cast(short)201, 192], [ cast(short)202, 26],
        [ cast(short)203, 27], [ cast(short)204, 28], [ cast(short)205, 29], [ cast(short)210, 34], [ cast(short)211, 35], [ cast(short)212, 36], [ cast(short)213, 37],
        [ cast(short)214, 38], [ cast(short)215, 39], [ cast(short)218, 42], [ cast(short)219, 43]],
        /* 13 bits */
        [[ cast(short)74, 640], [ cast(short)75, 704], [ cast(short)76, 768], [ cast(short)77, 832], [ cast(short)82, 1280], [ cast(short)83, 1344], [ cast(short)84, 1408],
        [ cast(short)85, 1472], [ cast(short)90, 1536], [ cast(short)91, 1600], [ cast(short)100, 1664], [ cast(short)101, 1728], [ cast(short)108, 512],
        [ cast(short)109, 576], [ cast(short)114, 896], [ cast(short)115, 960], [ cast(short)116, 1024], [ cast(short)117, 1088], [ cast(short)118, 1152],
        [ cast(short)119, 1216]]
    ];

    static const short[][][] WHITE_CODE = [
        /* 4 bits */
        [[ cast(short)7, 2], [ cast(short)8, 3], [ cast(short)11, 4], [ cast(short)12, 5], [ cast(short)14, 6], [ cast(short)15, 7]],
        /* 5 bits */
        [[ cast(short)7, 10], [ cast(short)8, 11], [ cast(short)18, 128], [ cast(short)19, 8], [ cast(short)20, 9], [ cast(short)27, 64]],
        /* 6 bits */
        [[ cast(short)3, 13], [ cast(short)7, 1], [ cast(short)8, 12], [ cast(short)23, 192], [ cast(short)24, 1664], [ cast(short)42, 16], [ cast(short)43, 17], [ cast(short)52, 14],
        [ cast(short)53, 15]],
        /* 7 bits */
        [[ cast(short)3, 22], [ cast(short)4, 23], [ cast(short)8, 20], [ cast(short)12, 19], [ cast(short)19, 26], [ cast(short)23, 21], [ cast(short)24, 28], [ cast(short)36, 27],
        [ cast(short)39, 18], [ cast(short)40, 24], [ cast(short)43, 25], [ cast(short)55, 256]],
        /* 8 bits */
        [[ cast(short)2, 29], [ cast(short)3, 30], [ cast(short)4, 45], [ cast(short)5, 46], [ cast(short)10, 47], [ cast(short)11, 48], [ cast(short)18, 33], [ cast(short)19, 34],
        [ cast(short)20, 35], [ cast(short)21, 36], [ cast(short)22, 37], [ cast(short)23, 38], [ cast(short)26, 31], [ cast(short)27, 32], [ cast(short)36, 53], [ cast(short)37, 54],
        [ cast(short)40, 39], [ cast(short)41, 40], [ cast(short)42, 41], [ cast(short)43, 42], [ cast(short)44, 43], [ cast(short)45, 44], [ cast(short)50, 61], [ cast(short)51, 62],
        [ cast(short)52, 63], [ cast(short)53, 0], [ cast(short)54, 320], [ cast(short)55, 384], [ cast(short)74, 59], [ cast(short)75, 60], [ cast(short)82, 49], [ cast(short)83, 50],
        [ cast(short)84, 51], [ cast(short)85, 52], [ cast(short)88, 55], [ cast(short)89, 56], [ cast(short)90, 57], [ cast(short)91, 58], [ cast(short)100, 448],
        [ cast(short)101, 512], [ cast(short)103, 640], [ cast(short)104, 576]],
        /* 9 bits */
        [[ cast(short)152, 1472], [ cast(short)153, 1536], [ cast(short)154, 1600], [ cast(short)155, 1728], [ cast(short)204, 704], [ cast(short)205, 768],
        [ cast(short)210, 832], [ cast(short)211, 896], [ cast(short)212, 960], [ cast(short)213, 1024], [ cast(short)214, 1088], [ cast(short)215, 1152],
        [ cast(short)216, 1216], [ cast(short)217, 1280], [ cast(short)218, 1344], [ cast(short)219, 1408]],
        /* 10 bits */
        [],
        /* 11 bits */
        [[ cast(short)8, 1792], [ cast(short)12, 1856], [ cast(short)13, 1920]],
        /* 12 bits */
        [/* EOL */[ cast(short)1, -1], [ cast(short)18, 1984], [ cast(short)19, 2048], [ cast(short)20, 2112], [ cast(short)21, 2176], [ cast(short)22, 2240], [ cast(short)23, 2304],
        [ cast(short)28, 2368], [ cast(short)29, 2432], [ cast(short)30, 2496], [ cast(short)31, 2560]]
    ];

    static const int BLACK_MIN_BITS = 2;
    static const int WHITE_MIN_BITS = 4;

    bool isWhite;
    int whiteValue = 0;
    int blackValue = 1;
    byte[] src;
    byte[] dest;
    int byteOffsetSrc = 0;
    int bitOffsetSrc = 0;
    int byteOffsetDest = 0;
    int bitOffsetDest = 0;
    int code = 0;
    int nbrBits = 0;
    /* nbr of bytes per row */
    int rowSize;

public int decode(byte[] src, byte[] dest, int offsetDest, int rowSize, int nRows) {
    this.src = src;
    this.dest = dest;
    this.rowSize = rowSize;
    byteOffsetSrc = 0;
    bitOffsetSrc = 0;
    byteOffsetDest = offsetDest;
    bitOffsetDest = 0;
    int cnt = 0;
    while (cnt < nRows && decodeRow()) {
        cnt++;
        /* byte aligned */
        if (bitOffsetDest > 0) {
            byteOffsetDest++;
            bitOffsetDest = 0;
        }
    }
    return byteOffsetDest - offsetDest;
}

bool decodeRow() {
    isWhite = true;
    int n = 0;
    while (n < rowSize) {
        int runLength = decodeRunLength();
        if (runLength < 0) return false;
        n += runLength;
        setNextBits(isWhite ? whiteValue : blackValue, runLength);
        isWhite = !isWhite;
    }
    return true;
}

int decodeRunLength() {
    int runLength = 0;
    int partialRun = 0;
    TryConst!(short[][][]) huffmanCode = isWhite ? WHITE_CODE : BLACK_CODE;
    while (true) {
        bool found = false;
        nbrBits = isWhite ? WHITE_MIN_BITS : BLACK_MIN_BITS;
        code = getNextBits(nbrBits);
        for (int i = 0; i < huffmanCode.length; i++) {
            for (int j = 0; j < huffmanCode[i].length; j++) {
                if (huffmanCode[i][j][0] is code) {
                    found = true;
                    partialRun = huffmanCode[i][j][1];
                    if (partialRun is -1) {
                        /* Stop when reaching final EOL on last byte */
                        if (byteOffsetSrc is src.length - 1) return -1;
                        /* Group 3 starts each row with an EOL - ignore it */
                    } else {
                        runLength += partialRun;
                        if (partialRun < 64) return runLength;
                    }
                    break;
                }
            }
            if (found) break;
            code = code << 1 | getNextBit();
        }
        if (!found) SWT.error(SWT.ERROR_INVALID_IMAGE);
    }
}

int getNextBit() {
    int value = (src[byteOffsetSrc] >>> (7 - bitOffsetSrc)) & 0x1;
    bitOffsetSrc++;
    if (bitOffsetSrc > 7) {
        byteOffsetSrc++;
        bitOffsetSrc = 0;
    }
    return value;
}

int getNextBits(int cnt) {
    int value = 0;
    for (int i = 0; i < cnt; i++) {
        value = value << 1 | getNextBit();
    }
    return value;
}

void setNextBits(int value, int cnt) {
    int n = cnt;
    while (bitOffsetDest > 0 && bitOffsetDest <= 7 && n > 0) {
        dest[byteOffsetDest] = value is 1 ?
            cast(byte)(dest[byteOffsetDest] | (1 << (7 - bitOffsetDest))) :
            cast(byte)(dest[byteOffsetDest] & ~(1 << (7 - bitOffsetDest)));
        n--;
        bitOffsetDest++;
    }
    if (bitOffsetDest is 8) {
        byteOffsetDest++;
        bitOffsetDest = 0;
    }
    while (n >= 8) {
        dest[byteOffsetDest++] = cast(byte) (value is 1 ? 0xFF : 0);
        n -= 8;
    }
    while (n > 0) {
        dest[byteOffsetDest] = value is 1 ?
            cast(byte)(dest[byteOffsetDest] | (1 << (7 - bitOffsetDest))) :
            cast(byte)(dest[byteOffsetDest] & ~(1 << (7 - bitOffsetDest)));
        n--;
        bitOffsetDest++;
    }
}

}