00001 #include "bmp_slave.h"
00002
00003 #include "thumbnailtool.h"
00004
00005 #include <qimage.h>
00006 #include <qobject.h>
00007 #include <qfile.h>
00008 #include <qpixmap.h>
00009 #include <qstring.h>
00010
00011 PHUNK_VIEW_INTERFACE( "Bmp", BmpSlave );
00012 namespace {
00013
00014 struct pBmpHeader {
00015
00016 char type[2];
00017 Q_INT32 hSize;
00018 Q_INT32 reserved1,reserved2;
00019
00020 Q_INT16 Planes;
00021 Q_INT16 BitCount;
00022 Q_INT32 Size;
00023 Q_INT32 Width;
00024 Q_INT32 Height;
00025 Q_INT32 Compression;
00026 Q_INT32 SizeImage;
00027 Q_INT32 XPerMeter;
00028 Q_INT32 YPerMeter;
00029 Q_INT32 ClrUsed;
00030 Q_INT32 ClrImportant;
00031 };
00032
00033 class BmpHeader {
00034 protected:
00035 void read_data();
00036 QString _name;
00037 QFile _inputfile;
00038 pBmpHeader m_Header;
00039
00040 static const int OLD = 12;
00041 static const int WIN = 40;
00042 static const int OS2 = 64;
00043 static const int RGB = 0;
00044 static const int RLE8 = 1;
00045 static const int RLE4 = 2;
00046
00047 public:
00048 BmpHeader(const QString&fname);
00049 virtual ~BmpHeader();
00050 bool isBmp()const{return qstrncmp(m_Header.type,"BM",2)==0;}
00051 bool isCompressed()const{return m_Header.Compression != 0;}
00052 QSize imageSize(){return QSize(m_Header.Width,m_Header.Height);}
00053 QString imageCompression()const;
00054 int bitsPixel()const{return m_Header.BitCount;}
00055 int Size()const{return m_Header.hSize;}
00056 int compressedSize()const{return m_Header.SizeImage;}
00057 int ColorsUsed()const{return m_Header.ClrUsed;}
00058 int XPix()const{return m_Header.XPerMeter;}
00059 int YPix()const{return m_Header.YPerMeter;}
00060 };
00061
00062 QString BmpHeader::imageCompression()const
00063 {
00064 switch (m_Header.Compression) {
00065 case RLE8:
00066 return "8Bit RLE Encoding";
00067 break;
00068 case RLE4:
00069 return "4Bit RLE Encoding";
00070 break;
00071 case RGB:
00072 default:
00073 return "No encoding";
00074 }
00075 }
00076
00077 BmpHeader::BmpHeader(const QString&fname)
00078 : _name(fname),_inputfile(_name)
00079 {
00080 read_data();
00081 }
00082
00083 void BmpHeader::read_data() {
00084 memset(&m_Header,0,sizeof(pBmpHeader));
00085 _inputfile.open(IO_Raw|IO_ReadOnly);
00086 if (!_inputfile.isOpen()) {
00087 return;
00088 }
00089 QDataStream s(&_inputfile);
00090 s.setByteOrder( QDataStream::LittleEndian );
00091 s.readRawBytes(m_Header.type,2);
00092 if (!isBmp()) {
00093 _inputfile.close();
00094 return;
00095 }
00096 s >> m_Header.hSize;
00097 s >> m_Header.reserved1 >> m_Header.reserved2;
00098 s >> m_Header.Size;
00099 if ( m_Header.Size == BmpHeader::WIN || m_Header.Size == BmpHeader::OS2 ) {
00100 s >> m_Header.Width >> m_Header.Height >> m_Header.Planes >> m_Header.BitCount;
00101 s >> m_Header.Compression >> m_Header.SizeImage;
00102 s >> m_Header.XPerMeter >> m_Header.YPerMeter;
00103 s >> m_Header.ClrUsed >> m_Header.ClrImportant;
00104 } else {
00105 Q_INT16 w, h;
00106 s >> w >> h >> m_Header.Planes >> m_Header.BitCount;
00107 m_Header.Width = w;
00108 m_Header.Height = h;
00109 m_Header.Compression = BmpHeader::RGB;
00110 m_Header.SizeImage = 0;
00111 m_Header.XPerMeter = m_Header.YPerMeter = 0;
00112 m_Header.ClrUsed = m_Header.ClrImportant = 0;
00113 }
00114 _inputfile.close();
00115 }
00116
00117 BmpHeader::~BmpHeader() {
00118 }
00119 }
00120
00121
00122 BmpSlave::BmpSlave()
00123 : SlaveInterface(QStringList("bmp"))
00124 {}
00125
00126 BmpSlave::~BmpSlave() {
00127
00128 }
00129
00130 QString BmpSlave::iconViewName(const QString& str) {
00131 QString st;
00132 BmpHeader bh(str);
00133 if (!bh.isBmp()) {
00134 st.append("No bmp file");
00135 return st;
00136 }
00137 QSize isize = bh.imageSize();
00138 st+=QObject::tr("Dimensions: %1 x %2\n").arg(isize.width()).arg(isize.height());
00139 st+=QObject::tr("Size: %1\n").arg(bh.Size());
00140 st+=QObject::tr("Depth: %1\n").arg(bh.bitsPixel());
00141 return st;
00142 }
00143
00144 QString BmpSlave::fullImageInfo( const QString& str) {
00145 QString st = "<qt>";
00146 BmpHeader bh(str);
00147 if (!bh.isBmp()) {
00148 st.append("No bmp file");
00149 st.append( "</qt>" );
00150 return st;
00151 }
00152 QSize isize = bh.imageSize();
00153 st+=QObject::tr("Dimensions: %1 x %2\n").arg(isize.width()).arg(isize.height());
00154 st+=QObject::tr("Size: %1\n").arg(bh.Size());
00155 st+=QObject::tr("Compression: %1\n").arg(bh.imageCompression());
00156 if (bh.isCompressed()) {
00157 st+=QObject::tr("Compressed size: %1").arg(bh.compressedSize());
00158 }
00159 st+=QObject::tr("Depth: %1\n").arg(bh.bitsPixel());
00160 st+=QObject::tr("used colors: %1\n").arg(bh.ColorsUsed());
00161 st+=QObject::tr("Resolution: %1 x %2\n").arg(bh.XPix()).arg(bh.YPix());
00162 st.append( "</qt>" );
00163 return st;
00164 }
00165
00166 QPixmap BmpSlave::pixmap(const QString& path, int width, int height ) {
00167 static QImage img;
00168 img.load( path );
00169 if ( img.isNull() ) {
00170 QPixmap pix;
00171 return pix;
00172 }
00173
00174 return ThumbNailTool::scaleImage( img, width,height );
00175 }