001: /*
002: Copyright © 2006,2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
003:
004: Contributors:
005: * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it):
006: contributed code is Copyright © 2006,2007 by Stefano Chizzolini.
007:
008: This file should be part of the source code distribution of "PDF Clown library"
009: (the Program): see the accompanying README files for more info.
010:
011: This Program is free software; you can redistribute it and/or modify it under
012: the terms of the GNU General Public License as published by the Free Software
013: Foundation; either version 2 of the License, or (at your option) any later version.
014:
015: This Program is distributed in the hope that it will be useful, but WITHOUT ANY
016: WARRANTY, either expressed or implied; without even the implied warranty of
017: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
018:
019: You should have received a copy of the GNU General Public License along with this
020: Program (see README files); if not, go to the GNU website (http://www.gnu.org/).
021:
022: Redistribution and use, with or without modification, are permitted provided that such
023: redistributions retain the above copyright notice, license and disclaimer, along with
024: this list of conditions.
025: */
026:
027: package it.stefanochizzolini.clown.documents.contents.entities;
028:
029: import it.stefanochizzolini.clown.bytes.Buffer;
030: import it.stefanochizzolini.clown.bytes.IBuffer;
031: import it.stefanochizzolini.clown.bytes.IInputStream;
032: import it.stefanochizzolini.clown.documents.contents.IContentContext;
033: import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
034: import it.stefanochizzolini.clown.documents.contents.objects.InlineImage;
035: import it.stefanochizzolini.clown.documents.contents.objects.InlineImageBody;
036: import it.stefanochizzolini.clown.documents.contents.objects.InlineImageHeader;
037: import it.stefanochizzolini.clown.documents.contents.xObjects.ImageXObject;
038: import it.stefanochizzolini.clown.documents.contents.xObjects.XObject;
039: import it.stefanochizzolini.clown.documents.Document;
040: import it.stefanochizzolini.clown.objects.PdfDictionary;
041: import it.stefanochizzolini.clown.objects.PdfDirectObject;
042: import it.stefanochizzolini.clown.objects.PdfInteger;
043: import it.stefanochizzolini.clown.objects.PdfName;
044: import it.stefanochizzolini.clown.objects.PdfReference;
045: import it.stefanochizzolini.clown.objects.PdfStream;
046:
047: import java.io.EOFException;
048: import java.nio.ByteOrder;
049: import java.util.Arrays;
050: import java.util.List;
051:
052: /**
053: JPEG image object [ISO 10918-1;JFIF:1.02].
054: @version 0.0.5
055: */
056: public class JpegImage extends Image {
057: // <class>
058: // <dynamic>
059: // <constructors>
060: JpegImage(IInputStream stream) {
061: super (stream);
062:
063: load();
064: }
065:
066: // </constructors>
067:
068: // <interface>
069: // <public>
070: @Override
071: public XObject toXObject(Document context) {
072: return new ImageXObject(context,
073: new PdfStream(new PdfDictionary(new PdfName[] {
074: PdfName.Width, PdfName.Height,
075: PdfName.BitsPerComponent, PdfName.ColorSpace,
076: PdfName.Filter }, new PdfDirectObject[] {
077: new PdfInteger(getWidth()),
078: new PdfInteger(getHeight()),
079: new PdfInteger(getBitsPerComponent()),
080: PdfName.DeviceRGB, PdfName.DCTDecode }),
081: new Buffer(getStream().toByteArray())));
082: }
083:
084: /**
085: @version 0.0.5
086: @since 0.0.5
087: */
088: @Override
089: public ContentObject toInlineObject(IContentContext context) {
090: return new InlineImage(
091: new InlineImageHeader(
092: (List<PdfDirectObject>) (List<? extends PdfDirectObject>) Arrays
093: .asList(PdfName.W, new PdfInteger(
094: getWidth()), PdfName.H,
095: new PdfInteger(getHeight()),
096: PdfName.CS, PdfName.RGB,
097: PdfName.BPC, new PdfInteger(
098: getBitsPerComponent()),
099: PdfName.F, PdfName.DCT)),
100: new InlineImageBody(new Buffer(getStream()
101: .toByteArray())));
102: }
103:
104: // </public>
105:
106: // <private>
107: private void load() {
108: /*
109: NOTE: Big-endian data expected.
110: */
111: IInputStream stream = getStream();
112: // Ensure that data is read using the proper endianness!
113: stream.setByteOrder(ByteOrder.BIG_ENDIAN);
114: try {
115: int index = 4;
116: stream.seek(index);
117: byte[] markerBytes = new byte[2];
118: while (true) {
119: index += stream.readUnsignedShort();
120: stream.seek(index);
121:
122: stream.read(markerBytes);
123: index += 2;
124:
125: // Frame header?
126: if (markerBytes[0] == (byte) 0xFF
127: && markerBytes[1] == (byte) 0xC0) {
128: stream.skip(2);
129: // Get the image bits per color component (sample precision)!
130: setBitsPerComponent(stream.readUnsignedByte());
131: // Get the image size!
132: setHeight(stream.readUnsignedShort());
133: setWidth(stream.readUnsignedShort());
134:
135: break;
136: }
137: }
138: } catch (Exception e) {
139: throw new RuntimeException(e);
140: }
141: }
142: // </private>
143: // </interface>
144: // </dynamic>
145: // </class>
146: }
|