//C- ------------------------------------------------------------------- //C- Java DjVu (r) (v. 0.8) //C- Copyright (c) 2004-2005 LizardTech, Inc. All Rights Reserved. //C- Java DjVu is protected by U.S. Pat. No.C- 6,058,214 and patents //C- pending. //C- //C- This software is subject to, and may be distributed under, the //C- GNU General Public License, Version 2. The license should have //C- accompanied the software or you may obtain a copy of the license //C- from the Free Software Foundation at http://www.fsf.org . //C- //C- The computer code originally released by LizardTech under this //C- license and unmodified by other parties is deemed "the LIZARDTECH //C- ORIGINAL CODE." Subject to any third party intellectual property //C- claims, LizardTech grants recipient a worldwide, royalty-free, //C- non-exclusive license to make, use, sell, or otherwise dispose of //C- the LIZARDTECH ORIGINAL CODE or of programs derived from the //C- LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU //C- General Public License. This grant only confers the right to //C- infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to //C- the extent such infringement is reasonably necessary to enable //C- recipient to make, have made, practice, sell, or otherwise dispose //C- of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to //C- any greater extent that may be necessary to utilize further //C- modifications or combinations. //C- //C- The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY //C- OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED //C- TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF //C- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. //C- //C- In addition, as a special exception, LizardTech Inc. gives permission //C- to link the code of this program with the proprietary Java //C- implementation provided by Sun (or other vendors as well), and //C- distribute linked combinations including the two. You must obey the //C- GNU General Public License in all respects for all of the code used //C- other than the proprietary Java implementation. If you modify this //C- file, you may extend this exception to your version of the file, but //C- you are not obligated to do so. If you do not wish to do so, delete //C- this exception statement from your version. //C- ------------------------------------------------------------------- //C- Developed by Bill C. Riemers, Foxtrot Technologies Inc. as work for //C- hire under US copyright laws. //C- ------------------------------------------------------------------- // package com.lizardtech.djvu; import java.io.IOException; import com.google.gwt.typedarrays.shared.TypedArrays; import com.google.gwt.typedarrays.shared.Uint8Array; /** * This class represents structured wavelette data. */ public class IWPixmap implements Pixmap { //~ Static fields/initializers --------------------------------------------- /** DOCUMENT ME! */ public static final int CRCBfull = 5; /** DOCUMENT ME! */ public static final int CRCBhalf = 3; /** DOCUMENT ME! */ public static final int CRCBMode = 1; /** DOCUMENT ME! */ public static final int CRCBnone = 2; /** DOCUMENT ME! */ public static final int CRCBnormal = 4; /** DOCUMENT ME! */ public static final float[][] rgb_to_ycc = { {0.304348F, 0.608696F, 0.086956F}, {0.463768F, -0.405797F, -0.057971F}, {-0.173913F, -0.347826F, 0.521739F} }; //~ Instance fields -------------------------------------------------------- /** DOCUMENT ME! */ protected IWCodec cbcodec = null; /** DOCUMENT ME! */ protected IWCodec crcodec = null; /** DOCUMENT ME! */ protected IWCodec ycodec = null; /** DOCUMENT ME! */ protected IWMap cbmap = null; /** DOCUMENT ME! */ protected IWMap crmap = null; /** DOCUMENT ME! */ protected IWMap ymap = null; /** DOCUMENT ME! */ protected int cbytes = 0; /** DOCUMENT ME! */ protected int crcb_delay = 10; /** DOCUMENT ME! */ protected boolean crcb_half = false; /** DOCUMENT ME! */ protected int cserial = 0; /** DOCUMENT ME! */ protected int cslice = 0; //~ Constructors ----------------------------------------------------------- /** * Creates a new IWPixmap object. */ public IWPixmap() {} //~ Methods ---------------------------------------------------------------- /** * Query if this is image data. * * @return true */ @Override public boolean isImageData() { return true; } /** * DOCUMENT ME! */ public void close_codec() { ycodec = crcodec = cbcodec = null; cslice = cbytes = cserial = 0; if(DjVuOptions.COLLECT_GARBAGE) { System.gc(); } } /** * Decode this chunk. * * @param bs DOCUMENT ME! * * @throws IOException DOCUMENT ME! */ @Override public void decode(final CachedInputStream bs) throws IOException { if(ycodec == null) { cslice = cserial = 0; ymap = null; } if(bs.read() != cserial) { throw new IOException( "(IWPixmap::decode) Chunk does not bear expected serial number"); } int nslices = cslice + bs.read(); if(cserial == 0) { int major = bs.read(); int minor = bs.read(); if((major & 0x7f) != 1) { throw new IOException( "(IWPixmap::decode) File has been compressed with an incompatible IWCodec"); } if(minor > 2) { throw new IOException( "(IWPixmap::decode) File has been compressed with a more recent IWCodec"); } int w = (bs.read() << 8); w |= bs.read(); int h = (bs.read() << 8); h |= bs.read(); crcb_delay = 0; crcb_half = false; int b = bs.read(); if(minor >= 2) { crcb_delay = 0x7f & b; } if(minor >= 2) { crcb_half = ((0x80 & b) == 0); } if((major & 0x80) != 0) { crcb_delay = -1; } ymap = new IWMap().init(w, h); ycodec = new IWCodec().init(ymap); if(crcb_delay >= 0) { cbmap = new IWMap().init(w, h); crmap = new IWMap().init(w, h); cbcodec = new IWCodec().init(cbmap); crcodec = new IWCodec().init(crmap); } } ZPCodec zp = new ZPCodec().init(bs); for(int flag = 1; (flag != 0) && (cslice < nslices); cslice++) { flag = ycodec.code_slice(zp); if((crcodec != null) && (cbcodec != null) && (crcb_delay <= cslice)) { flag |= cbcodec.code_slice(zp); flag |= crcodec.code_slice(zp); } } cserial++; // return nslices; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ @Override public int getHeight() { return (ymap != null) ? ymap.ih : 0; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public GPixmap getPixmap() { if(ymap == null) { return null; } final int w = ymap.iw; final int h = ymap.ih; final int pixsep = 4; final int rowsep = w * pixsep; Uint8Array bytes = TypedArrays.createUint8Array(h * rowsep); ymap.image(0, bytes, rowsep, pixsep, false); if((crmap != null) && (cbmap != null) && (crcb_delay >= 0)) { cbmap.image(1, bytes, rowsep, pixsep, crcb_half); crmap.image(2, bytes, rowsep, pixsep, crcb_half); } // Convert image to RGB final GPixmap ppm = new GPixmap().init(bytes, h, w); final GPixelReference pixel = ppm.createGPixelReference(0); for(int i = 0; i < h;) { pixel.setOffset(i++, 0); if((crmap != null) && (cbmap != null) && (crcb_delay >= 0)) { pixel.YCC_to_RGB(w); } else { for(int x = w; x-- > 0; pixel.incOffset()) { pixel.setGray(127 - pixel.getBlue()); } } } return ppm; } @Override public GPixmap getPixmap( int subsample, GRect rect, GPixmap retval) { if(ymap == null) { return null; } if(retval == null) { retval = new GPixmap(); } final int w = rect.width(); final int h = rect.height(); final int pixsep = 4; final int rowsep = w * pixsep; final Uint8Array bytes = retval.init(h, w, null).data; ymap.image(subsample, rect, 0, bytes, rowsep, pixsep, false); if((crmap != null) && (cbmap != null) && (crcb_delay >= 0)) { cbmap.image(subsample, rect, 1, bytes, rowsep, pixsep, crcb_half); crmap.image(subsample, rect, 2, bytes, rowsep, pixsep, crcb_half); } final GPixelReference pixel = retval.createGPixelReference(0); for(int i = 0; i < h;) { pixel.setOffset(i++, 0); if((crmap != null) && (cbmap != null) && (crcb_delay >= 0)) { pixel.YCC_to_RGB(w); } else { for(int x = w; x-- > 0; pixel.incOffset()) { pixel.setGray(127 - bytes.get(pixel.getOffset())); } } } return retval; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ @Override public int getWidth() { return (ymap != null)?ymap.iw:0; } /** * Set the CRCB Delay * * @param value the new CRCB delay value. * * @return the CRCB delay value */ public int setCrcbDelay(int value) { if(value >= 0) { crcb_delay = value; } return crcb_delay; } @Override public int getMemoryUsage() { int usage = ymap.nb * 2500; if (cbmap != null) usage *= 3; return usage; } }