MWAWPictBitmap.hxx
Go to the documentation of this file.
00001 /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
00002 
00003 /* libmwaw
00004 * Version: MPL 2.0 / LGPLv2+
00005 *
00006 * The contents of this file are subject to the Mozilla Public License Version
00007 * 2.0 (the "License"); you may not use this file except in compliance with
00008 * the License or as specified alternatively below. You may obtain a copy of
00009 * the License at http://www.mozilla.org/MPL/
00010 *
00011 * Software distributed under the License is distributed on an "AS IS" basis,
00012 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013 * for the specific language governing rights and limitations under the
00014 * License.
00015 *
00016 * Major Contributor(s):
00017 * Copyright (C) 2002 William Lachance (wrlach@gmail.com)
00018 * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
00019 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
00020 * Copyright (C) 2006, 2007 Andrew Ziem
00021 * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
00022 *
00023 *
00024 * All Rights Reserved.
00025 *
00026 * For minor contributions see the git repository.
00027 *
00028 * Alternatively, the contents of this file may be used under the terms of
00029 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
00030 * in which case the provisions of the LGPLv2+ are applicable
00031 * instead of those above.
00032 */
00033 
00034 /* This header contains code specific to some bitmap
00035  */
00036 
00037 #ifndef MWAW_PICT_BITMAP
00038 #  define MWAW_PICT_BITMAP
00039 
00040 #include <assert.h>
00041 
00042 #include <vector>
00043 
00044 #include "libmwaw_internal.hxx"
00045 #include "MWAWDebug.hxx"
00046 #include "MWAWPict.hxx"
00047 
00049 //
00050 //   Some container
00051 //
00053 
00055 template <class T> class MWAWPictBitmapContainer
00056 {
00057 public:
00059   MWAWPictBitmapContainer(MWAWVec2i const &sz) : m_size(sz), m_data(0L)
00060   {
00061     if (m_size[0]*m_size[1] == 0) return;
00062     m_data = new T[size_t(m_size[0]*m_size[1])];
00063     std::uninitialized_fill_n(m_data, m_size[0] * m_size[1], T());
00064   }
00066   virtual ~MWAWPictBitmapContainer()
00067   {
00068     if (m_data) delete [] m_data;
00069   }
00070 
00072   bool ok() const
00073   {
00074     return (m_data != 0L);
00075   }
00076 
00078   int cmp(MWAWPictBitmapContainer<T> const &orig) const
00079   {
00080     int diff = m_size.cmpY(orig.m_size);
00081     if (diff) return diff;
00082     if (!m_data) return orig.m_data ? 1 : 0;
00083     if (!orig.m_data) return -1;
00084     for (int i=0; i < m_size[0]*m_size[1]; i++) {
00085       if (m_data[i] < orig.m_data[i]) return -1;
00086       if (m_data[i] > orig.m_data[i]) return 1;
00087     }
00088     return 0;
00089   }
00091   MWAWVec2i const &size() const
00092   {
00093     return m_size;
00094   }
00096   int numRows() const
00097   {
00098     return m_size[0];
00099   }
00101   int numColumns() const
00102   {
00103     return m_size[1];
00104   }
00105 
00107   T const &get(int i, int j) const
00108   {
00109     if (m_data == 0L || i<0 || i >= m_size[0] || j<0 || j >= m_size[1])
00110       throw libmwaw::GenericException();
00111     return m_data[i+m_size[0]*j];
00112   }
00114   T const *getRow(int j) const
00115   {
00116     if (m_data == 0L || j<0 || j >= m_size[1])
00117       throw libmwaw::GenericException();
00118     return m_data+m_size[0]*j;
00119   }
00120 
00122   void set(int i, int j, T const &v)
00123   {
00124     if (m_data == 0L || i<0 || i >= m_size[0] || j<0 || j >= m_size[1]) {
00125       MWAW_DEBUG_MSG(("MWAWPictBitmapContainer::set: call with bad coordinate %d %d\n", i, j));
00126       return;
00127     }
00128     m_data[i+j*m_size[0]] = v;
00129   }
00130 
00132   template <class U>
00133   void setRow(int j, U const *val)
00134   {
00135     if (m_data == 0L || j<0 || j >= m_size[1]) {
00136       MWAW_DEBUG_MSG(("MWAWPictBitmapContainer::setRow: call with bad coordinate %d\n", j));
00137       return;
00138     }
00139     for (int i = 0, ind=j*m_size[0]; i < m_size[0]; i++, ind++) m_data[ind] = T(val[i]);
00140   }
00141 
00143   template <class U>
00144   void setColumn(int i, U const *val)
00145   {
00146     if (m_data == 0L || i<0 || i >= m_size[0]) {
00147       MWAW_DEBUG_MSG(("MWAWPictBitmapContainer::setColumn: call with bad coordinate %d\n", i));
00148       return;
00149     }
00150     for (int j = 0, ind=i; j < m_size[1]; j++, ind+=m_size[0]) m_data[ind] = T(val[i]);
00151   }
00152 
00153 private:
00154   MWAWPictBitmapContainer(MWAWPictBitmapContainer const &orig);
00155   MWAWPictBitmapContainer &operator=(MWAWPictBitmapContainer const &orig);
00156 protected:
00158   MWAWVec2i m_size;
00160   T *m_data;
00161 };
00162 
00164 class MWAWPictBitmapContainerBool : public MWAWPictBitmapContainer<bool>
00165 {
00166 public:
00168   MWAWPictBitmapContainerBool(MWAWVec2i const &sz) : MWAWPictBitmapContainer<bool>(sz) {}
00169 
00171   int cmp(MWAWPictBitmapContainerBool const &orig) const
00172   {
00173     int diff = m_size.cmpY(orig.m_size);
00174     if (diff) return diff;
00175     if (!m_data) return orig.m_data ? 1 : 0;
00176     if (!orig.m_data) return -1;
00177     for (int i=0; i < m_size[0]*m_size[1]; i++) {
00178       if (m_data[i] == orig.m_data[i]) continue;
00179       return m_data[i] ? 1 : -1;
00180     }
00181     return 0;
00182   }
00183 
00185   void setRowPacked(int j, unsigned char const *val)
00186   {
00187     if (m_data == 0L || j<0 || j >= m_size[1]) {
00188       MWAW_DEBUG_MSG(("MWAWPictBitmapContainerBool::setRowPacked: call with bad coordinate %d\n", j));
00189       return;
00190     }
00191     for (int i = 0, ind = j*m_size[0]; i < m_size[0];) {
00192       unsigned char v = *(val++);
00193       unsigned char mask = 0x80;
00194       for (int p = 0; p < 8 && i < m_size[0]; i++, p++, ind++) {
00195         m_data[ind] = ((v&mask) != 0);
00196         mask = (unsigned char)(mask >> 1);
00197       }
00198     }
00199   }
00200 };
00201 
00203 class MWAWPictBitmap : public MWAWPict
00204 {
00205 public:
00207   enum SubType { BW, Indexed, Color };
00209   virtual Type getType() const
00210   {
00211     return MWAWPict::Bitmap;
00212   }
00214   virtual SubType getSubType() const = 0;
00215 
00217   virtual bool getBinary(librevenge::RVNGBinaryData &res, std::string &s) const
00218   {
00219     if (!valid()) return false;
00220 
00221     s = "image/pict";
00222     createFileData(res);
00223     return true;
00224   }
00225 
00227   virtual bool valid() const
00228   {
00229     return false;
00230   }
00231 
00234   virtual int cmp(MWAWPict const &a) const
00235   {
00236     int diff = MWAWPict::cmp(a);
00237     if (diff) return diff;
00238     MWAWPictBitmap const &aPict = static_cast<MWAWPictBitmap const &>(a);
00239 
00240     // the type
00241     diff = getSubType() - aPict.getSubType();
00242     if (diff) return (diff < 0) ? -1 : 1;
00243 
00244     return 0;
00245   }
00246 
00247 protected:
00249   virtual bool createFileData(librevenge::RVNGBinaryData &result) const = 0;
00250 
00252   MWAWPictBitmap(MWAWVec2i const &sz)
00253   {
00254     setBdBox(MWAWBox2f(MWAWVec2f(0,0), sz));
00255   }
00256 };
00257 
00259 class MWAWPictBitmapBW : public MWAWPictBitmap
00260 {
00261 public:
00263   virtual SubType getSubType() const
00264   {
00265     return BW;
00266   }
00267 
00270   virtual int cmp(MWAWPict const &a) const
00271   {
00272     int diff = MWAWPictBitmap::cmp(a);
00273     if (diff) return diff;
00274     MWAWPictBitmapBW const &aPict = static_cast<MWAWPictBitmapBW const &>(a);
00275 
00276     return m_data.cmp(aPict.m_data);
00277   }
00278 
00280   virtual bool valid() const
00281   {
00282     return m_data.ok();
00283   }
00284 
00286   MWAWPictBitmapBW(MWAWVec2i const &sz) : MWAWPictBitmap(sz), m_data(sz) { }
00287 
00289   MWAWVec2i const &size() const
00290   {
00291     return m_data.size();
00292   }
00294   int numRows() const
00295   {
00296     return m_data.numRows();
00297   }
00299   int numColumns() const
00300   {
00301     return m_data.numColumns();
00302   }
00304   bool get(int i, int j) const
00305   {
00306     return m_data.get(i,j);
00307   }
00309   bool const *getRow(int j) const
00310   {
00311     return m_data.getRow(j);
00312   }
00314   void set(int i, int j, bool v)
00315   {
00316     m_data.set(i,j, v);
00317   }
00319   void setRow(int j, bool const *val)
00320   {
00321     m_data.setRow(j, val);
00322   }
00324   void setRowPacked(int j, unsigned char const *val)
00325   {
00326     m_data.setRowPacked(j, val);
00327   }
00329   void setColumn(int i, bool const *val)
00330   {
00331     m_data.setColumn(i, val);
00332   }
00333 
00334 protected:
00336   virtual bool createFileData(librevenge::RVNGBinaryData &result) const;
00337 
00339   MWAWPictBitmapContainerBool m_data;
00340 };
00341 
00343 class MWAWPictBitmapIndexed : public MWAWPictBitmap
00344 {
00345 public:
00347   virtual SubType getSubType() const
00348   {
00349     return Indexed;
00350   }
00351 
00354   virtual int cmp(MWAWPict const &a) const
00355   {
00356     int diff = MWAWPictBitmap::cmp(a);
00357     if (diff) return diff;
00358     MWAWPictBitmapIndexed const &aPict = static_cast<MWAWPictBitmapIndexed const &>(a);
00359 
00360     diff=int(m_colors.size())-int(aPict.m_colors.size());
00361     if (diff) return (diff < 0) ? -1 : 1;
00362     for (size_t c=0; c < m_colors.size(); c++) {
00363       if (m_colors[c] < aPict.m_colors[c])
00364         return 1;
00365       if (m_colors[c] > aPict.m_colors[c])
00366         return -1;
00367     }
00368     return m_data.cmp(aPict.m_data);
00369   }
00370 
00372   virtual bool valid() const
00373   {
00374     return m_data.ok();
00375   }
00376 
00378   MWAWPictBitmapIndexed(MWAWVec2i const &sz) : MWAWPictBitmap(sz), m_data(sz), m_colors() { }
00379 
00381   MWAWVec2i const &size() const
00382   {
00383     return m_data.size();
00384   }
00386   int numRows() const
00387   {
00388     return m_data.numRows();
00389   }
00391   int numColumns() const
00392   {
00393     return m_data.numColumns();
00394   }
00396   int get(int i, int j) const
00397   {
00398     return m_data.get(i,j);
00399   }
00401   int const *getRow(int j) const
00402   {
00403     return m_data.getRow(j);
00404   }
00405 
00407   void set(int i, int j, int v)
00408   {
00409     m_data.set(i,j, v);
00410   }
00412   template <class U> void setRow(int j, U const *val)
00413   {
00414     m_data.setRow(j, val);
00415   }
00417   template <class U> void setColumn(int i, U const *val)
00418   {
00419     m_data.setColumn(i, val);
00420   }
00421 
00423   std::vector<MWAWColor> const &getColors() const
00424   {
00425     return m_colors;
00426   }
00428   void setColors(std::vector<MWAWColor> const &cols)
00429   {
00430     m_colors = cols;
00431   }
00432 
00433 protected:
00435   virtual bool createFileData(librevenge::RVNGBinaryData &result) const;
00436 
00438   MWAWPictBitmapContainer<int> m_data;
00440   std::vector<MWAWColor> m_colors;
00441 };
00442 
00450 class MWAWPictBitmapColor : public MWAWPictBitmap
00451 {
00452 public:
00454   virtual SubType getSubType() const
00455   {
00456     return Indexed;
00457   }
00458 
00461   virtual int cmp(MWAWPict const &a) const
00462   {
00463     int diff = MWAWPictBitmap::cmp(a);
00464     if (diff) return diff;
00465     MWAWPictBitmapColor const &aPict = static_cast<MWAWPictBitmapColor const &>(a);
00466 
00467     return m_data.cmp(aPict.m_data);
00468   }
00469 
00471   virtual bool valid() const
00472   {
00473     return m_data.ok();
00474   }
00475 
00477   MWAWPictBitmapColor(MWAWVec2i const &sz, bool useAlphaChannel=false) : MWAWPictBitmap(sz), m_data(sz), m_hasAlpha(useAlphaChannel) { }
00478 
00480   MWAWVec2i const &size() const
00481   {
00482     return m_data.size();
00483   }
00485   int numRows() const
00486   {
00487     return m_data.numRows();
00488   }
00490   int numColumns() const
00491   {
00492     return m_data.numColumns();
00493   }
00495   MWAWColor get(int i, int j) const
00496   {
00497     return m_data.get(i,j);
00498   }
00500   MWAWColor const *getRow(int j) const
00501   {
00502     return m_data.getRow(j);
00503   }
00504 
00506   void set(int i, int j, MWAWColor const &v)
00507   {
00508     m_data.set(i,j, v);
00509   }
00511   void setRow(int j, MWAWColor const *val)
00512   {
00513     m_data.setRow(j, val);
00514   }
00516   void setColumn(int i, MWAWColor const *val)
00517   {
00518     m_data.setColumn(i, val);
00519   }
00520 
00521 protected:
00523   virtual bool createFileData(librevenge::RVNGBinaryData &result) const;
00524 
00526   MWAWPictBitmapContainer<MWAWColor> m_data;
00527 
00529   bool m_hasAlpha;
00530 };
00531 #endif
00532 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: