summaryrefslogtreecommitdiff
authoralwin <alwin>2004-11-01 13:33:51 (UTC)
committer alwin <alwin>2004-11-01 13:33:51 (UTC)
commit915af02212ea80e43da5bcc24415e3e48778bea9 (patch) (unidiff)
treeeff6dbcc2f1e62dfbb8f6ababe183306fe2077e1
parentb3153506a1be76a386f23a3af44f84042d148111 (diff)
downloadopie-915af02212ea80e43da5bcc24415e3e48778bea9.zip
opie-915af02212ea80e43da5bcc24415e3e48778bea9.tar.gz
opie-915af02212ea80e43da5bcc24415e3e48778bea9.tar.bz2
when jpeg image is smaller than requested thumbsize it will not use
scaled loading
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/graphics/opie-eye/slave/jpeg_slave.cpp52
1 files changed, 30 insertions, 22 deletions
diff --git a/noncore/graphics/opie-eye/slave/jpeg_slave.cpp b/noncore/graphics/opie-eye/slave/jpeg_slave.cpp
index fb7d5de..1bb81d9 100644
--- a/noncore/graphics/opie-eye/slave/jpeg_slave.cpp
+++ b/noncore/graphics/opie-eye/slave/jpeg_slave.cpp
@@ -10,13 +10,13 @@ using namespace Opie::Core;
10 10
11/* QT */ 11/* QT */
12#include <qobject.h> 12#include <qobject.h>
13#include <qimage.h> 13#include <qimage.h>
14 14
15/** 15/**
16 exif.h 16 exif.h
17*/ 17*/
18 18
19#include <stdio.h> 19#include <stdio.h>
20#include <stdlib.h> 20#include <stdlib.h>
21#include <math.h> 21#include <math.h>
22#include <time.h> 22#include <time.h>
@@ -263,13 +263,13 @@ int ExifData::ReadJpegSections (QFile & infile, ReadMode_t ReadMode)
263 for (a=0;a<7;a++){ 263 for (a=0;a<7;a++){
264 marker = infile.getch(); 264 marker = infile.getch();
265 if (marker != 0xff) break; 265 if (marker != 0xff) break;
266 266
267 if (a >= 6){ 267 if (a >= 6){
268 268
269 owarn << "too many padding bytes" << oendl; 269 owarn << "too many padding bytes" << oendl;
270 return false; 270 return false;
271 271
272 } 272 }
273 } 273 }
274 274
275 if (marker == 0xff){ 275 if (marker == 0xff){
@@ -328,20 +328,20 @@ int ExifData::ReadJpegSections (QFile & infile, ReadMode_t ReadMode)
328 SectionsRead ++; 328 SectionsRead ++;
329 //HaveAll = 1; 329 //HaveAll = 1;
330 } 330 }
331 return true; 331 return true;
332 332
333 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
334 owarn << "No image in jpeg!" << oendl; 334 owarn << "No image in jpeg!" << oendl;
335 return false; 335 return false;
336 336
337 case M_COM: // Comment section 337 case M_COM: // Comment section
338 // pieczy 2002-02-12 338 // pieczy 2002-02-12
339 // now the User comment goes to UserComment 339 // now the User comment goes to UserComment
340 // 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
341 process_COM(Data, itemlen); 341 process_COM(Data, itemlen);
342 break; 342 break;
343 343
344 case M_JFIF: 344 case M_JFIF:
345 // Regular jpegs always have this tag, exif images have the exif 345 // Regular jpegs always have this tag, exif images have the exif
346 // marker instead, althogh ACDsee will write images with both markers. 346 // marker instead, althogh ACDsee will write images with both markers.
347 // 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.
@@ -544,20 +544,20 @@ void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBa
544 case TAG_MAKE: 544 case TAG_MAKE:
545 ExifData::CameraMake = QString((char*)ValuePtr); 545 ExifData::CameraMake = QString((char*)ValuePtr);
546 break; 546 break;
547 547
548 case TAG_MODEL: 548 case TAG_MODEL:
549 ExifData::CameraModel = QString((char*)ValuePtr); 549 ExifData::CameraModel = QString((char*)ValuePtr);
550 break; 550 break;
551 551
552 case TAG_ORIENTATION: 552 case TAG_ORIENTATION:
553 Orientation = (int)ConvertAnyFormat(ValuePtr, Format); 553 Orientation = (int)ConvertAnyFormat(ValuePtr, Format);
554 break; 554 break;
555 555
556 case TAG_DATETIME_ORIGINAL: 556 case TAG_DATETIME_ORIGINAL:
557 DateTime = QString((char*)ValuePtr); 557 DateTime = QString((char*)ValuePtr);
558 break; 558 break;
559 559
560 case TAG_USERCOMMENT: 560 case TAG_USERCOMMENT:
561 // Olympus has this padded with trailing spaces. Remove these first. 561 // Olympus has this padded with trailing spaces. Remove these first.
562 for (a=ByteCount;;){ 562 for (a=ByteCount;;){
563 a--; 563 a--;
@@ -586,13 +586,13 @@ void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBa
586 } 586 }
587 break; 587 break;
588 588
589 case TAG_FNUMBER: 589 case TAG_FNUMBER:
590 // Simplest way of expressing aperture, so I trust it the most. 590 // Simplest way of expressing aperture, so I trust it the most.
591 // (overwrite previously computd value if there is one) 591 // (overwrite previously computd value if there is one)
592 ExifData::ApertureFNumber = (float)ConvertAnyFormat(ValuePtr, Format); 592 ExifData::ApertureFNumber = (float)ConvertAnyFormat(ValuePtr, Format);
593 break; 593 break;
594 594
595 case TAG_APERTURE: 595 case TAG_APERTURE:
596 case TAG_MAXAPERTURE: 596 case TAG_MAXAPERTURE:
597 // More relevant info always comes earlier, so only use this field if we don't 597 // More relevant info always comes earlier, so only use this field if we don't
598 // have appropriate aperture information yet. 598 // have appropriate aperture information yet.
@@ -663,18 +663,18 @@ void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBa
663 } 663 }
664 break; 664 break;
665 665
666 // Remaining cases contributed by: Volker C. Schoech (schoech@gmx.de) 666 // Remaining cases contributed by: Volker C. Schoech (schoech@gmx.de)
667 667
668 case TAG_EXPOSURE_BIAS: 668 case TAG_EXPOSURE_BIAS:
669 ExifData::ExposureBias = (float)ConvertAnyFormat(ValuePtr, Format); 669 ExifData::ExposureBias = (float)ConvertAnyFormat(ValuePtr, Format);
670 break; 670 break;
671 671
672 case TAG_WHITEBALANCE: 672 case TAG_WHITEBALANCE:
673 ExifData::Whitebalance = (int)ConvertAnyFormat(ValuePtr, Format); 673 ExifData::Whitebalance = (int)ConvertAnyFormat(ValuePtr, Format);
674 break; 674 break;
675 675
676 case TAG_METERING_MODE: 676 case TAG_METERING_MODE:
677 ExifData::MeteringMode = (int)ConvertAnyFormat(ValuePtr, Format); 677 ExifData::MeteringMode = (int)ConvertAnyFormat(ValuePtr, Format);
678 break; 678 break;
679 679
680 case TAG_EXPOSURE_PROGRAM: 680 case TAG_EXPOSURE_PROGRAM:
@@ -717,23 +717,23 @@ void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBa
717 // directory. this has got to be the result of a comitee! 717 // directory. this has got to be the result of a comitee!
718 unsigned char * SubdirStart; 718 unsigned char * SubdirStart;
719 unsigned Offset; 719 unsigned Offset;
720 720
721 if (DIR_ENTRY_ADDR(DirStart, NumDirEntries) + 4 <= OffsetBase+ExifLength){ 721 if (DIR_ENTRY_ADDR(DirStart, NumDirEntries) + 4 <= OffsetBase+ExifLength){
722 Offset = Get32u(DIR_ENTRY_ADDR(DirStart, NumDirEntries)); 722 Offset = Get32u(DIR_ENTRY_ADDR(DirStart, NumDirEntries));
723 // 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.
724 // 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.
725 // See http://bugs.kde.org/show_bug.cgi?id=54542 725 // See http://bugs.kde.org/show_bug.cgi?id=54542
726 if (Offset && Offset < ExifLength){ 726 if (Offset && Offset < ExifLength){
727 SubdirStart = OffsetBase + Offset; 727 SubdirStart = OffsetBase + Offset;
728 if (SubdirStart > OffsetBase+ExifLength){ 728 if (SubdirStart > OffsetBase+ExifLength){
729 if (SubdirStart < OffsetBase+ExifLength+20){ 729 if (SubdirStart < OffsetBase+ExifLength+20){
730 // Jhead 1.3 or earlier would crop the whole directory! 730 // Jhead 1.3 or earlier would crop the whole directory!
731 // As Jhead produces this form of format incorrectness, 731 // As Jhead produces this form of format incorrectness,
732 // I'll just let it pass silently 732 // I'll just let it pass silently
733 owarn << "Thumbnail removed with Jhead 1.3 or earlier" << oendl; 733 owarn << "Thumbnail removed with Jhead 1.3 or earlier" << oendl;
734 }else{ 734 }else{
735 return; 735 return;
736 } 736 }
737 }else{ 737 }else{
738 if (SubdirStart <= OffsetBase+ExifLength){ 738 if (SubdirStart <= OffsetBase+ExifLength){
739 ProcessExifDir(SubdirStart, OffsetBase, ExifLength); 739 ProcessExifDir(SubdirStart, OffsetBase, ExifLength);
@@ -745,13 +745,13 @@ void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBa
745 } 745 }
746 } 746 }
747 747
748 if (ThumbnailSize && ThumbnailOffset){ 748 if (ThumbnailSize && ThumbnailOffset){
749 if (ThumbnailSize + ThumbnailOffset <= ExifLength){ 749 if (ThumbnailSize + ThumbnailOffset <= ExifLength){
750 // The thumbnail pointer appears to be valid. Store it. 750 // The thumbnail pointer appears to be valid. Store it.
751 Thumbnail.loadFromData(OffsetBase + ThumbnailOffset, ThumbnailSize, "JPEG"); 751 Thumbnail.loadFromData(OffsetBase + ThumbnailOffset, ThumbnailSize, "JPEG");
752 } 752 }
753 } 753 }
754} 754}
755 755
756//-------------------------------------------------------------------------- 756//--------------------------------------------------------------------------
757// Process a COM marker. We want to leave the bytes unchanged. The 757// Process a COM marker. We want to leave the bytes unchanged. The
@@ -914,13 +914,13 @@ bool ExifData::scan(const QString & path)
914 f.open(IO_ReadOnly); 914 f.open(IO_ReadOnly);
915 915
916 // Scan the JPEG headers. 916 // Scan the JPEG headers.
917 ret = ReadJpegSections(f, READ_EXIF); 917 ret = ReadJpegSections(f, READ_EXIF);
918 918
919 if (ret == false){ 919 if (ret == false){
920 owarn << "Not JPEG file!" << oendl; 920 owarn << "Not JPEG file!" << oendl;
921 DiscardData(); 921 DiscardData();
922 f.close(); 922 f.close();
923 return false; 923 return false;
924 } 924 }
925 f.close(); 925 f.close();
926 DiscardData(); 926 DiscardData();
@@ -1412,17 +1412,25 @@ QString JpegSlave::fullImageInfo( const QString& path) {
1412 1412
1413 return tag; 1413 return tag;
1414} 1414}
1415 1415
1416QPixmap JpegSlave::pixmap( const QString& path, int wid, int hei) { 1416QPixmap JpegSlave::pixmap( const QString& path, int wid, int hei) {
1417 ExifData ImageInfo; 1417 ExifData ImageInfo;
1418 /*
1419 */
1418 if ( !ImageInfo.scan( path ) || ImageInfo.isNullThumbnail() ) { 1420 if ( !ImageInfo.scan( path ) || ImageInfo.isNullThumbnail() ) {
1419 QImage img; 1421 QImage img;
1420 QImageIO iio( path, 0l ); 1422 QImageIO iio( path, 0l );
1421 QString str = QString( "Fast Shrink( 4 ) Scale( %1, %2, ScaleFree)" ).arg( wid ).arg( hei ); 1423 if (wid < ImageInfo.getWidth() || hei<ImageInfo.getHeight()) {
1422 iio.setParameters( str.latin1() );// will be strdupped anyway 1424 odebug << "Scaling "<<ImageInfo.getWidth()<<"x"<<ImageInfo.getHeight()
1425 << " to "<<wid<<"x"<<hei<< " ("<<path<<")"<<oendl;
1426 QString str = QString( "Fast Shrink( 4 ) Scale( %1, %2, ScaleFree)" ).arg( wid ).arg( hei );
1427 iio.setParameters( str.latin1() );// will be strdupped anyway
1428 } else {
1429 odebug << "Not scaling "<<ImageInfo.getWidth()<<"x"<<ImageInfo.getHeight()<< " ("<<path<<")"<<oendl;
1430 }
1423 img = iio.read() ? iio.image() : QImage(); 1431 img = iio.read() ? iio.image() : QImage();
1424 return ThumbNailTool::scaleImage( img, wid,hei ); 1432 return ThumbNailTool::scaleImage( img, wid,hei );
1425 }else{ 1433 }else{
1426 QImage img = ImageInfo.getThumbnail(); 1434 QImage img = ImageInfo.getThumbnail();
1427 return ThumbNailTool::scaleImage( img, wid,hei ); 1435 return ThumbNailTool::scaleImage( img, wid,hei );
1428 } 1436 }