1
2
3
4
5
6
7 package ecar.pojo;
8
9 import java.io.DataInput;
10 import java.io.FileInputStream;
11 import java.io.IOException;
12 import java.io.InputStream;
13 import java.math.BigDecimal;
14 import java.net.URL;
15 import java.util.Vector;
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 public class ImageInfo {
146
147
148
149
150
151
152 public static final int FORMAT_JPEG = 0;
153
154
155
156
157
158
159
160 public static final int FORMAT_GIF = 1;
161
162
163
164
165
166
167
168 public static final int FORMAT_PNG = 2;
169
170
171
172
173
174
175 public static final int FORMAT_BMP = 3;
176
177
178
179
180
181
182 public static final int FORMAT_PCX = 4;
183
184
185
186
187 public static final int FORMAT_IFF = 5;
188
189
190
191
192
193
194 public static final int FORMAT_RAS = 6;
195
196
197 public static final int FORMAT_PBM = 7;
198
199
200 public static final int FORMAT_PGM = 8;
201
202
203 public static final int FORMAT_PPM = 9;
204
205
206 public static final int FORMAT_PSD = 10;
207
208
209
210
211
212
213
214
215
216
217
218
219 private static final String[] FORMAT_NAMES = { "JPEG", "GIF", "PNG", "BMP", "PCX", "IFF", "RAS", "PBM", "PGM", "PPM", "PSD" };
220
221
222
223
224
225 private static final String[] MIME_TYPE_STRINGS = { "image/jpeg", "image/gif", "image/png", "image/bmp", "image/pcx", "image/iff", "image/ras", "image/x-portable-bitmap", "image/x-portable-graymap", "image/x-portable-pixmap", "image/psd" };
226
227 private int width;
228 private int height;
229 private int bitsPerPixel;
230
231 private boolean progressive;
232 private int format;
233 private InputStream in;
234 private DataInput din;
235 private boolean collectComments = true;
236 private Vector comments;
237 private boolean determineNumberOfImages;
238 private int numberOfImages;
239 private int physicalHeightDpi;
240 private int physicalWidthDpi;
241 private int bitBuf;
242 private int bitPos;
243
244 private void addComment(String s) {
245 if (comments == null) {
246 comments = new Vector();
247 }
248 comments.addElement(s);
249 }
250
251
252
253
254
255
256
257
258 public boolean check() {
259 format = -1;
260 width = -1;
261 height = -1;
262 bitsPerPixel = -1;
263 numberOfImages = 1;
264 physicalHeightDpi = -1;
265 physicalWidthDpi = -1;
266 comments = null;
267 try {
268 int b1 = read() & 0xff;
269 int b2 = read() & 0xff;
270 if (b1 == 0x47 && b2 == 0x49) {
271 return checkGif();
272 }
273 else if (b1 == 0x89 && b2 == 0x50) {
274 return checkPng();
275 }
276 else if (b1 == 0xff && b2 == 0xd8) {
277 return checkJpeg();
278 }
279 else if (b1 == 0x42 && b2 == 0x4d) {
280 return checkBmp();
281 }
282 else if (b1 == 0x0a && b2 < 0x06) {
283 return checkPcx();
284 }
285 else if (b1 == 0x46 && b2 == 0x4f) {
286 return checkIff();
287 }
288 else if (b1 == 0x59 && b2 == 0xa6) {
289 return checkRas();
290 }
291 else if (b1 == 0x50 && b2 >= 0x31 && b2 <= 0x36) {
292 return checkPnm(b2 - '0');
293 }
294 else if (b1 == 0x38 && b2 == 0x42) {
295 return checkPsd();
296 }
297 else {
298 return false;
299 }
300 } catch (IOException ioe) {
301 return false;
302 }
303 }
304
305 private boolean checkBmp() throws IOException {
306 byte[] a = new byte[44];
307 if (read(a) != a.length) {
308 return false;
309 }
310 width = getIntLittleEndian(a, 16);
311 height = getIntLittleEndian(a, 20);
312 if (width < 1 || height < 1) {
313 return false;
314 }
315 bitsPerPixel = getShortLittleEndian(a, 26);
316 if (bitsPerPixel != 1 && bitsPerPixel != 4 && bitsPerPixel != 8 && bitsPerPixel != 16 && bitsPerPixel != 24 && bitsPerPixel != 32) {
317 return false;
318 }
319 int x = (int) (getIntLittleEndian(a, 36) * 0.0254);
320 if (x > 0) {
321 setPhysicalWidthDpi(x);
322 }
323 int y = (int) (getIntLittleEndian(a, 40) * 0.0254);
324 if (y > 0) {
325 setPhysicalHeightDpi(y);
326 }
327 format = FORMAT_BMP;
328 return true;
329 }
330
331 private boolean checkGif() throws IOException {
332 final byte[] GIF_MAGIC_87A = { 0x46, 0x38, 0x37, 0x61 };
333 final byte[] GIF_MAGIC_89A = { 0x46, 0x38, 0x39, 0x61 };
334 byte[] a = new byte[11];
335
336 if (read(a) != 11) {
337 return false;
338 }
339 if ((!equals(a, 0, GIF_MAGIC_89A, 0, 4)) && (!equals(a, 0, GIF_MAGIC_87A, 0, 4))) {
340 return false;
341 }
342 format = FORMAT_GIF;
343 width = getShortLittleEndian(a, 4);
344 height = getShortLittleEndian(a, 6);
345 int flags = a[8] & 0xff;
346 bitsPerPixel = ((flags >> 4) & 0x07) + 1;
347
348 if (!determineNumberOfImages) {
349 return true;
350 }
351
352 if ((flags & 0x80) != 0) {
353 int tableSize = (1 << ((flags & 7) + 1)) * 3;
354 skip(tableSize);
355 }
356 numberOfImages = 0;
357 int blockType;
358 do {
359 blockType = read();
360 switch (blockType) {
361 case (0x2c):
362 {
363 if (read(a, 0, 9) != 9) {
364 return false;
365 }
366 flags = a[8] & 0xff;
367 progressive = (flags & 0x40) != 0;
368
369
370
371
372
373 int localBitsPerPixel = (flags & 0x07) + 1;
374 if (localBitsPerPixel > bitsPerPixel) {
375 bitsPerPixel = localBitsPerPixel;
376 }
377 if ((flags & 0x80) != 0) {
378 skip((1 << localBitsPerPixel) * 3);
379 }
380 skip(1);
381 int n;
382 do {
383 n = read();
384 if (n > 0) {
385 skip(n);
386 }
387 else if (n == -1) {
388 return false;
389 }
390 } while (n > 0);
391 numberOfImages++;
392 break;
393 }
394 case (0x21):
395 {
396 int extensionType = read();
397 if (collectComments && extensionType == 0xfe) {
398 StringBuffer sb = new StringBuffer();
399 int n;
400 do {
401 n = read();
402 if (n == -1) {
403 return false;
404 }
405 if (n > 0) {
406 for (int i = 0; i < n; i++) {
407 int ch = read();
408 if (ch == -1) {
409 return false;
410 }
411 sb.append((char) ch);
412 }
413 }
414 } while (n > 0);
415 }
416 else {
417 int n;
418 do {
419 n = read();
420 if (n > 0) {
421 skip(n);
422 }
423 else if (n == -1) {
424 return false;
425 }
426 } while (n > 0);
427 }
428 break;
429 }
430 case (0x3b):
431 {
432 break;
433 }
434 default: {
435 return false;
436 }
437 }
438 } while (blockType != 0x3b);
439 return true;
440 }
441
442 private boolean checkIff() throws IOException {
443 byte[] a = new byte[10];
444
445
446 if (read(a, 0, 10) != 10) {
447 return false;
448 }
449 final byte[] IFF_RM = { 0x52, 0x4d };
450 if (!equals(a, 0, IFF_RM, 0, 2)) {
451 return false;
452 }
453 int type = getIntBigEndian(a, 6);
454 if (type != 0x494c424d &&
455 type != 0x50424d20) {
456 return false;
457 }
458
459 do {
460 if (read(a, 0, 8) != 8) {
461 return false;
462 }
463 int chunkId = getIntBigEndian(a, 0);
464 int size = getIntBigEndian(a, 4);
465 if ((size & 1) == 1) {
466 size++;
467 }
468 if (chunkId == 0x424d4844) {
469 if (read(a, 0, 9) != 9) {
470 return false;
471 }
472 format = FORMAT_IFF;
473 width = getShortBigEndian(a, 0);
474 height = getShortBigEndian(a, 2);
475 bitsPerPixel = a[8] & 0xff;
476 return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel < 33);
477 }
478 else {
479 skip(size);
480 }
481 } while (true);
482 }
483
484 private boolean checkJpeg() throws IOException {
485 byte[] data = new byte[12];
486 while (true) {
487 if (read(data, 0, 4) != 4) {
488 return false;
489 }
490 int marker = getShortBigEndian(data, 0);
491 int size = getShortBigEndian(data, 2);
492 if ((marker & 0xff00) != 0xff00) {
493 return false;
494 }
495 if (marker == 0xffe0) {
496 if (size < 14) {
497 return false;
498 }
499 if (read(data, 0, 12) != 12) {
500 return false;
501 }
502 final byte[] APP0_ID = { 0x4a, 0x46, 0x49, 0x46, 0x00 };
503 if (equals(APP0_ID, 0, data, 0, 5)) {
504
505 if (data[7] == 1) {
506 setPhysicalWidthDpi(getShortBigEndian(data, 8));
507 setPhysicalHeightDpi(getShortBigEndian(data, 10));
508 }
509 else if (data[7] == 2) {
510 int x = getShortBigEndian(data, 8);
511 int y = getShortBigEndian(data, 10);
512 setPhysicalWidthDpi((int) (x * 2.54f));
513 setPhysicalHeightDpi((int) (y * 2.54f));
514 }
515 }
516 skip(size - 14);
517 }
518 else if (collectComments && size > 2 && marker == 0xfffe) {
519 size -= 2;
520 byte[] chars = new byte[size];
521 if (read(chars, 0, size) != size) {
522 return false;
523 }
524 String comment = new String(chars, "iso-8859-1");
525 comment = comment.trim();
526 addComment(comment);
527 }
528 else if (marker >= 0xffc0 && marker <= 0xffcf && marker != 0xffc4 && marker != 0xffc8) {
529 if (read(data, 0, 6) != 6) {
530 return false;
531 }
532 format = FORMAT_JPEG;
533 bitsPerPixel = (data[0] & 0xff) * (data[5] & 0xff);
534 progressive = marker == 0xffc2 || marker == 0xffc6 || marker == 0xffca || marker == 0xffce;
535 width = getShortBigEndian(data, 3);
536 height = getShortBigEndian(data, 1);
537 return true;
538 }
539 else {
540 skip(size - 2);
541 }
542 }
543 }
544
545 private boolean checkPcx() throws IOException {
546 byte[] a = new byte[64];
547 if (read(a) != a.length) {
548 return false;
549 }
550 if (a[0] != 1) {
551 return false;
552 }
553
554 int x1 = getShortLittleEndian(a, 2);
555 int y1 = getShortLittleEndian(a, 4);
556 int x2 = getShortLittleEndian(a, 6);
557 int y2 = getShortLittleEndian(a, 8);
558 if (x1 < 0 || x2 < x1 || y1 < 0 || y2 < y1) {
559 return false;
560 }
561 width = x2 - x1 + 1;
562 height = y2 - y1 + 1;
563
564 int bits = a[1];
565 int planes = a[63];
566 if (planes == 1 && (bits == 1 || bits == 2 || bits == 4 || bits == 8)) {
567
568 bitsPerPixel = bits;
569 }
570 else if (planes == 3 && bits == 8) {
571
572 bitsPerPixel = 24;
573 }
574 else {
575 return false;
576 }
577 setPhysicalWidthDpi(getShortLittleEndian(a, 10));
578 setPhysicalHeightDpi(getShortLittleEndian(a, 10));
579 format = FORMAT_PCX;
580 return true;
581 }
582
583 private boolean checkPng() throws IOException {
584 final byte[] PNG_MAGIC = { 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
585 byte[] a = new byte[27];
586 if (read(a) != 27) {
587 return false;
588 }
589 if (!equals(a, 0, PNG_MAGIC, 0, 6)) {
590 return false;
591 }
592 format = FORMAT_PNG;
593 width = getIntBigEndian(a, 14);
594 height = getIntBigEndian(a, 18);
595 bitsPerPixel = a[22] & 0xff;
596 int colorType = a[23] & 0xff;
597 if (colorType == 2 || colorType == 6) {
598 bitsPerPixel *= 3;
599 }
600 progressive = (a[26] & 0xff) != 0;
601 return true;
602 }
603
604 private boolean checkPnm(int id) throws IOException {
605 if (id < 1 || id > 6) {
606 return false;
607 }
608 final int[] PNM_FORMATS = { FORMAT_PBM, FORMAT_PGM, FORMAT_PPM };
609 format = PNM_FORMATS[(id - 1) % 3];
610 boolean hasPixelResolution = false;
611 String s;
612 while (true) {
613 s = readLine();
614 if (s != null) {
615 s = s.trim();
616 }
617 if (s == null || s.length() < 1) {
618 continue;
619 }
620 if (s.charAt(0) == '#') {
621 if (collectComments && s.length() > 1) {
622 addComment(s.substring(1));
623 }
624 continue;
625 }
626 if (!hasPixelResolution) {
627 int spaceIndex = s.indexOf(' ');
628 if (spaceIndex == -1) {
629 return false;
630 }
631 String widthString = s.substring(0, spaceIndex);
632 spaceIndex = s.lastIndexOf(' ');
633 if (spaceIndex == -1) {
634 return false;
635 }
636 String heightString = s.substring(spaceIndex + 1);
637 try {
638 width = Integer.parseInt(widthString);
639 height = Integer.parseInt(heightString);
640 } catch (NumberFormatException nfe) {
641 return false;
642 }
643 if (width < 1 || height < 1) {
644 return false;
645 }
646 if (format == FORMAT_PBM) {
647 bitsPerPixel = 1;
648 return true;
649 }
650 hasPixelResolution = true;
651 }
652 else {
653 int maxSample;
654 try {
655 maxSample = Integer.parseInt(s);
656 } catch (NumberFormatException nfe) {
657 return false;
658 }
659 if (maxSample < 0) {
660 return false;
661 }
662 for (int i = 0; i < 25; i++) {
663 if (maxSample < (1 << (i + 1))) {
664 bitsPerPixel = i + 1;
665 if (format == FORMAT_PPM) {
666 bitsPerPixel *= 3;
667 }
668 return true;
669 }
670 }
671 return false;
672 }
673 }
674 }
675
676 private boolean checkPsd() throws IOException {
677 byte[] a = new byte[24];
678 if (read(a) != a.length) {
679 return false;
680 }
681 final byte[] PSD_MAGIC = { 0x50, 0x53 };
682 if (!equals(a, 0, PSD_MAGIC, 0, 2)) {
683 return false;
684 }
685 format = FORMAT_PSD;
686 width = getIntBigEndian(a, 16);
687 height = getIntBigEndian(a, 12);
688 int channels = getShortBigEndian(a, 10);
689 int depth = getShortBigEndian(a, 20);
690 bitsPerPixel = channels * depth;
691 return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel <= 64);
692 }
693
694 private boolean checkRas() throws IOException {
695 byte[] a = new byte[14];
696 if (read(a) != a.length) {
697 return false;
698 }
699 final byte[] RAS_MAGIC = { 0x6a, (byte) 0x95 };
700 if (!equals(a, 0, RAS_MAGIC, 0, 2)) {
701 return false;
702 }
703 format = FORMAT_RAS;
704 width = getIntBigEndian(a, 2);
705 height = getIntBigEndian(a, 6);
706 bitsPerPixel = getIntBigEndian(a, 10);
707 return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel <= 24);
708 }
709
710
711
712
713
714
715 private static boolean determineVerbosity(String[] args) {
716 if (args != null && args.length > 0) {
717 for (int i = 0; i < args.length; i++) {
718 if ("-c".equals(args[i])) {
719 return false;
720 }
721 }
722 }
723 return true;
724 }
725
726 private static boolean equals(byte[] a1, int offs1, byte[] a2, int offs2, int num) {
727 while (num-- > 0) {
728 if (a1[offs1++] != a2[offs2++]) {
729 return false;
730 }
731 }
732 return true;
733 }
734
735
736
737
738
739
740 public int getBitsPerPixel() {
741 return bitsPerPixel;
742 }
743
744
745
746
747
748
749
750
751 public String getComment(int index) {
752 if (comments == null || index < 0 || index >= comments.size()) {
753 throw new IllegalArgumentException("Not a valid comment index: " + index);
754 }
755 return (String) comments.elementAt(index);
756 }
757
758
759
760
761
762
763
764 public int getFormat() {
765 return format;
766 }
767
768
769
770
771
772
773 public String getFormatName() {
774 if (format >= 0 && format < FORMAT_NAMES.length) {
775 return FORMAT_NAMES[format];
776 }
777 else {
778 return "?";
779 }
780 }
781
782
783
784
785
786
787 public int getHeight() {
788 return height;
789 }
790
791 private static int getIntBigEndian(byte[] a, int offs) {
792 return (a[offs] & 0xff) << 24 | (a[offs + 1] & 0xff) << 16 | (a[offs + 2] & 0xff) << 8 | a[offs + 3] & 0xff;
793 }
794
795 private static int getIntLittleEndian(byte[] a, int offs) {
796 return (a[offs + 3] & 0xff) << 24 | (a[offs + 2] & 0xff) << 16 | (a[offs + 1] & 0xff) << 8 | a[offs] & 0xff;
797 }
798
799
800
801
802
803
804 public String getMimeType() {
805 if (format >= 0 && format < MIME_TYPE_STRINGS.length) {
806 if (format == FORMAT_JPEG && progressive) {
807 return "image/pjpeg";
808 }
809 return MIME_TYPE_STRINGS[format];
810 }
811 else {
812 return null;
813 }
814 }
815
816
817
818
819
820
821
822
823
824 public int getNumberOfComments() {
825 if (comments == null) {
826 return 0;
827 }
828 else {
829 return comments.size();
830 }
831 }
832
833
834
835
836
837
838
839
840 public int getNumberOfImages() {
841 return numberOfImages;
842 }
843
844
845
846
847
848
849
850
851 public int getPhysicalHeightDpi() {
852 return physicalHeightDpi;
853 }
854
855
856
857
858
859
860
861
862
863 public float getPhysicalHeightInch() {
864 int h = getHeight();
865 int ph = getPhysicalHeightDpi();
866 if (h > 0 && ph > 0) {
867 return ((float) h) / ((float) ph);
868 }
869 else {
870 return -1.0f;
871 }
872 }
873
874
875
876
877
878
879
880
881
882 public int getPhysicalWidthDpi() {
883 return physicalWidthDpi;
884 }
885
886
887
888
889
890
891
892
893
894 public float getPhysicalWidthInch() {
895 int w = getWidth();
896 int pw = getPhysicalWidthDpi();
897 if (w > 0 && pw > 0) {
898 return ((float) w) / ((float) pw);
899 }
900 else {
901 return -1.0f;
902 }
903 }
904
905 private static int getShortBigEndian(byte[] a, int offs) {
906 return (a[offs] & 0xff) << 8 | (a[offs + 1] & 0xff);
907 }
908
909 private static int getShortLittleEndian(byte[] a, int offs) {
910 return (a[offs] & 0xff) | (a[offs + 1] & 0xff) << 8;
911 }
912
913
914
915
916
917
918 public int getWidth() {
919 return width;
920 }
921
922
923
924
925
926
927 public boolean isProgressive() {
928 return progressive;
929 }
930
931
932
933
934
935
936
937
938 public static void main(String[] args) {
939 ImageInfo imageInfo = new ImageInfo();
940 imageInfo.setDetermineImageNumber(true);
941 boolean verbose = determineVerbosity(args);
942 if (args.length == 0) {
943 run(null, System.in, imageInfo, verbose);
944 }
945 else {
946 int index = 0;
947 while (index < args.length) {
948 InputStream in = null;
949 try {
950 String name = args[index++];
951
952 if (name.startsWith("http://")) {
953 in = new URL(name).openConnection().getInputStream();
954 }
955 else {
956 in = new FileInputStream(name);
957 }
958 run(name, in, imageInfo, verbose);
959 in.close();
960 } catch (IOException e) {
961
962 try {
963 in.close();
964 } catch (IOException ee) {
965 }
966 }
967 }
968 }
969 }
970
971 private static void print(String sourceName, ImageInfo ii, boolean verbose) {
972 if (verbose) {
973 printVerbose(sourceName, ii);
974 }
975 else {
976 printCompact(sourceName, ii);
977 }
978 }
979
980 private static void printCompact(String sourceName, ImageInfo imageInfo) {
981 final String SEP = "\t";
982
983
984
985
986
987
988
989
990
991 }
992
993 private static void printLine(int indentLevels, String text, float value, float minValidValue) {
994 if (value < minValidValue) {
995 return;
996 }
997 printLine(indentLevels, text, Float.toString(value));
998 }
999
1000 private static void printLine(int indentLevels, String text, int value, int minValidValue) {
1001 if (value >= minValidValue) {
1002 printLine(indentLevels, text, Integer.toString(value));
1003 }
1004 }
1005
1006 private static void printLine(int indentLevels, String text, String value) {
1007 if (value == null || value.length() == 0) {
1008 return;
1009 }
1010 while (indentLevels-- > 0) {
1011
1012 }
1013 if (text != null && text.length() > 0) {
1014
1015
1016 }
1017
1018 }
1019
1020 private static void printVerbose(String sourceName, ImageInfo ii) {
1021 printLine(0, null, sourceName);
1022 printLine(1, "File format: ", ii.getFormatName());
1023 printLine(1, "MIME type: ", ii.getMimeType());
1024 printLine(1, "Width (pixels): ", ii.getWidth(), 1);
1025 printLine(1, "Height (pixels): ", ii.getHeight(), 1);
1026 printLine(1, "Bits per pixel: ", ii.getBitsPerPixel(), 1);
1027 printLine(1, "Progressive: ", ii.isProgressive() ? "yes" : "no");
1028 printLine(1, "Number of images: ", ii.getNumberOfImages(), 1);
1029 printLine(1, "Physical width (dpi): ", ii.getPhysicalWidthDpi(), 1);
1030 printLine(1, "Physical height (dpi): ", ii.getPhysicalHeightDpi(), 1);
1031 printLine(1, "Physical width (inches): ", ii.getPhysicalWidthInch(), 1.0f);
1032 printLine(1, "Physical height (inches): ", ii.getPhysicalHeightInch(), 1.0f);
1033 int numComments = ii.getNumberOfComments();
1034 printLine(1, "Number of textual comments: ", numComments, 1);
1035 if (numComments > 0) {
1036 for (int i = 0; i < numComments; i++) {
1037 printLine(2, null, ii.getComment(i));
1038 }
1039 }
1040 }
1041
1042 private int read() throws IOException {
1043 if (in != null) {
1044 return in.read();
1045 }
1046 else {
1047 return din.readByte();
1048 }
1049 }
1050
1051 private int read(byte[] a) throws IOException {
1052 if (in != null) {
1053 return in.read(a);
1054 }
1055 else {
1056 din.readFully(a);
1057 return a.length;
1058 }
1059 }
1060
1061 private int read(byte[] a, int offset, int num) throws IOException {
1062 if (in != null) {
1063 return in.read(a, offset, num);
1064 }
1065 else {
1066 din.readFully(a, offset, num);
1067 return num;
1068 }
1069 }
1070
1071 private String readLine() throws IOException {
1072 return readLine(new StringBuffer());
1073 }
1074
1075 private String readLine(StringBuffer sb) throws IOException {
1076 boolean finished;
1077 do {
1078 int value = read();
1079 finished = (value == -1 || value == 10);
1080 if (!finished) {
1081 sb.append((char) value);
1082 }
1083 } while (!finished);
1084 return sb.toString();
1085 }
1086
1087 private long readUBits(int numBits) throws IOException {
1088 if (numBits == 0) {
1089 return 0;
1090 }
1091 int bitsLeft = numBits;
1092 long result = 0;
1093 if (bitPos == 0) {
1094 if (in != null) {
1095 bitBuf = in.read();
1096 }
1097 else {
1098 bitBuf = din.readByte();
1099 }
1100 bitPos = 8;
1101 }
1102
1103 while (true) {
1104 int shift = bitsLeft - bitPos;
1105 if (shift > 0) {
1106
1107 result |= bitBuf << shift;
1108 bitsLeft -= bitPos;
1109
1110
1111 if (in != null) {
1112 bitBuf = in.read();
1113 }
1114 else {
1115 bitBuf = din.readByte();
1116 }
1117 bitPos = 8;
1118 }
1119 else {
1120
1121 result |= bitBuf >> -shift;
1122 bitPos -= bitsLeft;
1123 bitBuf &= 0xff >> (8 - bitPos);
1124
1125 return result;
1126 }
1127 }
1128 }
1129
1130
1131
1132
1133
1134 private int readSBits(int numBits) throws IOException {
1135
1136 long uBits = readUBits(numBits);
1137
1138
1139 if ((uBits & (1L << (numBits - 1))) != 0) {
1140
1141 uBits |= -1L << numBits;
1142 }
1143
1144 return (int) uBits;
1145 }
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157 private static void run(String sourceName, InputStream in, ImageInfo imageInfo, boolean verbose) {
1158 imageInfo.setInput(in);
1159 imageInfo.setDetermineImageNumber(true);
1160 imageInfo.setCollectComments(verbose);
1161 if (imageInfo.check()) {
1162 print(sourceName, imageInfo, verbose);
1163 }
1164 }
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174 public void setCollectComments(boolean newValue) {
1175 collectComments = newValue;
1176 }
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189 public void setDetermineImageNumber(boolean newValue) {
1190 determineNumberOfImages = newValue;
1191 }
1192
1193
1194
1195
1196
1197
1198 public void setInput(DataInput dataInput) {
1199 din = dataInput;
1200 in = null;
1201 }
1202
1203
1204
1205
1206
1207 public void setInput(InputStream inputStream) {
1208 in = inputStream;
1209 din = null;
1210 }
1211
1212 private void setPhysicalHeightDpi(int newValue) {
1213 physicalWidthDpi = newValue;
1214 }
1215
1216 private void setPhysicalWidthDpi(int newValue) {
1217 physicalHeightDpi = newValue;
1218 }
1219
1220 private void skip(int num) throws IOException {
1221 while (num > 0) {
1222 long result;
1223 if (in != null) {
1224 result = in.skip(num);
1225 }
1226 else {
1227 result = din.skipBytes(num);
1228 }
1229 if (result > 0) {
1230 num -= result;
1231 }
1232 }
1233 }
1234
1235 public void redimensionaImagem(int limite) {
1236
1237 int larguraImagem;
1238 int alturaImagem;
1239 int diferenca1 = 0;
1240 int diferenca2 = 0;
1241 double proporcao = 0;
1242 double conversao = 0;
1243 int decimalPlace = 0;
1244
1245 larguraImagem = this.getWidth();
1246 alturaImagem = this.getHeight();
1247
1248 Integer largura = Integer.valueOf(larguraImagem);
1249 Integer altura = Integer.valueOf(alturaImagem);
1250 Integer limiteMaximo = Integer.valueOf(limite);
1251
1252 if (larguraImagem > 0 && alturaImagem > 0) {
1253
1254 if (larguraImagem < limite && alturaImagem > limite) {
1255
1256 proporcao = altura.doubleValue() / limiteMaximo.doubleValue();
1257 conversao = largura.doubleValue() / proporcao;
1258
1259 BigDecimal bd = new BigDecimal(conversao);
1260 bd = bd.setScale(decimalPlace, BigDecimal.ROUND_UP);
1261 conversao = bd.doubleValue();
1262
1263 larguraImagem = (int) conversao;
1264 alturaImagem = limite;
1265
1266 }
1267
1268 if (larguraImagem > limite && alturaImagem < limite) {
1269
1270 proporcao = largura.doubleValue() / limiteMaximo.doubleValue();
1271 conversao = altura.doubleValue() / proporcao;
1272
1273 BigDecimal bd = new BigDecimal(conversao);
1274 bd = bd.setScale(decimalPlace, BigDecimal.ROUND_UP);
1275 conversao = bd.doubleValue();
1276
1277 alturaImagem = (int) conversao;
1278 larguraImagem = limite;
1279
1280 }
1281
1282 if (larguraImagem > limite && alturaImagem > limite) {
1283
1284 diferenca1 = larguraImagem - limite;
1285
1286 diferenca2 = alturaImagem - limite;
1287
1288 if (diferenca1 > diferenca2) {
1289
1290 proporcao = largura.doubleValue() / limiteMaximo.doubleValue();
1291 conversao = altura.doubleValue() / proporcao;
1292
1293 BigDecimal bd = new BigDecimal(conversao);
1294 bd = bd.setScale(decimalPlace, BigDecimal.ROUND_UP);
1295 conversao = bd.doubleValue();
1296
1297 alturaImagem = (int) conversao;
1298 larguraImagem = limite;
1299
1300 }
1301
1302 if (diferenca1 < diferenca2) {
1303
1304 proporcao = altura.doubleValue() / limiteMaximo.doubleValue();
1305 conversao = largura.doubleValue() / proporcao;
1306
1307 BigDecimal bd = new BigDecimal(conversao);
1308 bd = bd.setScale(decimalPlace, BigDecimal.ROUND_UP);
1309 conversao = bd.doubleValue();
1310
1311 larguraImagem = (int) conversao;
1312 alturaImagem = limite;
1313
1314 }
1315
1316 if (diferenca1 == diferenca2) {
1317
1318 alturaImagem = limite;
1319 larguraImagem = limite;
1320 }
1321 }
1322 }
1323
1324 this.width = larguraImagem;
1325 this.height = alturaImagem;
1326
1327 }
1328
1329 public void zoomImagem(String zoom) {
1330
1331 int larguraImagem;
1332 int alturaImagem;
1333 double zoomAltura = 0;
1334 double zoomLargura = 0;
1335 int decimalPlace = 0;
1336
1337 larguraImagem = this.getWidth();
1338 alturaImagem = this.getHeight();
1339
1340 Integer largura = Integer.valueOf(larguraImagem);
1341 Integer altura = Integer.valueOf(alturaImagem);
1342
1343 if ("50%".equals(zoom)) {
1344 zoomAltura = altura.doubleValue() * 0.5;
1345 zoomLargura = largura.doubleValue() * 0.5;
1346 }
1347
1348 if ("75%".equals(zoom)) {
1349 zoomAltura = altura.doubleValue() * 0.75;
1350 zoomLargura = largura.doubleValue() * 0.75;
1351 }
1352
1353 if ("150%".equals(zoom)) {
1354 zoomAltura = altura.doubleValue() * 1.5;
1355 zoomLargura = largura.doubleValue() * 1.5;
1356 }
1357
1358 if ("200%".equals(zoom)) {
1359 zoomAltura = altura.doubleValue() * 2;
1360 zoomLargura = largura.doubleValue() * 2;
1361 }
1362
1363 if ("300%".equals(zoom)) {
1364 zoomAltura = altura.doubleValue() * 3;
1365 zoomLargura = largura.doubleValue() * 3;
1366 }
1367
1368 BigDecimal bdAltura = new BigDecimal(zoomAltura);
1369 bdAltura = bdAltura.setScale(decimalPlace, BigDecimal.ROUND_UP);
1370 zoomAltura = bdAltura.doubleValue();
1371
1372 BigDecimal bdLargura = new BigDecimal(zoomLargura);
1373 bdLargura = bdLargura.setScale(decimalPlace, BigDecimal.ROUND_UP);
1374 zoomLargura = bdLargura.doubleValue();
1375
1376 alturaImagem = (int) zoomAltura;
1377 larguraImagem = (int) zoomLargura;
1378
1379 this.width = larguraImagem;
1380 this.height = alturaImagem;
1381
1382 }
1383
1384 }