~zorba-coders/zorba/feature-setvar-typed--graphviz

« back to all changes in this revision

Viewing changes to src/com/zorba-xquery/www/modules/image/image_commons/image_function.cpp

  • Committer: ceejatec
  • Date: 2011-07-09 08:55:59 UTC
  • Revision ID: svn-v4:8046edc3-af21-0410-8661-ec7318497eea:modules/image/trunk:11192
Added EXTRA_SOURCES arg to DECLARE_ZORBA_MODULE(); use it in image module.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2006-2008 The FLWOR Foundation.
 
3
 * 
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at
 
7
 * 
 
8
 * http://www.apache.org/licenses/LICENSE-2.0
 
9
 * 
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
#include <sstream>
 
18
#include <zorba/zorba.h>
 
19
#include <Magick++.h>
 
20
#include <zorba/base64.h>
 
21
#include <zorba/error_list.h>
 
22
#include <zorba/user_exception.h>
 
23
#include <zorba/empty_sequence.h>
 
24
#include <zorba/singleton_item_sequence.h>
 
25
#include "image_function.h"
 
26
#include "image_module.h"
 
27
 
 
28
namespace zorba {  namespace imagemodule {
 
29
 
 
30
ImageFunction::ImageFunction(const ImageModule* aModule)
 
31
        : theModule(aModule)
 
32
{
 
33
}
 
34
 
 
35
ImageFunction::~ImageFunction()
 
36
{
 
37
}
 
38
 
 
39
String
 
40
ImageFunction::getURI() const
 
41
{
 
42
        return theModule->getURI();
 
43
}
 
44
void
 
45
ImageFunction::throwError(
 
46
        const std::string aErrorMessage,
 
47
        const Error& aErrorType)
 
48
{
 
49
  throw USER_EXCEPTION(aErrorType, aErrorMessage.c_str() );
 
50
}
 
51
 
 
52
void
 
53
ImageFunction::throwImageError(const DynamicContext* aDynamicContext, const char *aMessage) {
 
54
  std::stringstream lErrorMessage;
 
55
  // constuct error QName
 
56
  String lNamespace = "http://www.zorba-xquery.com/modules/image/error";
 
57
  String lLocalname = "IM001";
 
58
  Item lQName;
 
59
  Iterator_t lDummyIterator;
 
60
  aDynamicContext->getVariable(lNamespace, lLocalname, lQName, lDummyIterator); 
 
61
  // if we have zero length image, then tell the user so
 
62
  if (std::string(aMessage).find("zero-length") != std::string::npos) {
 
63
    lErrorMessage << "The passed xs:base64Binary seems to be empty.";
 
64
    USER_EXCEPTION(lQName, lErrorMessage.str());
 
65
  } else {
 
66
    lErrorMessage << "Error while processing xs:base64Binary. Possibly not a valid image type.";
 
67
    USER_EXCEPTION(lQName, lErrorMessage.str());
 
68
  }
 
69
}
 
70
 
 
71
void 
 
72
ImageFunction::throwErrorWithQName (const DynamicContext* aDynamicContext, const String& aLocalName, const String& aMessage) {
 
73
   String lNamespace = "http://www.zorba-xquery.com/modules/image/error";
 
74
   Item lQName;
 
75
   Iterator_t lDummyIterator;
 
76
   aDynamicContext->getVariable(lNamespace, aLocalName, lQName, lDummyIterator);
 
77
   USER_EXCEPTION(lQName, aMessage); 
 
78
}
 
79
 
 
80
void
 
81
ImageFunction::checkIfItemIsNull(Item& aItem) {
 
82
  if (aItem.isNull()) {
 
83
        std::stringstream lErrorMessage;
 
84
        lErrorMessage << "Error while building the base64binary item. ";
 
85
        throwError(lErrorMessage.str(), err::XPST0083);
 
86
  }
 
87
}
 
88
String
 
89
ImageFunction::getOneStringArg(
 
90
    const ExternalFunction::Arguments_t& aArgs,
 
91
    int aPos)
 
92
{
 
93
  Item lItem;
 
94
  Iterator_t  arg_iter = aArgs[aPos]->getIterator();
 
95
  arg_iter->open();
 
96
  if (!arg_iter->next(lItem)) {
 
97
    std::stringstream lErrorMessage;
 
98
    lErrorMessage << "An empty-sequence is not allowed as "
 
99
                  << aPos << ". parameter.";
 
100
    throwError(lErrorMessage.str(), err::XPTY0004);
 
101
  }
 
102
  zorba::String lTmpString = lItem.getStringValue();
 
103
  if (arg_iter->next(lItem)) {
 
104
    std::stringstream lErrorMessage;
 
105
    lErrorMessage << "A sequence of more then one item is not allowed as "
 
106
                  << aPos << ". parameter.";
 
107
    throwError(lErrorMessage.str(), err::XPTY0004);
 
108
  }
 
109
  arg_iter->close();
 
110
  return lTmpString;
 
111
}
 
112
 
 
113
bool
 
114
ImageFunction::getOneBoolArg(
 
115
    const ExternalFunction::Arguments_t& aArgs,
 
116
    int aPos)
 
117
{
 
118
  Item lItem;
 
119
  Iterator_t  arg_iter = aArgs[aPos]->getIterator();
 
120
  arg_iter->open();
 
121
  if (!arg_iter->next(lItem)) {
 
122
    std::stringstream lErrorMessage;
 
123
    lErrorMessage << "An empty-sequence is not allowed as "
 
124
                  << aPos << ". parameter.";
 
125
    throwError(lErrorMessage.str(), err::XPTY0004);
 
126
  }
 
127
  bool lTmpBool = lItem.getBooleanValue();
 
128
  if (arg_iter->next(lItem)) {
 
129
    std::stringstream lErrorMessage;
 
130
    lErrorMessage << "A sequence of more then one item is not allowed as "
 
131
                  << aPos << ". parameter.";
 
132
    throwError(lErrorMessage.str(), err::XPTY0004);
 
133
  }
 
134
  arg_iter->close();
 
135
  return lTmpBool;
 
136
}
 
137
 
 
138
void
 
139
ImageFunction::getOneColorArg(
 
140
     const ExternalFunction::Arguments_t& aArgs,
 
141
     int aPos,
 
142
     Magick::ColorRGB& aColor)
 
143
{
 
144
  Item lItem;
 
145
  Iterator_t  arg_iter = aArgs[aPos]->getIterator();
 
146
  arg_iter->open();
 
147
  if (!arg_iter->next(lItem)) {
 
148
    aColor = Magick::ColorRGB(0.0,0.0,0.0);
 
149
    return;
 
150
  }
 
151
  zorba::String lTmpString = lItem.getStringValue();
 
152
  if (arg_iter->next(lItem)) {
 
153
    std::stringstream lErrorMessage;
 
154
    lErrorMessage << "A sequence of more then one item is not allowed as "
 
155
                  << aPos << ". parameter.";
 
156
    throwError(lErrorMessage.str(), err::XPTY0004);
 
157
  }
 
158
  arg_iter->close();
 
159
  getColorFromString(lTmpString, aColor);
 
160
}
 
161
 
 
162
 
 
163
 
 
164
void 
 
165
ImageFunction::getColorFromString(const String aColorString,
 
166
                                  Magick::ColorRGB& aColor)
 
167
{
 
168
  int lRed = 0;
 
169
  int lGreen = 0;
 
170
  int lBlue = 0;
 
171
  sscanf(aColorString.substr(1,2).c_str(), "%x", &lRed);
 
172
  sscanf(aColorString.substr(3,2).c_str(), "%x", &lGreen);
 
173
  sscanf(aColorString.substr(5,2).c_str(), "%x", &lBlue);
 
174
  aColor = Magick::ColorRGB((double)lRed/(double)255.0, (double)lGreen/(double)255.0, (double)lBlue/(double)255.0);
 
175
 
 
176
}
 
177
 
 
178
int
 
179
ImageFunction::getOneIntArg(
 
180
    const ExternalFunction::Arguments_t& aArgs,
 
181
    int aPos)
 
182
{
 
183
  Item lItem;
 
184
  Iterator_t  arg_iter = aArgs[aPos]->getIterator();
 
185
  arg_iter->open();
 
186
  if (!arg_iter->next(lItem)) {
 
187
    std::stringstream lErrorMessage;
 
188
    lErrorMessage << "An empty-sequence is not allowed as "
 
189
                  << (aPos + 1)  << ". parameter.";
 
190
    throwError(lErrorMessage.str(), err::XPTY0004);
 
191
  }
 
192
  int lTmpInt = (int) lItem.getIntValue();
 
193
  if (arg_iter->next(lItem)) {
 
194
    std::stringstream lErrorMessage;
 
195
    lErrorMessage << "A sequence of more then one item is not allowed as "
 
196
                  << (aPos + 1)  << ". parameter.";
 
197
    throwError(lErrorMessage.str(), err::XPTY0004);
 
198
  }
 
199
  arg_iter->close();
 
200
  return lTmpInt;
 
201
 
 
202
}
 
203
 
 
204
unsigned int
 
205
ImageFunction::getOneUnsignedIntArg(const ExternalFunction::Arguments_t& aArgs,
 
206
                                    int aPos)
 
207
{
 
208
  Item lItem;
 
209
  Iterator_t  arg_iter = aArgs[aPos]->getIterator();
 
210
  arg_iter->open();
 
211
  if (!arg_iter->next(lItem)) {
 
212
    std::stringstream lErrorMessage;
 
213
    lErrorMessage << "An empty-sequence is not allowed as "
 
214
                  << (aPos + 1) << ". parameter.";
 
215
    throwError(lErrorMessage.str(), err::XPTY0004);
 
216
  }
 
217
  unsigned int lTmpInt = lItem.getUnsignedIntValue();
 
218
  if (arg_iter->next(lItem)) {
 
219
    std::stringstream lErrorMessage;
 
220
    lErrorMessage << "A sequence of more then one item is not allowed as "
 
221
                  << (aPos + 1) << ". parameter.";
 
222
    throwError(lErrorMessage.str(), err::XPTY0004);
 
223
  }
 
224
  arg_iter->close();
 
225
  return lTmpInt;
 
226
 
 
227
}
 
228
 
 
229
double
 
230
ImageFunction::getOneDoubleArg(
 
231
    const ExternalFunction::Arguments_t& aArgs,
 
232
    int aPos)
 
233
{
 
234
  Item lItem;
 
235
  Iterator_t  arg_iter = aArgs[aPos]->getIterator();
 
236
  arg_iter->open();
 
237
  if (!arg_iter->next(lItem)) {
 
238
    std::stringstream lErrorMessage;
 
239
    lErrorMessage << "An empty-sequence is not allowed as "
 
240
                  << (aPos + 1)  << ". parameter.";
 
241
    throwError(lErrorMessage.str(), err::XPTY0004);
 
242
  }
 
243
  double lTmpDouble =  lItem.getDoubleValue();
 
244
  if (arg_iter->next(lItem)) {
 
245
    std::stringstream lErrorMessage;
 
246
    lErrorMessage << "A sequence of more then one item is not allowed as "
 
247
                  << (aPos + 1) << ". parameter.";
 
248
    throwError(lErrorMessage.str(), err::XPTY0004);
 
249
  }
 
250
  arg_iter->close();
 
251
  return lTmpDouble;
 
252
}
 
253
 
 
254
 
 
255
String
 
256
ImageFunction::getEncodedStringFromBlob(Magick::Blob& aBlob) {
 
257
 
 
258
    std::string lStringOfBlobContent((char *)aBlob.data(), aBlob.length());
 
259
    String lZorbaStringOfBlobContent(lStringOfBlobContent);
 
260
 
 
261
    return zorba::encoding::Base64::encode(lZorbaStringOfBlobContent);
 
262
}
 
263
 
 
264
String
 
265
ImageFunction::getEncodedStringFromImage(const DynamicContext* aDynamicContext, Magick::Image& aImage) {
 
266
  Magick::Blob lBlob;
 
267
  try {
 
268
    aImage.write(&lBlob);
 
269
  } catch (Magick::Exception& error) {
 
270
    throwImageError(aDynamicContext, error.what());
 
271
  }
 
272
  return getEncodedStringFromBlob(lBlob);
 
273
}
 
274
 
 
275
 
 
276
 
 
277
 
 
278
 
 
279
void
 
280
ImageFunction::getOneImageArg(const DynamicContext* aDynamicContext,
 
281
                              const ExternalFunction::Arguments_t& aArgs,
 
282
                              int aPos,
 
283
                              Magick::Image& aImage)
 
284
{
 
285
  String lData;
 
286
  lData = getOneStringArg(aArgs, aPos);
 
287
  getImageFromString(aDynamicContext, lData, aImage);
 
288
}
 
289
 
 
290
void
 
291
ImageFunction::getOneOrMoreImageArg(const DynamicContext* aDynamicContext,
 
292
                                     const ExternalFunction::Arguments_t& aArgs,
 
293
                                     int aPos,
 
294
                                     std::list<Magick::Image>& aImages,
 
295
                                     const unsigned int aDelay,
 
296
                                     const unsigned int aIterations)
 
297
 
 
298
{
 
299
  Item lItem;
 
300
  // make sure there is at least one item at the position
 
301
  Iterator_t  arg_iter = aArgs[aPos]->getIterator();
 
302
  arg_iter->open();
 
303
  if (!arg_iter->next(lItem)) {
 
304
    throwError("An empty sequence is not allowed as first parameter", err::XPTY0004);
 
305
  }
 
306
 
 
307
  Magick::Image lFirstImage;
 
308
  ImageFunction::getImageFromString(aDynamicContext, lItem.getStringValue(), lFirstImage);
 
309
  lFirstImage.animationDelay(aDelay);
 
310
  lFirstImage.animationIterations(aIterations);
 
311
  lFirstImage.gifDisposeMethod(3);
 
312
  aImages.push_back(lFirstImage);
 
313
  Magick::Image lTempImage;
 
314
  while (arg_iter->next(lItem)) {
 
315
    getImageFromString(aDynamicContext, lItem.getStringValue(), lTempImage);
 
316
    aImages.push_back(lTempImage);
 
317
  }
 
318
  arg_iter->close();
 
319
 
 
320
}
 
321
 
 
322
void
 
323
ImageFunction::getImageFromString(const DynamicContext* aDynamicContext, const String aString, Magick::Image& aImage) {
 
324
 
 
325
  String lDecodedContent = zorba::encoding::Base64::decode(aString);
 
326
  Magick::Blob lBlob(lDecodedContent.c_str(), lDecodedContent.size());
 
327
 
 
328
  try {
 
329
    aImage.read(lBlob);
 
330
 
 
331
  } catch (Magick::Exception &error)   {
 
332
      throwImageError(aDynamicContext, error.what());
 
333
  }
 
334
}
 
335
 
 
336
 
 
337
bool
 
338
ImageFunction::getAntiAliasingArg(
 
339
    const ExternalFunction::Arguments_t& aArgs,
 
340
    int aPos)
 
341
{
 
342
  Item lItem;
 
343
  Iterator_t  arg_iter = aArgs[aPos]->getIterator();
 
344
  arg_iter->open();
 
345
  if (!arg_iter->next(lItem)) {
 
346
    return false;
 
347
  }
 
348
  bool lTmpBool = lItem.getBooleanValue();
 
349
  if (arg_iter->next(lItem)) {
 
350
    std::stringstream lErrorMessage;
 
351
    lErrorMessage << "A sequence of more then one item is not allowed as "
 
352
                  << (aPos + 1) << ". parameter.";
 
353
    throwError(lErrorMessage.str(), err::XPTY0004);
 
354
  }
 
355
  arg_iter->close();
 
356
  return lTmpBool;
 
357
}
 
358
 
 
359
double
 
360
ImageFunction::getStrokeWidthArg(const ExternalFunction::Arguments_t& aArgs,
 
361
                                 int aPos)
 
362
{
 
363
  Item lItem;
 
364
  Iterator_t  arg_iter = aArgs[aPos]->getIterator();
 
365
  arg_iter->open();
 
366
  if (!arg_iter->next(lItem)) {
 
367
    return 1;
 
368
  }
 
369
  double lTmpDouble = lItem.getDoubleValue();
 
370
  if (arg_iter->next(lItem)) {
 
371
    std::stringstream lErrorMessage;
 
372
    lErrorMessage << "A sequence of more then one item is not allowed as "
 
373
                  << (aPos + 1) << ". parameter.";
 
374
    throwError(lErrorMessage.str(), err::XPTY0004);
 
375
  }
 
376
  arg_iter->close();
 
377
  return lTmpDouble;
 
378
}
 
379
 
 
380
 
 
381
 
 
382
} // imagemodule 
 
383
} // zorba