Diffstat (limited to 'noncore/graphics/opie-eye/slave/jpeg_slave.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/graphics/opie-eye/slave/jpeg_slave.cpp | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/noncore/graphics/opie-eye/slave/jpeg_slave.cpp b/noncore/graphics/opie-eye/slave/jpeg_slave.cpp index 086b47f..fb7d5de 100644 --- a/noncore/graphics/opie-eye/slave/jpeg_slave.cpp +++ b/noncore/graphics/opie-eye/slave/jpeg_slave.cpp | |||
@@ -1,23 +1,27 @@ | |||
1 | #include "jpeg_slave.h" | 1 | #include "jpeg_slave.h" |
2 | |||
3 | #include "thumbnailtool.h" | 2 | #include "thumbnailtool.h" |
4 | 3 | ||
5 | PHUNK_VIEW_INTERFACE( "JPEG", JpegSlave ) | 4 | PHUNK_VIEW_INTERFACE( "JPEG", JpegSlave ) |
6 | 5 | ||
7 | #include <qtopia/timestring.h> | 6 | /* OPIE */ |
7 | #include <opie2/odebug.h> | ||
8 | #include <qpe/timestring.h> | ||
9 | using namespace Opie::Core; | ||
10 | |||
11 | /* QT */ | ||
8 | #include <qobject.h> | 12 | #include <qobject.h> |
9 | #include <qimage.h> | 13 | #include <qimage.h> |
10 | 14 | ||
11 | /** | 15 | /** |
12 | exif.h | 16 | exif.h |
13 | */ | 17 | */ |
14 | 18 | ||
15 | #include <stdio.h> | 19 | #include <stdio.h> |
16 | #include <stdlib.h> | 20 | #include <stdlib.h> |
17 | #include <math.h> | 21 | #include <math.h> |
18 | #include <time.h> | 22 | #include <time.h> |
19 | 23 | ||
20 | #include <qstring.h> | 24 | #include <qstring.h> |
21 | #include <qfile.h> | 25 | #include <qfile.h> |
22 | #include <qimage.h> | 26 | #include <qimage.h> |
23 | 27 | ||
@@ -106,33 +110,33 @@ public: | |||
106 | float getCCDWidth() { return CCDWidth; } | 110 | float getCCDWidth() { return CCDWidth; } |
107 | float getExposureBias() { return ExposureBias; } | 111 | float getExposureBias() { return ExposureBias; } |
108 | int getExposureProgram() { return ExposureProgram; } | 112 | int getExposureProgram() { return ExposureProgram; } |
109 | int getISOequivalent() { return ISOequivalent; } | 113 | int getISOequivalent() { return ISOequivalent; } |
110 | int getCompressionLevel() { return CompressionLevel; } | 114 | int getCompressionLevel() { return CompressionLevel; } |
111 | QString getUserComment() { return UserComment; } | 115 | QString getUserComment() { return UserComment; } |
112 | QString getComment() { return Comment; } | 116 | QString getComment() { return Comment; } |
113 | QImage getThumbnail(); | 117 | QImage getThumbnail(); |
114 | bool isThumbnailSane(); | 118 | bool isThumbnailSane(); |
115 | bool isNullThumbnail() { return !isThumbnailSane(); } | 119 | bool isNullThumbnail() { return !isThumbnailSane(); } |
116 | }; | 120 | }; |
117 | 121 | ||
118 | class FatalError { | 122 | class FatalError { |
119 | const char* ex; | 123 | const char* ex; |
120 | public: | 124 | public: |
121 | FatalError(const char* s) { ex = s; } | 125 | FatalError(const char* s) { ex = s; } |
122 | void debug_print() const { qWarning("exception: %s", ex ); } | 126 | void debug_print() const { owarn << "exception: " << ex << "" << oendl; } |
123 | }; | 127 | }; |
124 | 128 | ||
125 | 129 | ||
126 | 130 | ||
127 | static unsigned char * LastExifRefd; | 131 | static unsigned char * LastExifRefd; |
128 | static int ExifSettingsLength; | 132 | static int ExifSettingsLength; |
129 | static double FocalplaneXRes; | 133 | static double FocalplaneXRes; |
130 | static double FocalplaneUnits; | 134 | static double FocalplaneUnits; |
131 | static int MotorolaOrder = 0; | 135 | static int MotorolaOrder = 0; |
132 | static int SectionsRead; | 136 | static int SectionsRead; |
133 | //static int HaveAll; | 137 | //static int HaveAll; |
134 | 138 | ||
135 | //-------------------------------------------------------------------------- | 139 | //-------------------------------------------------------------------------- |
136 | // Table of Jpeg encoding process names | 140 | // Table of Jpeg encoding process names |
137 | 141 | ||
138 | #define M_SOF0 0xC0 // Start Of Frame N | 142 | #define M_SOF0 0xC0 // Start Of Frame N |
@@ -249,33 +253,33 @@ int ExifData::ReadJpegSections (QFile & infile, ReadMode_t ReadMode) | |||
249 | SectionsRead = 0; | 253 | SectionsRead = 0; |
250 | return false; | 254 | return false; |
251 | } | 255 | } |
252 | for(SectionsRead = 0; SectionsRead < MAX_SECTIONS-1; ){ | 256 | for(SectionsRead = 0; SectionsRead < MAX_SECTIONS-1; ){ |
253 | int marker = 0; | 257 | int marker = 0; |
254 | int got; | 258 | int got; |
255 | unsigned int ll,lh; | 259 | unsigned int ll,lh; |
256 | unsigned int itemlen; | 260 | unsigned int itemlen; |
257 | uchar * Data; | 261 | uchar * Data; |
258 | 262 | ||
259 | for (a=0;a<7;a++){ | 263 | for (a=0;a<7;a++){ |
260 | marker = infile.getch(); | 264 | marker = infile.getch(); |
261 | if (marker != 0xff) break; | 265 | if (marker != 0xff) break; |
262 | 266 | ||
263 | if (a >= 6){ | 267 | if (a >= 6){ |
264 | 268 | ||
265 | qWarning( "too many padding bytes" ); | 269 | owarn << "too many padding bytes" << oendl; |
266 | return false; | 270 | return false; |
267 | 271 | ||
268 | } | 272 | } |
269 | } | 273 | } |
270 | 274 | ||
271 | if (marker == 0xff){ | 275 | if (marker == 0xff){ |
272 | // 0xff is legal padding, but if we get that many, something's wrong. | 276 | // 0xff is legal padding, but if we get that many, something's wrong. |
273 | return false; | 277 | return false; |
274 | } | 278 | } |
275 | 279 | ||
276 | Sections[SectionsRead].Type = marker; | 280 | Sections[SectionsRead].Type = marker; |
277 | 281 | ||
278 | // Read the length of the section. | 282 | // Read the length of the section. |
279 | lh = (uchar) infile.getch(); | 283 | lh = (uchar) infile.getch(); |
280 | ll = (uchar) infile.getch(); | 284 | ll = (uchar) infile.getch(); |
281 | 285 | ||
@@ -314,33 +318,33 @@ int ExifData::ReadJpegSections (QFile & infile, ReadMode_t ReadMode) | |||
314 | } | 318 | } |
315 | 319 | ||
316 | got = infile.readBlock((char*)Data, size); | 320 | got = infile.readBlock((char*)Data, size); |
317 | if (( unsigned ) got != size){ | 321 | if (( unsigned ) got != size){ |
318 | return false; | 322 | return false; |
319 | } | 323 | } |
320 | 324 | ||
321 | Sections[SectionsRead].Data = Data; | 325 | Sections[SectionsRead].Data = Data; |
322 | Sections[SectionsRead].Size = size; | 326 | Sections[SectionsRead].Size = size; |
323 | Sections[SectionsRead].Type = PSEUDO_IMAGE_MARKER; | 327 | Sections[SectionsRead].Type = PSEUDO_IMAGE_MARKER; |
324 | SectionsRead ++; | 328 | SectionsRead ++; |
325 | //HaveAll = 1; | 329 | //HaveAll = 1; |
326 | } | 330 | } |
327 | return true; | 331 | return true; |
328 | 332 | ||
329 | case M_EOI: // in case it's a tables-only JPEG stream | 333 | case M_EOI: // in case it's a tables-only JPEG stream |
330 | qWarning( "No image in jpeg!" ); | 334 | owarn << "No image in jpeg!" << oendl; |
331 | return false; | 335 | return false; |
332 | 336 | ||
333 | case M_COM: // Comment section | 337 | case M_COM: // Comment section |
334 | // pieczy 2002-02-12 | 338 | // pieczy 2002-02-12 |
335 | // now the User comment goes to UserComment | 339 | // now the User comment goes to UserComment |
336 | // so we can store a Comment section also in READ_EXIF mode | 340 | // so we can store a Comment section also in READ_EXIF mode |
337 | process_COM(Data, itemlen); | 341 | process_COM(Data, itemlen); |
338 | break; | 342 | break; |
339 | 343 | ||
340 | case M_JFIF: | 344 | case M_JFIF: |
341 | // Regular jpegs always have this tag, exif images have the exif | 345 | // Regular jpegs always have this tag, exif images have the exif |
342 | // marker instead, althogh ACDsee will write images with both markers. | 346 | // marker instead, althogh ACDsee will write images with both markers. |
343 | // this program will re-create this marker on absence of exif marker. | 347 | // this program will re-create this marker on absence of exif marker. |
344 | // hence no need to keep the copy from the file. | 348 | // hence no need to keep the copy from the file. |
345 | free(Sections[--SectionsRead].Data); | 349 | free(Sections[--SectionsRead].Data); |
346 | break; | 350 | break; |
@@ -713,33 +717,33 @@ void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBa | |||
713 | // directory. this has got to be the result of a comitee! | 717 | // directory. this has got to be the result of a comitee! |
714 | unsigned char * SubdirStart; | 718 | unsigned char * SubdirStart; |
715 | unsigned Offset; | 719 | unsigned Offset; |
716 | 720 | ||
717 | if (DIR_ENTRY_ADDR(DirStart, NumDirEntries) + 4 <= OffsetBase+ExifLength){ | 721 | if (DIR_ENTRY_ADDR(DirStart, NumDirEntries) + 4 <= OffsetBase+ExifLength){ |
718 | Offset = Get32u(DIR_ENTRY_ADDR(DirStart, NumDirEntries)); | 722 | Offset = Get32u(DIR_ENTRY_ADDR(DirStart, NumDirEntries)); |
719 | // There is at least one jpeg from an HP camera having an Offset of almost MAXUINT. | 723 | // There is at least one jpeg from an HP camera having an Offset of almost MAXUINT. |
720 | // Adding OffsetBase to it produces an overflow, so compare with ExifLength here. | 724 | // Adding OffsetBase to it produces an overflow, so compare with ExifLength here. |
721 | // See http://bugs.kde.org/show_bug.cgi?id=54542 | 725 | // See http://bugs.kde.org/show_bug.cgi?id=54542 |
722 | if (Offset && Offset < ExifLength){ | 726 | if (Offset && Offset < ExifLength){ |
723 | SubdirStart = OffsetBase + Offset; | 727 | SubdirStart = OffsetBase + Offset; |
724 | if (SubdirStart > OffsetBase+ExifLength){ | 728 | if (SubdirStart > OffsetBase+ExifLength){ |
725 | if (SubdirStart < OffsetBase+ExifLength+20){ | 729 | if (SubdirStart < OffsetBase+ExifLength+20){ |
726 | // Jhead 1.3 or earlier would crop the whole directory! | 730 | // Jhead 1.3 or earlier would crop the whole directory! |
727 | // As Jhead produces this form of format incorrectness, | 731 | // As Jhead produces this form of format incorrectness, |
728 | // I'll just let it pass silently | 732 | // I'll just let it pass silently |
729 | qWarning( "Thumbnail removed with Jhead 1.3 or earlier" ); | 733 | owarn << "Thumbnail removed with Jhead 1.3 or earlier" << oendl; |
730 | }else{ | 734 | }else{ |
731 | return; | 735 | return; |
732 | } | 736 | } |
733 | }else{ | 737 | }else{ |
734 | if (SubdirStart <= OffsetBase+ExifLength){ | 738 | if (SubdirStart <= OffsetBase+ExifLength){ |
735 | ProcessExifDir(SubdirStart, OffsetBase, ExifLength); | 739 | ProcessExifDir(SubdirStart, OffsetBase, ExifLength); |
736 | } | 740 | } |
737 | } | 741 | } |
738 | } | 742 | } |
739 | }else{ | 743 | }else{ |
740 | // The exif header ends before the last next directory pointer. | 744 | // The exif header ends before the last next directory pointer. |
741 | } | 745 | } |
742 | } | 746 | } |
743 | 747 | ||
744 | if (ThumbnailSize && ThumbnailOffset){ | 748 | if (ThumbnailSize && ThumbnailOffset){ |
745 | if (ThumbnailSize + ThumbnailOffset <= ExifLength){ | 749 | if (ThumbnailSize + ThumbnailOffset <= ExifLength){ |
@@ -900,33 +904,33 @@ ExifData::ExifData() | |||
900 | } | 904 | } |
901 | 905 | ||
902 | //-------------------------------------------------------------------------- | 906 | //-------------------------------------------------------------------------- |
903 | // process a EXIF jpeg file | 907 | // process a EXIF jpeg file |
904 | //-------------------------------------------------------------------------- | 908 | //-------------------------------------------------------------------------- |
905 | bool ExifData::scan(const QString & path) | 909 | bool ExifData::scan(const QString & path) |
906 | { | 910 | { |
907 | int ret; | 911 | int ret; |
908 | 912 | ||
909 | QFile f(path); | 913 | QFile f(path); |
910 | f.open(IO_ReadOnly); | 914 | f.open(IO_ReadOnly); |
911 | 915 | ||
912 | // Scan the JPEG headers. | 916 | // Scan the JPEG headers. |
913 | ret = ReadJpegSections(f, READ_EXIF); | 917 | ret = ReadJpegSections(f, READ_EXIF); |
914 | 918 | ||
915 | if (ret == false){ | 919 | if (ret == false){ |
916 | qWarning( "Not JPEG file!" ); | 920 | owarn << "Not JPEG file!" << oendl; |
917 | DiscardData(); | 921 | DiscardData(); |
918 | f.close(); | 922 | f.close(); |
919 | return false; | 923 | return false; |
920 | } | 924 | } |
921 | f.close(); | 925 | f.close(); |
922 | DiscardData(); | 926 | DiscardData(); |
923 | 927 | ||
924 | //now make the strings clean, | 928 | //now make the strings clean, |
925 | // for exmaple my Casio is a "QV-4000 " | 929 | // for exmaple my Casio is a "QV-4000 " |
926 | CameraMake = CameraMake.stripWhiteSpace(); | 930 | CameraMake = CameraMake.stripWhiteSpace(); |
927 | CameraModel = CameraModel.stripWhiteSpace(); | 931 | CameraModel = CameraModel.stripWhiteSpace(); |
928 | UserComment = UserComment.stripWhiteSpace(); | 932 | UserComment = UserComment.stripWhiteSpace(); |
929 | Comment = Comment.stripWhiteSpace(); | 933 | Comment = Comment.stripWhiteSpace(); |
930 | return true; | 934 | return true; |
931 | } | 935 | } |
932 | 936 | ||