Skip to content

Commit aeb80e3

Browse files
committed
Merge pull request #5 from bstoots/fix-putimages-ordering
Fix sequence in _putimages() by writing values back to underlying map
2 parents aa8414c + 30a6105 commit aeb80e3

File tree

1 file changed

+86
-74
lines changed

1 file changed

+86
-74
lines changed

src/main/java/com/koadweb/javafpdf/FPDF.java

Lines changed: 86 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,11 @@
3636
import java.util.ArrayList;
3737
import java.util.Calendar;
3838
import java.util.HashMap;
39+
import java.util.Iterator;
3940
import java.util.List;
4041
import java.util.Locale;
4142
import java.util.Map;
43+
import java.util.Map.Entry;
4244
import java.util.Set;
4345
import javax.imageio.ImageIO;
4446
import org.apache.sanselan.ImageReadException;
@@ -832,70 +834,80 @@ protected void _putheader() {
832834
}
833835

834836
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+
}
899911
}
900912

901913
private byte[] gzcompress(byte[] pal) {
@@ -1139,16 +1151,16 @@ protected void _puttrailer() {
11391151
}
11401152

11411153
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+
}
11521164
}
11531165

11541166
protected String _textstring(final String s) {

0 commit comments

Comments
 (0)