|
36 | 36 | import java.util.ArrayList; |
37 | 37 | import java.util.Calendar; |
38 | 38 | import java.util.HashMap; |
| 39 | +import java.util.Iterator; |
39 | 40 | import java.util.List; |
40 | 41 | import java.util.Locale; |
41 | 42 | import java.util.Map; |
| 43 | +import java.util.Map.Entry; |
42 | 44 | import java.util.Set; |
43 | 45 | import javax.imageio.ImageIO; |
44 | 46 | import org.apache.sanselan.ImageReadException; |
@@ -832,70 +834,80 @@ protected void _putheader() { |
832 | 834 | } |
833 | 835 |
|
834 | 836 | protected void _putimages() { |
835 | | - String filter = (this.compress) ? "/Filter /FlateDecode " : ""; |
836 | | - // while(list(file,info)=each(this.images)) |
837 | | - for (String file : this.images.keySet()) { |
838 | | - this._newobj(); |
839 | | - this.images.get(file).put("n", Integer.valueOf(this.n)); |
840 | | - this._out("<</Type /XObject"); |
841 | | - this._out("/Subtype /Image"); |
842 | | - this._out("/Width " |
843 | | - + this.images.get(file).get("w")); |
844 | | - this._out("/Height " |
845 | | - + this.images.get(file).get("h")); |
846 | | - |
847 | | - if (this.images.get(file).containsKey("alphaMask")) { |
848 | | - this._out("/SMask " + (Integer)this.images.get("alphaMask-" + file).get("n") + " 0 R"); |
849 | | - } |
850 | | - |
851 | | - if (this.images.get(file).get("cs") == "Indexed") { |
852 | | - this._out("/ColorSpace [/Indexed /DeviceRGB " |
853 | | - + (((byte[]) this.images.get(file).get("pal")).length / 3 - 1) + " " + (this.n + 1) + " 0 R]"); |
854 | | - } else { |
855 | | - this._out("/ColorSpace /" + this.images.get(file).get("cs")); |
856 | | - if (this.images.get(file).get("cs") == "DeviceCMYK") { |
857 | | - this._out("/Decode [1 0 1 0 1 0 1 0]"); |
858 | | - } |
859 | | - } |
860 | | - this._out("/BitsPerComponent " + this.images.get(file).get("bpc")); |
861 | | - if (this.images.get(file).get("f") != null) { |
862 | | - this._out("/Filter /" + this.images.get(file).get("f")); |
863 | | - } |
864 | | - if (this.images.get(file).get("parms") != null) { |
865 | | - this._out((String) this.images.get(file).get("parms")); |
866 | | - } |
867 | | - if (this.images.get(file).get("trns") != null) { |
868 | | - byte[] trnsarr = ((byte[]) this.images.get(file).get("trns")); |
869 | | - StringBuilder trns = new StringBuilder(); |
870 | | - trns.append("/Mask [ "); |
871 | | - for (int i = 0; i < trnsarr.length; i++) { |
872 | | - trns.append(_stringify(trnsarr)); |
873 | | - } |
874 | | - trns.append(']'); |
875 | | - this._out(trns.toString()); |
876 | | - } |
877 | | - this._out("/Length " + ((byte[]) (this.images.get(file).get("data"))).length + ">>"); |
878 | | - try { |
879 | | - this._putstream(new String((byte[]) this.images.get(file).get("data"), "ISO-8859-1")); |
880 | | - } catch (UnsupportedEncodingException e) { |
881 | | - this._putstream(new String((byte[]) this.images.get(file).get("data"))); |
882 | | - } |
883 | | - this.images.get(file).put("data", null); |
884 | | - this._out("endobj"); |
885 | | - // Palette |
886 | | - if (this.images.get(file).get("cs") == "Indexed") { |
887 | | - this._newobj(); |
888 | | - byte[] pal = (byte[]) this.images.get(file).get("pal"); |
889 | | - pal = (this.compress) ? gzcompress(pal) : pal; |
890 | | - this._out("<<" + filter + "/Length " + pal.length + ">>"); |
891 | | - try { |
892 | | - this._putstream(new String(pal, "ISO-8859-1")); |
893 | | - } catch (UnsupportedEncodingException e) { |
894 | | - this._putstream(new String(pal)); |
895 | | - } |
896 | | - this._out("endobj"); |
897 | | - } |
898 | | - } |
| 837 | + String filter = (this.compress) ? "/Filter /FlateDecode " : ""; |
| 838 | + // Yikes, this.images: Map<String, Map<String, Object>> |
| 839 | + Iterator<Entry<String, Map<String, Object>>> it = this.images.entrySet().iterator(); |
| 840 | + while (it.hasNext()) { |
| 841 | + Map.Entry<String, Map<String, Object>> imageEntry = it.next(); |
| 842 | + Map<String, Object> image = imageEntry.getValue(); |
| 843 | + // Have to call _newobj() before other stuff. this.n gets incremented in here |
| 844 | + this._newobj(); |
| 845 | + // Don't miss this, we set the image order in here. If this doesn't get set |
| 846 | + // weird stuff will happen later on such as corrupted PDFs. Also note that it |
| 847 | + // needs updated in the underlying Map or it will be missing later on _putresources happens |
| 848 | + image.put("n", this.n); |
| 849 | + this._out("<</Type /XObject"); |
| 850 | + this._out("/Subtype /Image"); |
| 851 | + this._out("/Width " + image.get("w")); |
| 852 | + this._out("/Height " + image.get("h")); |
| 853 | + // |
| 854 | + if (images.containsKey("alphaMask")) { |
| 855 | + this._out("/SMask " + image.get("n") + " 0 R"); |
| 856 | + } |
| 857 | + // |
| 858 | + if (image.get("cs") == "Indexed") { |
| 859 | + // This used to be (this.n + 1) instead of just image.get("n"). Not really sure if this will cause problems |
| 860 | + // but the old way didn't make much sense to me. Cross that bridge when we get there I suppose. |
| 861 | + this._out("/ColorSpace [/Indexed /DeviceRGB " + (((byte[]) image.get("pal")).length / 3 - 1) + " " + image.get("n") + " 0 R]"); |
| 862 | + } else { |
| 863 | + this._out("/ColorSpace /" + image.get("cs")); |
| 864 | + if (image.get("cs") == "DeviceCMYK") { |
| 865 | + this._out("/Decode [1 0 1 0 1 0 1 0]"); |
| 866 | + } |
| 867 | + } |
| 868 | + // |
| 869 | + this._out("/BitsPerComponent " + image.get("bpc")); |
| 870 | + if (image.get("f") != null) { |
| 871 | + this._out("/Filter /" + image.get("f")); |
| 872 | + } |
| 873 | + if (image.get("parms") != null) { |
| 874 | + this._out((String) image.get("parms")); |
| 875 | + } |
| 876 | + if (image.get("trns") != null) { |
| 877 | + byte[] trnsarr = ((byte[]) image.get("trns")); |
| 878 | + StringBuilder trns = new StringBuilder(); |
| 879 | + trns.append("/Mask [ "); |
| 880 | + for (int i = 0; i < trnsarr.length; i++) { |
| 881 | + trns.append(_stringify(trnsarr)); |
| 882 | + } |
| 883 | + trns.append(']'); |
| 884 | + this._out(trns.toString()); |
| 885 | + } |
| 886 | + this._out("/Length " + ((byte[]) (image.get("data"))).length + ">>"); |
| 887 | + try { |
| 888 | + this._putstream(new String((byte[]) image.get("data"), "ISO-8859-1")); |
| 889 | + } catch (UnsupportedEncodingException e) { |
| 890 | + this._putstream(new String((byte[]) image.get("data"))); |
| 891 | + } |
| 892 | + image.put("data", null); |
| 893 | + this._out("endobj"); |
| 894 | + // Palette |
| 895 | + if (image.get("cs") == "Indexed") { |
| 896 | + this._newobj(); |
| 897 | + byte[] pal = (byte[]) image.get("pal"); |
| 898 | + pal = (this.compress) ? gzcompress(pal) : pal; |
| 899 | + this._out("<<" + filter + "/Length " + pal.length + ">>"); |
| 900 | + try { |
| 901 | + this._putstream(new String(pal, "ISO-8859-1")); |
| 902 | + } catch (UnsupportedEncodingException e) { |
| 903 | + this._putstream(new String(pal)); |
| 904 | + } |
| 905 | + this._out("endobj"); |
| 906 | + } |
| 907 | + // Set object back into underlying data structure so any changes are |
| 908 | + // available elsewhere in future processing logic |
| 909 | + imageEntry.setValue(image); |
| 910 | + } |
899 | 911 | } |
900 | 912 |
|
901 | 913 | private byte[] gzcompress(byte[] pal) { |
@@ -1139,16 +1151,16 @@ protected void _puttrailer() { |
1139 | 1151 | } |
1140 | 1152 |
|
1141 | 1153 | protected void _putxobjectdict() { |
1142 | | - StringBuilder s = new StringBuilder(); |
1143 | | - for (Map<String, Object> image : this.images.values()) { |
1144 | | - s.append("/I"); |
1145 | | - s.append(image.get("i")); |
1146 | | - s.append(' '); |
1147 | | - s.append(image.get("n")); |
1148 | | - s.append(" 0 R"); |
1149 | | - this._out(s.toString()); |
1150 | | - s.delete(0, s.length()); |
1151 | | - } |
| 1154 | + StringBuilder s = new StringBuilder(); |
| 1155 | + for (Map<String, Object> image : this.images.values()) { |
| 1156 | + s.append("/I"); |
| 1157 | + s.append(image.get("i")); |
| 1158 | + s.append(' '); |
| 1159 | + s.append(image.get("n")); |
| 1160 | + s.append(" 0 R"); |
| 1161 | + this._out(s.toString()); |
| 1162 | + s.delete(0, s.length()); |
| 1163 | + } |
1152 | 1164 | } |
1153 | 1165 |
|
1154 | 1166 | protected String _textstring(final String s) { |
|
0 commit comments