Jeremias, you got me very close. That part of the work is now committed. Thanks for the help!
Daniel On Wed, Apr 29, 2009 at 7:46 AM, Daniel Wilson < [email protected]> wrote: > Thanks, Jeremias! > > That makes sense. I'll try implementing it & may have a couple more > questions. > > Daniel Wilson > > > On Wed, Apr 29, 2009 at 3:01 AM, Jeremias Maerki > <[email protected]>wrote: > >> As noted in another thread, bitmaps with 1bpp (or generally speaking: >> bitmaps with less than 8 bits per pixels) should be represented in >> memory using the IndexColorModel, i.e. a color lookup table. That way >> the pixels don't have to be extended to their full color values. The >> problem with the CMYK color space is that java.awt.image.IndexColorModel >> only supports sRGB. So you may end up with implementing a new ColorModel >> subclass which can represent non-sRGB colors. Of course, you could also >> map the CMYK colors to sRGB and still use IndexColorModel but if someone >> came an wanted a CMYK TIFF representation of a PDF, you'd have two color >> conversions involved which could have all sorts of side-effects. But >> that is certainly advanced stuff that could probably be handled at some >> later point. >> >> Here's an example of an IndexColorModel for an RGB-based 1bpp image: >> byte[] map = new byte[] {(byte)0x00, (byte)0xff}; >> ColorModel cm = new IndexColorModel(1, 2, map, map, map); >> >> That's just the color model with the lookup table. The other key element >> is the DataBuffer instance (on which the Raster instance will operate) >> with >> the correct SampleModel. For 1bpp, this should in the end be a >> java.awt.image.MultiPixelPackedSampleModel, for example: >> >> MultiPixelPackedSampleModel packedSampleModel = new >> MultiPixelPackedSampleModel( >> DataBuffer.TYPE_BYTE, img.getWidth(), img.getHeight(), 1); >> >> AFAICT, the approach with creating a ColorModel instance in the >> PDColorSpace subclass is probably wrong if you want to get an optimized >> in-memory representation, since the color model just interprets the >> colors. It doesn't know how the pixels are represented (SampleModel). >> Only the XObject itself knows how many bits represent a pixel. >> >> HTH >> >> On 29.04.2009 03:16:37 Daniel Wilson wrote: >> > Given a bpc = 1 and a DeviceCMYK color space: >> > >> > byte[] array = getPDStream().getByteArray(); >> > >> > creates an array with width*height / 8 bytes. >> > >> > PDColorSpace colorspace = getColorSpace(); >> > ColorModel cm = colorspace.createColorModel( bpc ); >> > WritableRaster raster = cm.createCompatibleWritableRaster( width, height >> ); >> > DataBufferByte buffer = (DataBufferByte)raster.getDataBuffer(); >> > byte[] bufferData = buffer.getData(); >> > >> > cm is a ColorModel reporting 32 pixelBits. >> > bufferData now has width*height * 4 bytes -- or 32 times as many as >> array. >> > >> > >> > System.arraycopy( array, 0,bufferData, 0, >> > (array.length<bufferData.length?array.length: bufferData.length) ); >> > The ternary in there saves us from a buffer overflow ... but that's >> still >> > the wrong answer. >> > Just copying a 1-bit/pixel buffer into a 32-bit/pixel buffer cannot be >> the >> > right answer. >> > >> > Am I to read each BIT of the source array and convert it to a 32-bit >> integer >> > to write? So 0 becomes 0x00000000 and 1 becomes 0xFFFFFFFF ? >> > >> > Or is colorspace.CreateColorModel creating the wrong one? This looks >> right >> > ... >> > >> > logger().info("testing Sector9's implementation"); >> > >> > int[] nbBits = { bpc, bpc, bpc, bpc }; >> > ComponentColorModel componentColorModel = >> > new ComponentColorModel( createColorSpace(), >> > nbBits, >> > false, >> > false, >> > Transparency.OPAQUE, >> > DataBuffer.TYPE_BYTE ); >> > >> > Thanks for your ideas! >> > >> > Daniel Wilson >> >> >> >> >> Jeremias Maerki >> >> >
