1 /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
2 
3 /* libmwaw
4 * Version: MPL 2.0 / LGPLv2+
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 2.0 (the "License"); you may not use this file except in compliance with
8 * the License or as specified alternatively below. You may obtain a copy of
9 * the License at http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * Major Contributor(s):
17 * Copyright (C) 2002 William Lachance (wrlach@gmail.com)
18 * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
19 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
20 * Copyright (C) 2006, 2007 Andrew Ziem
21 * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
22 *
23 *
24 * All Rights Reserved.
25 *
26 * For minor contributions see the git repository.
27 *
28 * Alternatively, the contents of this file may be used under the terms of
29 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
30 * in which case the provisions of the LGPLv2+ are applicable
31 * instead of those above.
32 */
33 
34 /* This header contains code specific to a pict which can be stored in a
35  *      librevenge::RVNGBinaryData, this includes :
36  *         - the mac Pict format (in MWAWPictMac)
37  *         - some old data names db3
38  *         - some potential short data file
39  */
40 
41 #ifndef MWAW_PICT_DATA
42 #  define MWAW_PICT_DATA
43 
44 #  include <ostream>
45 
46 #  include <librevenge/librevenge.h>
47 
48 #  include "libmwaw_internal.hxx"
49 #  include "MWAWPict.hxx"
50 
51 /** \brief an abstract class which defines basic formated picture ( Apple� Pict, DB3, ...) */
52 class MWAWPictData : public MWAWPict
53 {
54 public:
55   //! the picture subtype
56   enum SubType { PictMac, DB3, Unknown };
57   //! destructor
58   ~MWAWPictData() override;
59   //! returns the picture type
getType() const60   Type getType() const override
61   {
62     return MWAWPict::PictData;
63   }
64   //! returns the picture subtype
65   virtual SubType getSubType() const = 0;
66 
67   //! returns the final picture
getBinary(MWAWEmbeddedObject & picture) const68   bool getBinary(MWAWEmbeddedObject &picture) const override
69   {
70     if (!valid() || isEmpty()) return false;
71 
72     librevenge::RVNGBinaryData data;
73     createFileData(m_data, data);
74     picture=MWAWEmbeddedObject(data, "image/pict");
75     return true;
76   }
77 
78   //! returns true if we are relatively sure that the data are correct
sure() const79   virtual bool sure() const
80   {
81     return getSubType() != Unknown;
82   }
83 
84   //! returns true if the picture is valid
valid() const85   virtual bool valid() const
86   {
87     return false;
88   }
89 
90   //! returns true if the picture is valid and has size 0 or contains no data
isEmpty() const91   bool isEmpty() const
92   {
93     return m_empty;
94   }
95 
96   /** checks if the data pointed by input is known
97      - if not return MWAW_R_BAD
98      - if true
99      - fills box if possible, if not set box=MWAWBox2f() */
check(MWAWInputStreamPtr const & input,int size,MWAWBox2f & box)100   static ReadResult check(MWAWInputStreamPtr const &input, int size, MWAWBox2f &box)
101   {
102     return checkOrGet(input, size, box, nullptr);
103   }
104 
105   /** checks if the data pointed by input is known
106    * - if not or if the pict is empty, returns 0L
107    * - if not returns a container of picture */
get(MWAWInputStreamPtr const & input,int size)108   static MWAWPictData *get(MWAWInputStreamPtr const &input, int size)
109   {
110     MWAWPictData *res = nullptr;
111     MWAWBox2f box;
112     if (checkOrGet(input, size, box, &res) == MWAW_R_BAD) return nullptr;
113     if (res) { // if the bdbox is good, we set it
114       MWAWVec2f sz = box.size();
115       if (sz.x()>0 && sz.y()>0) res->setBdBox(box);
116     }
117     return res;
118   }
119 
120   /** a virtual function used to obtain a strict order,
121    * must be redefined in the subs class */
cmp(MWAWPict const & a) const122   int cmp(MWAWPict const &a) const override
123   {
124     int diff = MWAWPict::cmp(a);
125     if (diff) return diff;
126     auto const &aPict = static_cast<MWAWPictData const &>(a);
127 
128     diff = static_cast<int>(m_empty) - static_cast<int>(aPict.m_empty);
129     if (diff) return (diff < 0) ? -1 : 1;
130     else if (m_empty) // both empty
131       return 0;
132     // the type
133     diff = getSubType() - aPict.getSubType();
134     if (diff) return (diff < 0) ? -1 : 1;
135 
136     if (m_data.size() < aPict.m_data.size())
137       return 1;
138     if (m_data.size() > aPict.m_data.size())
139       return -1;
140     unsigned char const *data=m_data.getDataBuffer();
141     unsigned char const *aData=m_data.getDataBuffer();
142     if (!data || !aData) return 0; // must only appear if the two buffers are empty
143     for (unsigned long c=0; c < m_data.size(); c++, data++, aData++) {
144       if (*data < *aData) return -1;
145       if (*data > *aData) return 1;
146     }
147     return 0;
148   }
149 
150 protected:
151   /** a file pict can be created from the data pict by adding a header with size 512,
152    * this function do this conversion needed to return the final picture */
153   static bool createFileData(librevenge::RVNGBinaryData const &orig, librevenge::RVNGBinaryData &result);
154 
155   //! protected constructor: use check to construct a picture
MWAWPictData()156   MWAWPictData()
157     : m_data()
158     , m_empty(false)
159   {
160   }
MWAWPictData(MWAWBox2f &)161   explicit MWAWPictData(MWAWBox2f &)
162     : m_data()
163     , m_empty(false)
164   {
165   }
166 
167   /** \brief checks if the data pointed by input and of given size is a pict
168    * - if not returns MWAW_R_BAD
169    * - if true
170    *    - fills the box size
171    *    - creates a picture if result is given and if the picture is not empty */
172   static ReadResult checkOrGet(MWAWInputStreamPtr input, int size,
173                                MWAWBox2f &box, MWAWPictData **result = nullptr);
174 
175   //! the data size (without the empty header of 512 characters)
176   librevenge::RVNGBinaryData m_data;
177 
178   //! some picture can be valid but empty
179   bool m_empty;
180 };
181 
182 //! a small table file (known by open office)
183 class MWAWPictDB3 final : public MWAWPictData
184 {
185 public:
186   //! destructor
187   ~MWAWPictDB3() final;
188 
189   //! returns the picture subtype
getSubType() const190   SubType getSubType() const final
191   {
192     return DB3;
193   }
194 
195   //! returns true if the picture is valid
valid() const196   bool valid() const final
197   {
198     return m_data.size() != 0;
199   }
200 
201   /** a virtual function used to obtain a strict order,
202   must be redefined in the subs class */
cmp(MWAWPict const & a) const203   int cmp(MWAWPict const &a) const final
204   {
205     return MWAWPictData::cmp(a);
206   }
207 
208 protected:
209 
210   //! protected constructor: uses check to construct a picture
MWAWPictDB3()211   MWAWPictDB3()
212   {
213     m_empty = false;
214   }
215 
216   friend class MWAWPictData;
217   /** \brief checks if the data pointed by input and of given size is a pict
218    * - if not returns MWAW_R_BAD
219    * - if true
220    *    - set empty to true if the picture contains no data
221    *    - creates a picture if result is given and if the picture is not empty */
222   static ReadResult checkOrGet(MWAWInputStreamPtr input, int size, MWAWPictData **result = nullptr);
223 };
224 
225 //! class to store small data which are potentially a picture
226 class MWAWPictDUnknown final : public MWAWPictData
227 {
228 public:
229   //! destructor
230   ~MWAWPictDUnknown() final;
231 
232   //! returns the picture subtype
getSubType() const233   SubType getSubType() const final
234   {
235     return Unknown;
236   }
237 
238   //! returns true if the picture is valid
valid() const239   bool valid() const final
240   {
241     return m_data.size() != 0;
242   }
243 
244   /** a virtual function used to obtain a strict order,
245    * must be redefined in the subs class */
cmp(MWAWPict const & a) const246   int cmp(MWAWPict const &a) const final
247   {
248     return MWAWPictData::cmp(a);
249   }
250 
251 protected:
252 
253   //! protected constructor: uses check to construct a picture
MWAWPictDUnknown()254   MWAWPictDUnknown()
255   {
256     m_empty = false;
257   }
258 
259   friend class MWAWPictData;
260 
261   /** \brief checks if the data pointed by input and of given size is a pict
262    * - if not returns MWAW_R_BAD
263    * - if true
264    *    - set empty to true if the picture contains no data
265    *    - creates a picture if result is given and if the picture is not empty */
266   static ReadResult checkOrGet(MWAWInputStreamPtr input, int size, MWAWPictData **result = nullptr);
267 };
268 
269 #endif
270 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
271