1 51 package org.apache.fop.image; 52 53 import java.net.URL ; 55 import java.io.ByteArrayOutputStream ; 56 import java.io.InputStream ; 57 58 import org.apache.fop.datatypes.ColorSpace; 60 import org.apache.fop.pdf.DCTFilter; 61 import org.apache.fop.image.analyser.ImageReader; 62 63 69 public class JpegImage extends AbstractFopImage { 70 boolean hasAPPEMarker = false; 71 boolean found_icc_profile = false; 72 boolean found_dimensions = false; 73 74 public JpegImage(URL href) throws FopImageException { 75 super(href); 76 } 77 78 public JpegImage(URL href, 79 ImageReader imgReader) throws FopImageException { 80 super(href, imgReader); 81 } 82 83 protected void loadImage() throws FopImageException { 84 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 85 ByteArrayOutputStream iccStream = new ByteArrayOutputStream (); 86 InputStream inStream; 87 this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_UNKNOWN); 88 byte[] readBuf = new byte[4096]; 89 int bytes_read; 90 int index = 0; 91 boolean cont = true; 92 93 this.m_compressionType = new DCTFilter(); 94 this.m_compressionType.setApplied(true); 95 96 try { 97 inStream = this.m_href.openStream(); 98 99 while ((bytes_read = inStream.read(readBuf)) != -1) { 100 baos.write(readBuf, 0, bytes_read); 101 } 102 } catch (java.io.IOException ex) { 103 throw new FopImageException("Error while loading image " + 104 this.m_href.toString() + " : " + ex.getClass() + 105 " - " + ex.getMessage()); 106 } 107 108 this.m_bitmaps = baos.toByteArray(); 109 this.m_bitsPerPixel = 8; 110 this.m_isTransparent = false; 111 112 if (this.m_bitmaps.length > (index + 2) && 113 uByte(this.m_bitmaps[index]) == 255 && 114 uByte(this.m_bitmaps[index + 1]) == 216) { 115 index += 2; 116 117 while (index < this.m_bitmaps.length && cont) { 118 if (this.m_bitmaps.length > (index + 2) && 120 uByte(this.m_bitmaps[index]) == 255) { 121 122 if (uByte(this.m_bitmaps[index + 1]) == 192 || 124 uByte(this.m_bitmaps[index + 1]) == 194) { 125 126 this.m_height = calcBytes(this.m_bitmaps[index + 5], 127 this.m_bitmaps[index + 6]); 128 this.m_width = calcBytes(this.m_bitmaps[index + 7], 129 this.m_bitmaps[index + 8]); 130 131 if (this.m_bitmaps[index + 9] == 1) { 132 this.m_colorSpace.setColorSpace(ColorSpace.DEVICE_GRAY); 133 } else if (this.m_bitmaps[index + 9] == 3) { 134 this.m_colorSpace.setColorSpace(ColorSpace.DEVICE_RGB); 135 } else if (this.m_bitmaps[index + 9] == 4) { 136 this.m_colorSpace.setColorSpace(ColorSpace.DEVICE_CMYK); 137 } 138 139 found_dimensions = true; 140 if (found_icc_profile) { 141 cont = false; 142 break; 143 } 144 index += calcBytes(this.m_bitmaps[index + 2], 145 this.m_bitmaps[index + 3]) + 2; 146 147 } else if (uByte(this.m_bitmaps[index+1]) == 226 && 148 this.m_bitmaps.length > (index+60)) { 149 byte[] icc_string = new byte[11]; 151 System.arraycopy(this.m_bitmaps, index+4, icc_string, 0, 11); 152 153 162 if ("ICC_PROFILE".equals(new String (icc_string))){ 163 int chunkSize = calcBytes(this.m_bitmaps[index + 2], 164 this.m_bitmaps[index + 3]) + 2; 165 166 iccStream.write(this.m_bitmaps, index+16, chunkSize - 18); } 168 169 index += calcBytes(this.m_bitmaps[index + 2], 170 this.m_bitmaps[index + 3]) + 2; 171 } else if ((uByte(this.m_bitmaps[index]) == 0xff && 173 uByte(this.m_bitmaps[index+1]) == 0xee && 174 uByte(this.m_bitmaps[index+2]) == 0 && 175 uByte(this.m_bitmaps[index+3]) == 14 && 176 "Adobe".equals(new String (this.m_bitmaps, index+4, 5)))) { 177 hasAPPEMarker = true; 183 184 index += calcBytes(this.m_bitmaps[index + 2], 185 this.m_bitmaps[index + 3]) + 2; 186 } else { 187 index += calcBytes(this.m_bitmaps[index + 2], 188 this.m_bitmaps[index + 3]) + 2; 189 } 190 191 192 } else { 193 cont = false; 194 199 } 200 } 201 } else { 202 throw new FopImageException( "\n1 Error while loading image " + 203 this.m_href.toString() + " : JpegImage - Invalid JPEG Header."); 204 } 205 if (iccStream.size() > 0) { 206 byte[] align = new byte[((iccStream.size()) % 8) + 8]; 207 try {iccStream.write(align);} catch (Exception e) { 208 throw new FopImageException( "\n1 Error while loading image " + 209 this.m_href.toString() + " : " + e.getMessage()); 210 } 211 this.m_colorSpace.setICCProfile(iccStream.toByteArray()); 212 } 213 214 if (hasAPPEMarker && this.m_colorSpace.getColorSpace() == ColorSpace.DEVICE_CMYK) 215 this.m_invertImage = true; 216 } 217 218 private int calcBytes(byte bOne, byte bTwo) { 219 return (uByte(bOne) * 256) + uByte(bTwo); 220 } 221 222 private int uByte(byte bIn) { 223 if (bIn < 0) { 224 return 256 + bIn; 225 } else { 226 return bIn; 227 } 228 } 229 } 230 231 232 | Popular Tags |