KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > util > IECompatibleJpegInputStream


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.util;
11
12 import java.io.*;
13 /**
14  * IECompatibleJpegInputStream removes additional information left by PhotoShop 7 in jpegs
15  * , this information may crash Internet Exploder. that's why you need to remove it.
16  *
17  * With PS 7, Adobe decided by default to embed XML-encoded "preview" data into JPEG files,
18  * using a feature of the JPEG format that permits embedding of arbitrarily-named "profiles".
19  * In theory, these files are valid according to the JPEG specifications.
20  * However they break many applications, including Quark and, significantly,
21  * various versions of Internet Explorer on various platforms.
22  *
23  * @since MMBase 1.7
24  * @author Kees Jongenburger <keesj@dds.nl>
25  * @version $Id: IECompatibleJpegInputStream.java,v 1.8 2006/06/27 14:36:38 johannes Exp $
26  */

27 public class IECompatibleJpegInputStream extends FilterInputStream implements Runnable JavaDoc {
28
29     private PipedInputStream pis;
30     private PipedOutputStream pos;
31
32     /**
33      * create a new InputStream that parse the content of a jpeg file and removes application headers
34      * if the content is not a jpeg the content remains unaffected
35      */

36     public IECompatibleJpegInputStream(InputStream in) {
37         super(in);
38         pis = new PipedInputStream();
39         pos = new PipedOutputStream();
40         try {
41             pis.connect(pos);
42         } catch (IOException ioe) {
43         }
44         ThreadPools.filterExecutor.execute(this);
45     }
46
47     public void run() {
48         try {
49             //read the first 2 byte so see if it is a jpeg file
50
int magic1 = in.read();
51             int magic2 = in.read();
52             pos.write(magic1);
53             pos.write(magic2);
54
55             if (magic1 == 0xff && magic2 == 0xd8) {
56                 int b;
57                 //start reading
58
while ((b = in.read()) != -1) {
59                     if (b == 0xff) {
60                         int marker = in.read();
61
62                         if (marker == 0x00 || marker == 0xd8 || marker == 0xd9) { //some markers have no "size" like the escaping .. start and end of jpeg
63
pos.write(b);
64                             pos.write(marker);
65                         } else if (marker >= 0xe0 && marker <= 0xef) { //application markers not really required
66
//} else if (marker == 0xed) { //this marker is an application marker used by photoshop. it looks like this is the marker
67
//where photoshop stores the xml stuff that we never wanted so if you only want to remove the xml part of the file this is enough
68
int msb = in.read();
69                             int lsb = in.read();
70
71                             int size = msb * 256 + lsb;
72                             in.skip(size - 2);
73                         } else {
74                             int msb = in.read();
75
76                             int lsb = in.read();
77
78                             int size = msb * 256 + lsb;
79                             size -= 2;
80                             pos.write(b);
81                             pos.write(marker);
82                             pos.write(msb);
83                             pos.write(lsb);
84                             while (size > 0) {
85                                 pos.write(in.read());
86                                 size--;
87                             }
88                         }
89                     } else {
90                         pos.write(b);
91                     }
92                 }
93             } else {
94                 int c = 0;
95                 byte[] buf = new byte[1024];
96                 while ((c = in.read(buf)) != -1) {
97                     pos.write(buf, 0, c);
98                 }
99             }
100             in.close();
101             pos.flush();
102             pos.close();
103         } catch (Exception JavaDoc e) {};
104     }
105
106     public int available() throws IOException {
107         return pis.available();
108     }
109
110     public void close() throws IOException {
111         pis.close();
112         super.close();
113     }
114
115     public int read() throws IOException {
116         return pis.read();
117     }
118
119     public int read(byte[] b, int off, int len) throws IOException {
120         return pis.read(b, off, len);
121     }
122
123     public int read(byte[] b) throws IOException {
124         return pis.read(b);
125     }
126
127     public long skip(long n) throws IOException {
128         return pis.skip(n);
129     }
130
131     /**
132      * Util method that uses the IECompatibleInputStream to convert a byte array
133      * if the content is not a jpeg the content is not affected
134      * @param in the byte array
135      * @return the converted (ie compatible) jpeg
136      */

137     public static byte[] process(byte[] in) {
138         try {
139             InputStream inputStream = new IECompatibleJpegInputStream(new ByteArrayInputStream(in));
140             ByteArrayOutputStream out = new ByteArrayOutputStream();
141             int c = 0;
142             byte[] buf = new byte[1024];
143             while ((c = inputStream.read(buf)) != -1) {
144                 out.write(buf, 0, c);
145             }
146             out.flush();
147             return out.toByteArray();
148         } catch (IOException e) {}
149         return in;
150     }
151
152     //command line method
153
public static void main(String JavaDoc[] argv) throws IOException {
154         if (argv.length == 0) {
155             System.err.println(IECompatibleJpegInputStream.class.getName() + " removes headers from jpeg files");
156             System.err.println("it requires 2 parameters , the input jpeg and the output jpeg");
157             System.exit(1);
158         } else if (argv.length == 2) {
159             File file = new File(argv[0]);
160             if (!file.exists()) {
161                 System.err.println("can't convert non existing file" + file.getPath());
162             }
163             File out = new File(argv[1]);
164             InputStream in = new IECompatibleJpegInputStream(new FileInputStream(file));
165             OutputStream fos = new BufferedOutputStream(new FileOutputStream(out));
166             int c = 0;
167             while ((c = in.read()) != -1) {
168                 fos.write(c);
169             }
170             in.close();
171             fos.flush();
172             fos.close();
173         }
174     }
175 }
176
Popular Tags