19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright 2007, The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.awt;
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Bitmap;
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.BitmapFactory;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.Transparency;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.color.ColorSpace;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//import java.awt.image.BufferedImage;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.image.ColorModel;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.image.ComponentColorModel;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.image.DataBuffer;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.image.DirectColorModel;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.image.ImageConsumer;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.image.IndexColorModel;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Hashtable;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.awt.gl.image.DecodingImageSource;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.awt.gl.image.ImageDecoder;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.awt.internal.nls.Messages;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class AndroidImageDecoder extends ImageDecoder {
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int hintflags =
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ImageConsumer.SINGLEFRAME | // PNG is a static image
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ImageConsumer.TOPDOWNLEFTRIGHT | // This order is only one possible
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ImageConsumer.COMPLETESCANLINES; // Don't deliver incomplete scanlines
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Each pixel is a grayscale sample.
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int PNG_COLOR_TYPE_GRAY = 0;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Each pixel is an R,G,B triple.
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int PNG_COLOR_TYPE_RGB = 2;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Each pixel is a palette index, a PLTE chunk must appear.
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int PNG_COLOR_TYPE_PLTE = 3;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Each pixel is a grayscale sample, followed by an alpha sample.
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int PNG_COLOR_TYPE_GRAY_ALPHA = 4;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Each pixel is an R,G,B triple, followed by an alpha sample.
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int PNG_COLOR_TYPE_RGBA = 6;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int NB_OF_LINES_PER_CHUNK = 1;  // 0 = full image
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Bitmap bm;  // The image as decoded by Android
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Header information
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int imageWidth; // Image size
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int imageHeight;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int colorType;  // One of the PNG_ constants from above
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int bitDepth;   // Number of bits per color
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    byte cmap[];    // The color palette for index color models
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ColorModel model;  // The corresponding AWT color model
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean transferInts; // Is transfer of type int or byte?
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int dataElementsPerPixel;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Buffers for decoded image data
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    byte byteOut[];
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int intOut[];
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AndroidImageDecoder(DecodingImageSource src, InputStream is) {
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(src, is);
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dataElementsPerPixel = 1;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All the decoding is done in Android
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * AWT???: Method returns only once the image is completly
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * decoded; decoding is not done asynchronously
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void decodeImage() throws IOException {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bm = BitmapFactory.decodeStream(inputStream);
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (bm == null) {
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IOException("Input stream empty and no image cached");
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Check size
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            imageWidth = bm.getWidth();
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            imageHeight = bm.getHeight();
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (imageWidth < 0 || imageHeight < 0 ) {
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new RuntimeException("Illegal image size: "
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + imageWidth + ", " + imageHeight);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // We got the image fully decoded; now send all image data to AWT
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setDimensions(imageWidth, imageHeight);
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            model = createColorModel();
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setColorModel(model);
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setHints(hintflags);
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setProperties(new Hashtable<Object, Object>()); // Empty
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sendPixels(NB_OF_LINES_PER_CHUNK != 0 ? NB_OF_LINES_PER_CHUNK : imageHeight);
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            imageComplete(ImageConsumer.STATICIMAGEDONE);
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (IOException e) {
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw e;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RuntimeException e) {
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            imageComplete(ImageConsumer.IMAGEERROR);
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw e;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            closeStream();
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create the AWT color model
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ???AWT: Android Bitmaps are always of type: ARGB-8888-Direct color model
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * However, we leave the code here for a more powerfull decoder
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that returns a native model, and the conversion is then handled
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in AWT. With such a decoder, we would need to get the colorType,
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the bitDepth, (and the color palette for an index color model)
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * from the image and construct the correct color model here.
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ColorModel createColorModel() {
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ColorModel cm = null;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int bmModel = 5; // TODO This doesn't exist: bm.getColorModel();
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cmap = null;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (bmModel) {
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // A1_MODEL
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 1:
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            colorType = PNG_COLOR_TYPE_GRAY;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bitDepth = 1;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // A8_MODEL
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 2:
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            colorType = PNG_COLOR_TYPE_GRAY_ALPHA;
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bitDepth = 8;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // INDEX8_MODEL
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // RGB_565_MODEL
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // ARGB_8888_MODEL
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 3:
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 4:
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 5:
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            colorType = bm.hasAlpha() ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bitDepth = 8;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // awt.3C=Unknown PNG color type
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (colorType) {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PNG_COLOR_TYPE_GRAY: {
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 &&  bitDepth != 1) {
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // awt.3C=Unknown PNG color type
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Create gray color model
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int numEntries = 1 << bitDepth;
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int scaleFactor = 255 / (numEntries-1);
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                byte comps[] = new byte[numEntries];
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int i = 0; i < numEntries; i++) {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    comps[i] = (byte) (i * scaleFactor);
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm = new IndexColorModel(bitDepth, numEntries, comps, comps, comps);
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                transferInts = false;
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PNG_COLOR_TYPE_RGB: {
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (bitDepth != 8) {
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // awt.3C=Unknown PNG color type
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm = new DirectColorModel(24, 0xff0000, 0xFF00, 0xFF);
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                transferInts = true;
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PNG_COLOR_TYPE_PLTE: {
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // awt.3C=Unknown PNG color type
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (cmap == null) {
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new IllegalStateException("Palette color type is not supported");
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm = new IndexColorModel(bitDepth, cmap.length / 3, cmap, 0, false);
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                transferInts = false;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PNG_COLOR_TYPE_GRAY_ALPHA: {
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (bitDepth != 8) {
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // awt.3C=Unknown PNG color type
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        true, false,
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        Transparency.TRANSLUCENT,
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        DataBuffer.TYPE_BYTE);
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                transferInts = false;
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dataElementsPerPixel = 2;
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case PNG_COLOR_TYPE_RGBA: {
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (bitDepth != 8) {
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // awt.3C=Unknown PNG color type
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm = ColorModel.getRGBdefault();
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                transferInts = true;
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // awt.3C=Unknown PNG color type
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return cm;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void sendPixels(int nbOfLinesPerChunk) {
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int w = imageWidth;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int h = imageHeight;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int n = 1;
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (nbOfLinesPerChunk > 0 && nbOfLinesPerChunk <= h) {
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            n = nbOfLinesPerChunk;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (transferInts) {
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Create output buffer
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intOut = new int[w * n];
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int yi = 0; yi < h; yi += n) {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Last chunk might contain less liness
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (n > 1 && h - yi < n ) {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    n = h - yi;
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                bm.getPixels(intOut, 0, w, 0, yi, w, n);
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setPixels(0, yi, w, n, model, intOut, 0, w);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Android bitmaps always store ints (ARGB-8888 direct model)
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("Byte transfer not supported");
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
275