Advertisement
Guest User

TAFF Thingy

a guest
Jan 11th, 2013
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 80.14 KB | None | 0 0
  1. 00001 /***************************************************************************
  2. 00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
  3. 00003  *                           Matthias Hardt, Guido Madaus                  *
  4. 00004  *                                                                         *
  5. 00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
  6. 00006  *                           Stefan Schwarzer & Guido Madaus               *
  7. 00007  *                                                                         *
  8. 00008  *   Copyright (C) 2009-2012 BerLinux Solutions GmbH                       *
  9. 00009  *                                                                         *
  10. 00010  *   Authors:                                                              *
  11. 00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
  12. 00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
  13. 00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
  14. 00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
  15. 00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
  16. 00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
  17. 00017  *                                                                         *
  18. 00018  *   This library is free software; you can redistribute it and/or         *
  19. 00019  *   modify it under the terms of the GNU Lesser General Public            *
  20. 00020  *   License version 2.1 as published by the Free Software Foundation.     *
  21. 00021  *                                                                         *
  22. 00022  *   This library is distributed in the hope that it will be useful,       *
  23. 00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  24. 00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
  25. 00025  *   Lesser General Public License for more details.                       *
  26. 00026  *                                                                         *
  27. 00027  *   You should have received a copy of the GNU Lesser General Public      *
  28. 00028  *   License along with this library; if not, write to the                 *
  29. 00029  *   Free Software Foundation, Inc.,                                       *
  30. 00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
  31. 00031  **************************************************************************/
  32. 00032
  33. 00033 #include "mmstools/mmstafffile.h"
  34. 00034 #include "mmstools/tools.h"
  35. 00035 #include <sys/types.h>
  36. 00036 #include <sys/stat.h>
  37. 00037 #include <unistd.h>
  38. 00038 #include <libxml/parser.h>
  39. 00039 #include <libxml/tree.h>
  40. 00040 #include <cstring>
  41. 00041 #include <iostream>
  42. 00042
  43. 00043 #ifdef __HAVE_PNG__
  44. 00044 #include <png.h>
  45. 00045 #endif
  46. 00046
  47. 00047 #ifdef __HAVE_JPEG__
  48. 00048 #include <csetjmp>
  49. 00049 extern "C" {
  50. 00050 #include <jpeglib.h>
  51. 00051 }
  52. 00052 #endif
  53. 00053
  54. 00054 #ifdef __HAVE_TIFF__
  55. 00055 extern "C" {
  56. 00056 #include <tiffio.h>
  57. 00057 }
  58. 00058 #endif
  59. 00059
  60. 00060 MMSTaffFile::MMSTaffFile(string taff_filename, TAFF_DESCRIPTION *taff_desc,
  61. 00061                          string external_filename, MMSTAFF_EXTERNAL_TYPE external_type,
  62. 00062                          bool ignore_blank_values, bool trace, bool print_warnings,
  63. 00063                          bool force_rewrite_taff, bool auto_rewrite_taff) {
  64. 00064     this->taff_filename = taff_filename;
  65. 00065     this->taff_desc = taff_desc;
  66. 00066     this->taff_buf = NULL;
  67. 00067     this->taff_buf_size = 0;
  68. 00068     this->taff_buf_pos = 0;
  69. 00069     this->loaded = false;
  70. 00070     this->correct_version = false;
  71. 00071     this->external_filename = external_filename;
  72. 00072     this->external_type = external_type;
  73. 00073     this->ignore_blank_values = ignore_blank_values;
  74. 00074     this->trace = trace;
  75. 00075     this->print_warnings = print_warnings;
  76. 00076     this->destination_pixelformat = MMSTAFF_PF_ARGB;
  77. 00077     this->destination_premultiplied = true;
  78. 00078     this->mirror_size = 0;
  79. 00079     this->rotate_180 = false;
  80. 00080     this->correct_version = false;
  81. 00081     this->current_tag = -1;
  82. 00082     this->current_tag_pos = 0;
  83. 00083
  84. 00084     if (!this->taff_desc)
  85. 00085         if (this->external_type == MMSTAFF_EXTERNAL_TYPE_IMAGE)
  86. 00086             this->taff_desc = &mmstaff_image_taff_description;
  87. 00087
  88. 00088     if ((this->taff_filename == "")&&(this->external_filename == ""))
  89. 00089         return;
  90. 00090
  91. 00091     // read the file into taff_buf
  92. 00092     bool ret = false;
  93. 00093     if (!force_rewrite_taff)
  94. 00094         ret = readFile();
  95. 00095     if (!ret)
  96. 00096         // failed or rewrite, try to convert from external_filename
  97. 00097         if ((force_rewrite_taff)||(auto_rewrite_taff)) {
  98. 00098             if (convertExternal2TAFF()) {
  99. 00099                 if (this->taff_filename != "") {
  100. 00100                     // auto read in
  101. 00101                     readFile();
  102. 00102                 }
  103. 00103             }
  104. 00104         }
  105. 00105 }
  106. 00106
  107. 00107 MMSTaffFile::~MMSTaffFile() {
  108. 00108     if (this->taff_buf)
  109. 00109         free(this->taff_buf);
  110. 00110 }
  111. 00111
  112. 00112 bool MMSTaffFile::writeBuffer(MMSFile *mmsfile, void *ptr, size_t *ritems, size_t size, size_t nitems, bool *write_status) {
  113. 00113
  114. 00114     if (mmsfile) {
  115. 00115         // writing to file
  116. 00116         if (!mmsfile->writeBuffer(ptr, ritems, size, nitems)) {
  117. 00117             // error while writing file
  118. 00118             printf("TAFF: Error while writing to file %s\n", mmsfile->getName().c_str());
  119. 00119             if (write_status) *write_status = false;
  120. 00120             return false;
  121. 00121         }
  122. 00122     }
  123. 00123     else {
  124. 00124         // writing to taff_buf
  125. 00125         memcpy(&this->taff_buf[taff_buf_pos], ptr, size * nitems);
  126. 00126         this->taff_buf_pos+= size * nitems;
  127. 00127
  128. 00128         //TODO: check the taff_buf_size and realloc the buffer if taff_buf_size is to small
  129. 00129     }
  130. 00130
  131. 00131     return true;
  132. 00132 }
  133. 00133
  134. 00134 bool MMSTaffFile::postprocessImage(void **buf, int *width, int *height, int *pitch,
  135. 00135                                         int *size, bool *alphachannel) {
  136. 00136
  137. 00137     // should i pre-multiply with alpha channel?
  138. 00138     if (this->destination_premultiplied && (*alphachannel == true)) {
  139. 00139         unsigned int *src = (unsigned int*)*buf;
  140. 00140         for (int i = *width * *height; i > 0; i--) {
  141. 00141             register unsigned int s = *src;
  142. 00142             register unsigned int sa = s >> 24;
  143. 00143             if (sa != 0xff)
  144. 00144                 // source alpha is > 0x00 and < 0xff
  145. 00145                 *src = ((((s & 0x00ff00ff) * sa) >> 8) & 0x00ff00ff) |
  146. 00146                        ((((s & 0x0000ff00) * sa) >> 8) & 0x0000ff00) |
  147. 00147                        ((((s & 0xff000000))));
  148. 00148             src++;
  149. 00149         }
  150. 00150     }
  151. 00151
  152. 00152     // should create a mirror effect?
  153. 00153     if (this->mirror_size > 0) {
  154. 00154         // yes
  155. 00155         unsigned int *dst = (unsigned int*)*buf;
  156. 00156         dst+=*width * *height;
  157. 00157         unsigned int *src = dst - *width;
  158. 00158         unsigned int alpha = 170;
  159. 00159         unsigned int alphaX = 0x050 / this->mirror_size;
  160. 00160         if (0x050 % this->mirror_size >= (this->mirror_size >> 1))
  161. 00161             alphaX++;
  162. 00162         if (alphaX == 0) alphaX = 1;
  163. 00163         for (int i = 0; i < this->mirror_size; i++) {
  164. 00164             for (int j = 0; j < *width; j++) {
  165. 00165                 register unsigned int s = *src;
  166. 00166                 register unsigned int sa = s >> 24;
  167. 00167                 *dst = (s & 0x00ffffff) | (((sa > alpha)?(sa-alpha):0)<<24);
  168. 00168                 dst++;
  169. 00169                 src++;
  170. 00170             }
  171. 00171             src-=(*width) << 1;
  172. 00172             alpha+=alphaX;
  173. 00173         }
  174. 00174
  175. 00175         // set new values
  176. 00176         *height = (*height) + this->mirror_size;
  177. 00177         *size = (*pitch) * (*height);
  178. 00178     }
  179. 00179
  180. 00180     if (this->rotate_180) {
  181. 00181         // rotate the image by 180 degree
  182. 00182         rotateUIntBuffer180((unsigned int*)*buf, *pitch, *width, *height);
  183. 00183     }
  184. 00184
  185. 00185     // have to convert the pixelformat?
  186. 00186     bool has_alpha = false;
  187. 00187     switch (this->destination_pixelformat) {
  188. 00188     case MMSTAFF_PF_ARGB:
  189. 00189         if (*alphachannel) {
  190. 00190             // no convertion, only have to check if we have really an alpha channel
  191. 00191             unsigned int *src = (unsigned int*)*buf;
  192. 00192             for (int i = *width * *height; i > 0; i--) {
  193. 00193                 register unsigned int s = *src;
  194. 00194                 s = s >> 24;
  195. 00195                 if (s != 0xff) has_alpha = true;
  196. 00196                 if (has_alpha) break;
  197. 00197                 src++;
  198. 00198             }
  199. 00199         }
  200. 00200         break;
  201. 00201     case MMSTAFF_PF_AiRGB: {
  202. 00202             // invert the alpha channel
  203. 00203             unsigned int *src = (unsigned int*)*buf;
  204. 00204             for (int i = *width * *height; i > 0; i--) {
  205. 00205                 register unsigned int s = *src;
  206. 00206                 register unsigned int a = s;
  207. 00207                 a = ~a;
  208. 00208                 a = a & 0xff000000;
  209. 00209                 if (a && !has_alpha) has_alpha = true;
  210. 00210                 s = s & 0x00ffffff;
  211. 00211                 s = s | a;
  212. 00212                 *src = s;
  213. 00213                 src++;
  214. 00214             }
  215. 00215         }
  216. 00216         break;
  217. 00217     case MMSTAFF_PF_AYUV: {
  218. 00218             // convert RGB to YUV color space
  219. 00219             unsigned int *src = (unsigned int*)*buf;
  220. 00220             for (int i = *width * *height; i > 0; i--) {
  221. 00221                 register unsigned int s = *src;
  222. 00222                 register int r = (s >> 16) & 0xff;
  223. 00223                 register int g = (s >> 8) & 0xff;
  224. 00224                 register int b = s  & 0xff;
  225. 00225                 if (!has_alpha)
  226. 00226                     if ((s >> 24) != 0xff) has_alpha = true;
  227. 00227                 s = s & 0xff000000;                                     //A
  228. 00228                 if (s) {
  229. 00229                     s = s | (((((66*r+129*g+25*b+128)>>8)+16) & 0xff) << 16);   //Y
  230. 00230                     s = s | (((((-38*r-74*g+112*b+128)>>8)+128) & 0xff) << 8);  //U (Cb)
  231. 00231                     s = s | ((((112*r-94*g-18*b+128)>>8)+128) & 0xff);          //V (Cr)
  232. 00232                 }
  233. 00233                 *src = s;
  234. 00234                 src++;
  235. 00235             }
  236. 00236         }
  237. 00237         break;
  238. 00238     case MMSTAFF_PF_ARGB4444: {
  239. 00239             // divide ARGB data into halves
  240. 00240             *pitch = (*pitch) >> 1;
  241. 00241             *size = (*size) >> 1;
  242. 00242             void *newbuf = malloc(*size);
  243. 00243             if (!newbuf) {
  244. 00244                 free(*buf);
  245. 00245                 *buf = NULL;
  246. 00246                 return false;
  247. 00247             }
  248. 00248
  249. 00249             // convert it
  250. 00250             unsigned int *src = (unsigned int*)*buf;
  251. 00251             unsigned short int *dst = (unsigned short int*)newbuf;
  252. 00252             for (int i = *width * *height; i > 0; i--) {
  253. 00253                 register unsigned int s = *src;
  254. 00254                 register unsigned short int d;
  255. 00255                 if (!has_alpha)
  256. 00256                     if ((s >> 28) != 0x0f) has_alpha = true;
  257. 00257                 d =   ((s & 0xf0000000) >> 16)
  258. 00258                     | ((s & 0x00f00000) >> 12)
  259. 00259                     | ((s & 0x0000f000) >> 8)
  260. 00260                     | ((s & 0x000000f0) >> 4);
  261. 00261                 *dst = d;
  262. 00262                 src++;
  263. 00263                 dst++;
  264. 00264             }
  265. 00265
  266. 00266             // switch buffers
  267. 00267             free(*buf);
  268. 00268             *buf = newbuf;
  269. 00269         }
  270. 00270         break;
  271. 00271     case MMSTAFF_PF_RGB16: {
  272. 00272             // convert into RGB16 format (remove alpha channel)
  273. 00273             *pitch = (*pitch) >> 1;
  274. 00274             *size = (*size) >> 1;
  275. 00275             void *newbuf = malloc(*size);
  276. 00276             if (!newbuf) {
  277. 00277                 free(*buf);
  278. 00278                 *buf = NULL;
  279. 00279                 return false;
  280. 00280             }
  281. 00281
  282. 00282             // convert it
  283. 00283             unsigned int *src = (unsigned int*)*buf;
  284. 00284             unsigned short int *dst = (unsigned short int*)newbuf;
  285. 00285             for (int i = *width * *height; i > 0; i--) {
  286. 00286                 // get src
  287. 00287                 register unsigned int SRC = *src;
  288. 00288                 register unsigned int A = SRC >> 24;
  289. 00289                 register unsigned int SA= 0x100 - A;
  290. 00290                 register unsigned short int d;
  291. 00291
  292. 00292                 // set background color to black
  293. 00293                 unsigned int r = 0;
  294. 00294                 unsigned int g = 0;
  295. 00295                 unsigned int b = 0;
  296. 00296
  297. 00297                 // invert src alpha
  298. 00298                 r = SA * r;
  299. 00299                 g = SA * g;
  300. 00300                 b = (SA * b) >> 5;
  301. 00301
  302. 00302                 // add src to dst
  303. 00303                 r += (A*(SRC & 0xf80000)) >> 19;
  304. 00304                 g += (A*(SRC & 0xfc00)) >> 5;
  305. 00305                 b += (A*(SRC & 0xf8)) >> 8;
  306. 00306                 d =   ((r & 0xffe000)   ? 0xf800 : ((r >> 8) << 11))
  307. 00307                     | ((g & 0xfff80000) ? 0x07e0 : ((g >> 13) << 5))
  308. 00308                     | ((b & 0xff00)     ? 0x1f   : (b >> 3));
  309. 00309                 *dst = d;
  310. 00310                 src++;
  311. 00311                 dst++;
  312. 00312             }
  313. 00313
  314. 00314             // switch buffers
  315. 00315             free(*buf);
  316. 00316             *buf = newbuf;
  317. 00317         }
  318. 00318         break;
  319. 00319     case MMSTAFF_PF_ABGR: {
  320. 00320             // change the positions of red and blue
  321. 00321             // for example disko's ABGR is equal to GL_RGBA in OpenGL
  322. 00322             unsigned int *src = (unsigned int*)*buf;
  323. 00323             for (int i = *width * *height; i > 0; i--) {
  324. 00324                 register unsigned int s = *src;
  325. 00325                 register unsigned int rb = s & 0x00ff00ff;
  326. 00326                 if (!has_alpha)
  327. 00327                     if ((s >> 24) != 0xff) has_alpha = true;
  328. 00328                 s = s & 0xff00ff00;
  329. 00329                 s = s | (rb << 16);
  330. 00330                 s = s | (rb >> 16);
  331. 00331                 *src = s;
  332. 00332                 src++;
  333. 00333             }
  334. 00334         }
  335. 00335         break;
  336. 00336     default: break;
  337. 00337     }
  338. 00338
  339. 00339     if (*alphachannel) {
  340. 00340         // per input parameter we assumed, that we have an alpha channel
  341. 00341         // here we overwrite it with the result from the previous check
  342. 00342         // so it can be, that we have an image with alpha channel but all alpha values are 0xff
  343. 00343         // in this case we mark the image with "no alpha channel"
  344. 00344         *alphachannel = has_alpha;
  345. 00345     }
  346. 00346
  347. 00347     return true;
  348. 00348 }
  349. 00349
  350. 00350
  351. 00351
  352. 00352 #ifdef __HAVE_PNG__
  353. 00353 // PNG callback function (read)
  354. 00354 // so we are able to read data with MMSFile class instead of standard FILE*
  355. 00355 void MMSTaff_read_png_data_callback(png_structp png_ptr, png_bytep data, png_size_t length) {
  356. 00356     MMSFile *file = (MMSFile *)png_get_io_ptr(png_ptr);
  357. 00357     size_t ritems;
  358. 00358     file->readBuffer((void *)data, &ritems, 1, length);
  359. 00359 }
  360. 00360 #endif
  361. 00361
  362. 00362
  363. 00363
  364. 00364 bool MMSTaffFile::readPNG(const char *filename, void **buf, int *width, int *height, int *pitch,
  365. 00365                               int *size, bool *alphachannel) {
  366. 00366 #ifdef __HAVE_PNG__
  367. 00367     MMSFile         *file;
  368. 00368     char            png_sig[8];
  369. 00369     png_structp     png_ptr = NULL;
  370. 00370     png_infop       info_ptr = NULL;
  371. 00371     png_infop       end_info_ptr = NULL;
  372. 00372     png_bytep       *row_pointers = NULL;
  373. 00373
  374. 00374     // check if file does exist and if it is an png format
  375. 00375     *buf = NULL;
  376. 00376     file = new MMSFile(filename);
  377. 00377     if (!file) {
  378. 00378         return false;
  379. 00379     }
  380. 00380     if (file->getLastError()) {
  381. 00381         return false;
  382. 00382     }
  383. 00383
  384. 00384     size_t ritems = 0;
  385. 00385     if (file->readBuffer(png_sig, &ritems, 1, sizeof(png_sig))) {
  386. 00386         if (ritems != sizeof(png_sig)) {
  387. 00387             delete file;
  388. 00388             return false;
  389. 00389         }
  390. 00390     }
  391. 00391     else {
  392. 00392         delete file;
  393. 00393         return false;
  394. 00394     }
  395. 00395
  396. 00396 #if PNG_LIBPNG_VER_MINOR == 2
  397. 00397     if (!png_check_sig((png_byte*)png_sig, sizeof(png_sig))) {
  398. 00398 #else
  399. 00399     if (png_sig_cmp((png_byte*)png_sig, 0, sizeof(png_sig)) != 0) {
  400. 00400 #endif
  401. 00401         delete file;
  402. 00402         return false;
  403. 00403     }
  404. 00404
  405. 00405
  406. 00406     // init png structs and abend handler
  407. 00407     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  408. 00408     if (!png_ptr) {
  409. 00409         delete file;
  410. 00410         return false;
  411. 00411     }
  412. 00412     png_set_sig_bytes(png_ptr, sizeof(png_sig));
  413. 00413
  414. 00414     // set read callback function
  415. 00415     png_set_read_fn(png_ptr, file, MMSTaff_read_png_data_callback);
  416. 00416
  417. 00417     if(setjmp(png_jmpbuf(png_ptr))) {
  418. 00418         // abend from libpng
  419. 00419         printf("png read error\n");
  420. 00420         png_destroy_read_struct(&png_ptr, (info_ptr)?&info_ptr:NULL, (end_info_ptr)?&end_info_ptr:NULL);
  421. 00421         if (row_pointers) free(row_pointers);
  422. 00422         if (*buf) free(*buf);
  423. 00423         *buf = NULL;
  424. 00424         delete file;
  425. 00425         return false;
  426. 00426     }
  427. 00427
  428. 00428     info_ptr = png_create_info_struct(png_ptr);
  429. 00429     if (!info_ptr) {
  430. 00430         png_destroy_read_struct(&png_ptr, NULL, NULL);
  431. 00431         delete file;
  432. 00432         return false;
  433. 00433     }
  434. 00434
  435. 00435     end_info_ptr = png_create_info_struct(png_ptr);
  436. 00436     if (!end_info_ptr) {
  437. 00437         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
  438. 00438         delete file;
  439. 00439         return false;
  440. 00440     }
  441. 00441
  442. 00442     // read png infos
  443. 00443     png_read_info(png_ptr, info_ptr);
  444. 00444     png_uint_32 w;
  445. 00445     png_uint_32 h;
  446. 00446     int bit_depth;
  447. 00447     int color_type;
  448. 00448     png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, NULL, NULL, NULL);
  449. 00449
  450. 00450     // check the png format
  451. 00451     if ((bit_depth != 8 && bit_depth != 16)
  452. 00452         || (color_type != PNG_COLOR_TYPE_PALETTE && color_type != PNG_COLOR_TYPE_GRAY
  453. 00453             && color_type != PNG_COLOR_TYPE_RGB && color_type != PNG_COLOR_TYPE_RGB_ALPHA)) {
  454. 00454         // format not supported
  455. 00455         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);
  456. 00456         delete file;
  457. 00457         return false;
  458. 00458     }
  459. 00459
  460. 00460     // set input transformations
  461. 00461     if (bit_depth == 16) {
  462. 00462         // strip to 8 bit channels
  463. 00463         png_set_strip_16(png_ptr);
  464. 00464     }
  465. 00465     png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER);
  466. 00466
  467. 00467 #if __BYTE_ORDER == __BIG_ENDIAN
  468. 00468     png_set_swap_alpha(png_ptr);
  469. 00469 #else
  470. 00470     png_set_bgr(png_ptr);
  471. 00471 #endif
  472. 00472
  473. 00473     png_set_interlace_handling(png_ptr);
  474. 00474     if (color_type == PNG_COLOR_TYPE_PALETTE) {
  475. 00475         // convert palette to rgb data
  476. 00476         png_set_palette_to_rgb(png_ptr);
  477. 00477     }
  478. 00478     if (color_type == PNG_COLOR_TYPE_GRAY) {
  479. 00479         // convert grayscale to rgb data
  480. 00480         png_set_gray_to_rgb(png_ptr);
  481. 00481     }
  482. 00482
  483. 00483     *alphachannel = true;
  484. 00484     if (color_type != PNG_COLOR_TYPE_RGB_ALPHA && color_type != PNG_COLOR_TYPE_GRAY_ALPHA) {
  485. 00485         // image has no alpha channel, add alpha channel 0xff
  486. 00486         *alphachannel = false;
  487. 00487         png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
  488. 00488     }
  489. 00489
  490. 00490     png_read_update_info(png_ptr, info_ptr);
  491. 00491
  492. 00492     // allocate memory for row pointers
  493. 00493     *width = w;
  494. 00494     *height = h;
  495. 00495     *pitch = 4 * w;
  496. 00496     *size = *pitch * h;
  497. 00497     row_pointers = (png_bytep*)malloc(*height * sizeof(png_bytep));
  498. 00498     if (!row_pointers) {
  499. 00499         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);
  500. 00500         delete file;
  501. 00501         return false;
  502. 00502     }
  503. 00503
  504. 00504     // allocate memory for image data
  505. 00505     if (this->mirror_size > *height) this->mirror_size = *height;
  506. 00506     *buf = malloc((*size) + (*pitch) * this->mirror_size);
  507. 00507     if (!*buf) {
  508. 00508         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);
  509. 00509         free(row_pointers);
  510. 00510         delete file;
  511. 00511         return false;
  512. 00512     }
  513. 00513     char *b = (char*)*buf;
  514. 00514     for (int i = 0; i < *height; i++) {
  515. 00515         row_pointers[i]=(png_byte*)b;
  516. 00516         b+=*pitch;
  517. 00517     }
  518. 00518
  519. 00519     // read the image data
  520. 00520     png_read_image(png_ptr, row_pointers);
  521. 00521     png_read_end(png_ptr, end_info_ptr);
  522. 00522
  523. 00523     // all right, freeing helpers
  524. 00524     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);
  525. 00525     free(row_pointers);
  526. 00526     delete file;
  527. 00527
  528. 00528     // at this point we have ARGB (MMSTAFF_PF_ARGB) pixels ********
  529. 00529     // so check now if i have to convert it
  530. 00530
  531. 00531     // create mirror, rotate and convert to target pixelformat
  532. 00532     return postprocessImage(buf, width, height, pitch, size, alphachannel);
  533. 00533 #else
  534. 00534     return false;
  535. 00535 #endif
  536. 00536 }
  537. 00537
  538. 00538
  539. 00539
  540. 00540 #ifdef __HAVE_JPEG__
  541. 00541 struct JPEGErrorManager {
  542. 00542   struct jpeg_error_mgr pub;            /**< "public" fields        */
  543. 00543   jmp_buf               setjmpBuffer;   /**< for return to caller   */
  544. 00544 };
  545. 00545
  546. 00546 METHODDEF(void) JPEGErrorExit(j_common_ptr cinfo) {
  547. 00547     /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
  548. 00548     struct JPEGErrorManager *myerr = (struct JPEGErrorManager*)cinfo->err;
  549. 00549
  550. 00550     /* Always display the message. */
  551. 00551     /* We could postpone this until after returning, if we chose. */
  552. 00552     (*cinfo->err->output_message)(cinfo);
  553. 00553
  554. 00554     /* Return control to the setjmp point */
  555. 00555     longjmp(myerr->setjmpBuffer, 1);
  556. 00556 }
  557. 00557 #endif
  558. 00558
  559. 00559 bool MMSTaffFile::readJPEG(const char *filename, void **buf, int *width, int *height, int *pitch,
  560. 00560                                 int *size, bool *alphachannel) {
  561. 00561 #ifdef __HAVE_JPEG__
  562. 00562     struct jpeg_decompress_struct   cinfo;
  563. 00563     struct JPEGErrorManager         jerr;
  564. 00564     FILE                            *fp;
  565. 00565     JSAMPARRAY                      rowBuf;     /**< Output row buffer */
  566. 00566     int                             rowStride;  /**< physical row width in output buffer */
  567. 00567
  568. 00568     MMSFile         *file=NULL;
  569. 00569     size_t ritems = 0;
  570. 00570     char *fileBuffer=NULL;
  571. 00571
  572. 00572     if (strToUpr(string(filename).substr(0,7)) == "HTTP://") {
  573. 00573         // check if file does exist and if it is an png format
  574. 00574         file = new MMSFile(filename);
  575. 00575         if (!file) {
  576. 00576             return false;
  577. 00577         }
  578. 00578         if (file->getLastError()) {
  579. 00579             return false;
  580. 00580         }
  581. 00581
  582. 00582         if (!file->readBufferEx((void **)&fileBuffer, &ritems)) {
  583. 00583             delete file;
  584. 00584             return false;
  585. 00585         }
  586. 00586
  587. 00587         if((fp = fmemopen(fileBuffer, ritems, "rb")) == NULL) {
  588. 00588             free(fileBuffer);
  589. 00589             fileBuffer = NULL;
  590. 00590             delete file;
  591. 00591             return false;
  592. 00592         }
  593. 00593     } else {
  594. 00594         if((fp = fopen(filename, "rb")) == NULL) {
  595. 00595             return false;
  596. 00596         }
  597. 00597     }
  598. 00598
  599. 00599     cinfo.err = jpeg_std_error(&jerr.pub);
  600. 00600     jerr.pub.error_exit = JPEGErrorExit;
  601. 00601     if(setjmp(jerr.setjmpBuffer)) {
  602. 00602         jpeg_destroy_decompress(&cinfo);
  603. 00603         fclose(fp);
  604. 00604         if (file) {
  605. 00605             if (fileBuffer)
  606. 00606                 free(fileBuffer);
  607. 00607             fileBuffer = NULL;
  608. 00608             delete file;
  609. 00609         }
  610. 00610         return false;
  611. 00611     }
  612. 00612     jpeg_create_decompress(&cinfo);
  613. 00613     jpeg_stdio_src(&cinfo, fp);
  614. 00614
  615. 00615     if(jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK) {
  616. 00616         fclose(fp);
  617. 00617         if (file) {
  618. 00618             if (fileBuffer)
  619. 00619                 free(fileBuffer);
  620. 00620             fileBuffer = NULL;
  621. 00621             delete file;
  622. 00622         }
  623. 00623         return false;
  624. 00624     }
  625. 00625
  626. 00626     /* dimension filled by jpeg_read_header() */
  627. 00627     *width  = (int)cinfo.image_width;
  628. 00628     *height = (int)cinfo.image_height;
  629. 00629     *pitch  = *width * 4;
  630. 00630     *size   = *pitch * *height;
  631. 00631
  632. 00632     // jpeg generally has no alpha channel
  633. 00633     *alphachannel = false;
  634. 00634
  635. 00635     /* setting decompression parameters */
  636. 00636     cinfo.out_color_space = JCS_RGB;    /**< setting output colorspace to RGB */
  637. 00637
  638. 00638     /* start decompression */
  639. 00639     jpeg_start_decompress(&cinfo);
  640. 00640
  641. 00641     rowStride = cinfo.output_width * cinfo.output_components;
  642. 00642     rowBuf = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowStride, 1);
  643. 00643
  644. 00644     /* allocate memory for ARGB output */
  645. 00645     if(this->mirror_size > *height) this->mirror_size = *height;
  646. 00646     *buf = malloc((*size) + (*pitch) * this->mirror_size);
  647. 00647     if(!*buf) {
  648. 00648         jpeg_finish_decompress(&cinfo);
  649. 00649         jpeg_destroy_decompress(&cinfo);
  650. 00650         fclose(fp);
  651. 00651         if (file) {
  652. 00652             if (fileBuffer)
  653. 00653                 free(fileBuffer);
  654. 00654             fileBuffer = NULL;
  655. 00655             delete file;
  656. 00656         }
  657. 00657         return false;
  658. 00658     }
  659. 00659
  660. 00660     unsigned int *src = (unsigned int*)*buf;
  661. 00661     while(cinfo.output_scanline < cinfo.output_height) {
  662. 00662         jpeg_read_scanlines(&cinfo, rowBuf, 1);
  663. 00663         unsigned char *b = *rowBuf;
  664. 00664         for(unsigned int i = 0; i < cinfo.output_width; ++i) {
  665. 00665             *src = 0xff000000 + (b[0] << 16) + (b[1] << 8) + b[2];
  666. 00666             b += 3;
  667. 00667             src++;
  668. 00668         }
  669. 00669     }
  670. 00670
  671. 00671     jpeg_finish_decompress(&cinfo);
  672. 00672     jpeg_destroy_decompress(&cinfo);
  673. 00673     fclose(fp);
  674. 00674     if (file) {
  675. 00675         if (fileBuffer)
  676. 00676             free(fileBuffer);
  677. 00677         fileBuffer = NULL;
  678. 00678         delete file;
  679. 00679     }
  680. 00680
  681. 00681     /* create mirror, rotate and convert to target pixelformat */
  682. 00682     return postprocessImage(buf, width, height, pitch, size, alphachannel);
  683. 00683 #else
  684. 00684     return false;
  685. 00685 #endif
  686. 00686 }
  687. 00687
  688. 00688 bool MMSTaffFile::readTIFF(const char *filename, void **buf, int *width, int *height, int *pitch,
  689. 00689                                 int *size, bool *alphachannel) {
  690. 00690 #ifdef __HAVE_TIFF__
  691. 00691     TIFF* tiff;
  692. 00692
  693. 00693     if((tiff = TIFFOpen(filename, "rb")) == NULL) {
  694. 00694         return false;
  695. 00695     }
  696. 00696
  697. 00697     TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, width);
  698. 00698     TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, height);
  699. 00699     *pitch  = *width * 4;
  700. 00700     *size   = *pitch * *height;
  701. 00701
  702. 00702     // we assume that we have an alpha channel
  703. 00703     *alphachannel = true;
  704. 00704
  705. 00705     /* allocate memory for ARGB output */
  706. 00706     if(this->mirror_size > *height) this->mirror_size = *height;
  707. 00707     //*buf = (unsigned int*)_TIFFmalloc((*size) + (*pitch) * this->mirror_size);
  708. 00708     *buf = malloc((*size) + (*pitch) * this->mirror_size);
  709. 00709     if(!*buf) {
  710. 00710         TIFFClose(tiff);
  711. 00711         return false;
  712. 00712     }
  713. 00713
  714. 00714     if(TIFFReadRGBAImageOriented(tiff, *width, *height, (uint32*)*buf, ORIENTATION_TOPLEFT, 0) == 0) {
  715. 00715         TIFFClose(tiff);
  716. 00716         return false;
  717. 00717     }
  718. 00718
  719. 00719     /* convert from BGRA to ARGB */
  720. 00720     unsigned int *src = (unsigned int*)*buf;
  721. 00721     unsigned int nPixels = *width * *height;
  722. 00722     for(unsigned int i = 0; i < nPixels; ++i) {
  723. 00723         register unsigned int s = (*src ^ (*src >> 16)) & 0xff;
  724. 00724         *src = *src ^ (s | (s << 16));
  725. 00725         src++;
  726. 00726     }
  727. 00727
  728. 00728     //_TIFFfree(*buf);
  729. 00729     TIFFClose(tiff);
  730. 00730
  731. 00731     /* create mirror, rotate and convert to target pixelformat */
  732. 00732     return postprocessImage(buf, width, height, pitch, size, alphachannel);
  733. 00733 #else
  734. 00734     return false;
  735. 00735 #endif
  736. 00736 }
  737. 00737
  738. 00738
  739. 00739 bool MMSTaffFile::convertString2TaffAttributeType(TAFF_ATTRTYPE attrType, char *attrValStr, bool *attrValStr_valid,
  740. 00740                                 bool *int_val_set, bool *byte_val_set, int *int_val,
  741. 00741                                 const char *attrname, int attrid, const char *nodename, int nodeline) {
  742. 00742     xmlChar *attrVal = (xmlChar *)attrValStr;
  743. 00743     if (!attrValStr) return false;
  744. 00744     if (!attrValStr_valid) return false;
  745. 00745     *attrValStr_valid = true;
  746. 00746     if (int_val_set)  *int_val_set = false;
  747. 00747     if (byte_val_set) *byte_val_set = false;
  748. 00748
  749. 00749     bool check_ok = true;
  750. 00750
  751. 00751
  752. 00752     string validvals = "";
  753. 00753     bool badval = false;
  754. 00754     switch (attrType) {
  755. 00755     case TAFF_ATTRTYPE_NONE:
  756. 00756     case TAFF_ATTRTYPE_STRING:
  757. 00757     case TAFF_ATTRTYPE_BINDATA:
  758. 00758         break;
  759. 00759
  760. 00760     case TAFF_ATTRTYPE_NE_STRING:
  761. 00761         badval = (!*attrVal);
  762. 00762         if (badval) {
  763. 00763             validvals = "any characters, but not empty";
  764. 00764             check_ok = false;
  765. 00765         }
  766. 00766         break;
  767. 00767
  768. 00768     case TAFF_ATTRTYPE_BOOL:
  769. 00769         if (!byte_val_set || !int_val) return false;
  770. 00770         badval = ((xmlStrcmp(attrVal, (xmlChar *)"true"))&&(xmlStrcmp(attrVal, (xmlChar *)"false")));
  771. 00771         if (badval) {
  772. 00772             validvals = "\"true\", \"false\"";
  773. 00773             check_ok = false;
  774. 00774         }
  775. 00775         else {
  776. 00776             *byte_val_set = true;
  777. 00777             if (xmlStrcmp(attrVal, (xmlChar *)"true")==0)
  778. 00778                 *int_val = 0xff;
  779. 00779             else
  780. 00780                 *int_val = 0;
  781. 00781         }
  782. 00782         break;
  783. 00783
  784. 00784     case TAFF_ATTRTYPE_UCHAR:
  785. 00785     case TAFF_ATTRTYPE_UCHAR100:
  786. 00786         if (!byte_val_set || !int_val) return false;
  787. 00787         badval = ((xmlStrlen(attrVal) < 1)||(xmlStrlen(attrVal) > 3));
  788. 00788         if (!badval) {
  789. 00789             char iv[3+1];
  790. 00790             *int_val = atoi((char*)attrVal);
  791. 00791             sprintf(iv, "%d", *int_val);
  792. 00792             badval = (xmlStrcmp(attrVal, (xmlChar *)iv));
  793. 00793             if (!badval) {
  794. 00794                 if (attrType == TAFF_ATTRTYPE_UCHAR100)
  795. 00795                     badval = (*int_val<0||*int_val>100);
  796. 00796                 else
  797. 00797                     badval = (*int_val<0||*int_val>255);
  798. 00798             }
  799. 00799             *byte_val_set = !badval;
  800. 00800         }
  801. 00801         if (badval) {
  802. 00802             if (attrType == TAFF_ATTRTYPE_UCHAR100)
  803. 00803                 validvals = "\"0\"..\"100\"";
  804. 00804             else
  805. 00805                 validvals = "\"0\"..\"255\"";
  806. 00806             check_ok = false;
  807. 00807         }
  808. 00808         break;
  809. 00809
  810. 00810     case TAFF_ATTRTYPE_INT:
  811. 00811         if (!int_val_set || !int_val) return false;
  812. 00812         char iv[11+1];
  813. 00813         *int_val = atoi((char*)attrVal);
  814. 00814         sprintf(iv, "%d", *int_val);
  815. 00815         badval = (xmlStrcmp(attrVal, (xmlChar *)iv));
  816. 00816         *int_val_set = !badval;
  817. 00817         if (badval) {
  818. 00818             validvals = "\"-2147483648\"..\"2147483647\"";
  819. 00819             check_ok = false;
  820. 00820         }
  821. 00821         break;
  822. 00822
  823. 00823     case TAFF_ATTRTYPE_STATE:
  824. 00824         if (!byte_val_set || !int_val) return false;
  825. 00825         badval = ((xmlStrcmp(attrVal, (xmlChar *)"true"))&&(xmlStrcmp(attrVal, (xmlChar *)"false"))
  826. 00826                 &&(xmlStrcmp(attrVal, (xmlChar *)"auto")));
  827. 00827         if (badval) {
  828. 00828             validvals = "\"true\", \"false\", \"auto\"";
  829. 00829             check_ok = false;
  830. 00830         }
  831. 00831         else {
  832. 00832             *byte_val_set = true;
  833. 00833             if (xmlStrcmp(attrVal, (xmlChar *)"true")==0)
  834. 00834                 *int_val = 0xff;
  835. 00835             else
  836. 00836             if (xmlStrcmp(attrVal, (xmlChar *)"auto")==0)
  837. 00837                 *int_val = 0x01;
  838. 00838             else
  839. 00839                 *int_val = 0;
  840. 00840         }
  841. 00841         break;
  842. 00842
  843. 00843     case TAFF_ATTRTYPE_SEQUENCE_MODE: {
  844. 00844         if (!byte_val_set || !int_val) return false;
  845. 00845         bool sm_true            = !xmlStrcmp(attrVal, (xmlChar *)"true");
  846. 00846         bool sm_false           = !xmlStrcmp(attrVal, (xmlChar *)"false");
  847. 00847         bool sm_linear          = !xmlStrcmp(attrVal, (xmlChar *)"linear");
  848. 00848         bool sm_log             = !xmlStrcmp(attrVal, (xmlChar *)"log");
  849. 00849         bool sm_log_soft_start  = !xmlStrcmp(attrVal, (xmlChar *)"log_soft_start");
  850. 00850         bool sm_log_soft_end    = !xmlStrcmp(attrVal, (xmlChar *)"log_soft_end");
  851. 00851         badval = (!sm_true && !sm_false && !sm_linear && !sm_log && !sm_log_soft_start && !sm_log_soft_end);
  852. 00852         if (badval) {
  853. 00853             validvals = "\"true\", \"false\", \"linear\", \"log\", \"log_soft_start\", \"log_soft_end\"";
  854. 00854             check_ok = false;
  855. 00855         }
  856. 00856         else {
  857. 00857             *byte_val_set = true;
  858. 00858             if (sm_true)
  859. 00859                 *int_val = 0xff;
  860. 00860             else
  861. 00861             if (sm_linear)
  862. 00862                 *int_val = 0x01;
  863. 00863             else
  864. 00864             if (sm_log)
  865. 00865                 *int_val = 0x02;
  866. 00866             else
  867. 00867             if (sm_log_soft_start)
  868. 00868                 *int_val = 0x03;
  869. 00869             else
  870. 00870             if (sm_log_soft_end)
  871. 00871                 *int_val = 0x04;
  872. 00872             else
  873. 00873                 *int_val = 0;
  874. 00874         }
  875. 00875         }
  876. 00876         break;
  877. 00877
  878. 00878     case TAFF_ATTRTYPE_COLOR:
  879. 00879         if (!int_val_set || !int_val) return false;
  880. 00880         MMSFBColor color;
  881. 00881         badval = (!getMMSFBColorFromString((const char*)attrVal, &color));
  882. 00882         if (badval) {
  883. 00883             validvals = "argb values in hex format, syntax: \"#rrggbbaa\"";
  884. 00884             check_ok = false;
  885. 00885         }
  886. 00886         else {
  887. 00887             *int_val_set = true;
  888. 00888             *int_val = (int)color.getARGB();
  889. 00889         }
  890. 00890         break;
  891. 00891     }
  892. 00892
  893. 00893     // check if the value is blank and i have to ignore it
  894. 00894     if (this->ignore_blank_values) {
  895. 00895         if (!*attrVal) {
  896. 00896             *attrValStr_valid = false;
  897. 00897             if (int_val_set)  *int_val_set = false;
  898. 00898             if (byte_val_set) *byte_val_set = false;
  899. 00899             return true;
  900. 00900         }
  901. 00901     }
  902. 00902
  903. 00903     if (!check_ok) {
  904. 00904         printf("Error: Value \"%s\" is invalid for the attribute \"%s\" of tag \"%s\", line %d of file %s\n       valid values: %s\n",
  905. 00905                         attrVal, (attrname)?attrname:"?", (nodename)?nodename:"?", nodeline, external_filename.c_str(), validvals.c_str());
  906. 00906         *attrValStr_valid = false;
  907. 00907         if (int_val_set)  *int_val_set = false;
  908. 00908         if (byte_val_set) *byte_val_set = false;
  909. 00909         return false;
  910. 00910     }
  911. 00911
  912. 00912     // all right
  913. 00913     if (this->trace)
  914. 00914         printf(" Attribute \"%s\" found, ID=%d, value=\"%s\"\n", (attrname)?attrname:"?", attrid, attrVal);
  915. 00915
  916. 00916     return true;
  917. 00917 }
  918. 00918
  919. 00919
  920. 00920 bool MMSTaffFile::convertXML2TAFF_throughDoc(int depth, void *void_node, MMSFile *taff_file) {
  921. 00921
  922. 00922     bool wok = true;
  923. 00923     xmlNode *node = (xmlNode*) void_node;
  924. 00924     xmlNode *cur_node;
  925. 00925     if (depth==0)
  926. 00926         /* work with root */
  927. 00927         cur_node = node;
  928. 00928     else
  929. 00929         /* iterate through childs */
  930. 00930         cur_node = node->children;
  931. 00931
  932. 00932     while (cur_node) {
  933. 00933
  934. 00934         int tagid = 0;
  935. 00935         bool tag_found = false;
  936. 00936
  937. 00937         while (this->taff_desc->tagtable[tagid].name) {
  938. 00938             if (xmlStrcmp(cur_node->name, (const xmlChar *)this->taff_desc->tagtable[tagid].name)==0) {
  939. 00939                 /* tag found in XML and tagtable, check the type? */
  940. 00940                 if (this->taff_desc->tagtable[tagid].typeattr)
  941. 00941                 {
  942. 00942                     /* searching the typeattr and type */
  943. 00943                     for (xmlAttr *cur_attr = cur_node->properties; cur_attr; cur_attr = cur_attr->next) {
  944. 00944                         if (xmlStrcmp(cur_attr->name, (const xmlChar *)this->taff_desc->tagtable[tagid].typeattr)==0) {
  945. 00945                             xmlChar *attrVal = xmlGetProp(cur_node, cur_attr->name);
  946. 00946                             if (attrVal) {
  947. 00947                                 if (xmlStrcmp(attrVal, (const xmlChar *)this->taff_desc->tagtable[tagid].type)==0) {
  948. 00948                                     tag_found = true;
  949. 00949                                     break;
  950. 00950                                 }
  951. 00951                                 xmlFree(attrVal);
  952. 00952                             }
  953. 00953                         }
  954. 00954                     }
  955. 00955                 }
  956. 00956                 else
  957. 00957                     tag_found = true;
  958. 00958
  959. 00959                 if (tag_found)
  960. 00960                     break;
  961. 00961             }
  962. 00962             tagid++;
  963. 00963         }
  964. 00964
  965. 00965         if (tag_found) {
  966. 00966
  967. 00967             if (this->trace)
  968. 00968                 printf("Tag \"%s\" found, ID=%d\n", cur_node->name, tagid);
  969. 00969
  970. 00970             /* writing the new tag */
  971. 00971             if (taff_file) {
  972. 00972                 size_t ritems;
  973. 00973                 unsigned char wb[2];
  974. 00974                 wb[0]=MMSTAFF_TAGTABLE_TYPE_TAG;
  975. 00975                 wb[1]=(unsigned char)tagid;
  976. 00976                 writeBuffer(taff_file, wb, &ritems, 1, 2, &wok);
  977. 00977             }
  978. 00978
  979. 00979             /* get variables */
  980. 00980             for (xmlAttr *cur_attr = cur_node->properties; cur_attr; cur_attr = cur_attr->next) {
  981. 00981
  982. 00982                 int attrid = 0;
  983. 00983                 TAFF_ATTRDESC *attr = this->taff_desc->tagtable[tagid].attr;
  984. 00984                 bool attr_found = false;
  985. 00985
  986. 00986                 if (!attr) continue;
  987. 00987
  988. 00988                 xmlChar *attrVal = xmlGetProp(cur_node, cur_attr->name);
  989. 00989                 if (!attrVal) continue;
  990. 00990
  991. 00991                 while (attr[attrid].name)
  992. 00992                 {
  993. 00993                     if (xmlStrcmp(cur_attr->name, (const xmlChar *)attr[attrid].name)==0) {
  994. 00994                         attr_found = true;
  995. 00995                         break;
  996. 00996                     }
  997. 00997                     attrid++;
  998. 00998                 }
  999. 00999
  1000. 01000                 if (attr_found) {
  1001. 01001
  1002. 01002                     // now check the type of the variable
  1003. 01003                     bool attrValStr_valid;
  1004. 01004                     bool int_val_set;
  1005. 01005                     bool byte_val_set;
  1006. 01006                     int  int_val;
  1007. 01007
  1008. 01008                     if (!convertString2TaffAttributeType(attr[attrid].type, (char *)attrVal, &attrValStr_valid,
  1009. 01009                                                     &int_val_set, &byte_val_set, &int_val,
  1010. 01010                                                     (const char *)cur_attr->name, attrid,
  1011. 01011                                                     (const char *)cur_node->name, cur_node->line)) {
  1012. 01012                         // check failed
  1013. 01013                         return false;
  1014. 01014                     }
  1015. 01015
  1016. 01016                     if (!attrValStr_valid && !int_val_set && !byte_val_set) {
  1017. 01017                         // no values to process
  1018. 01018                         continue;
  1019. 01019                     }
  1020. 01020
  1021. 01021
  1022. 01022                     // attribute value is determined, write it now
  1023. 01023                     if (taff_file) {
  1024. 01024                         if (!int_val_set && !byte_val_set) {
  1025. 01025                             /* get the length of the value INCLUDING the 0x00 because of fast read & parse of the TAFF */
  1026. 01026                             int attrvallen = xmlStrlen(attrVal) + 1;
  1027. 01027
  1028. 01028                             size_t ritems;
  1029. 01029                             unsigned char wb[3];
  1030. 01030                             wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1031. 01031                             wb[1]=(unsigned char)attrid;
  1032. 01032                             if (attrvallen >= 0xff) {
  1033. 01033                                 /* in this case set 0xff as mark and append the full integer */
  1034. 01034                                 wb[2]=0xff;
  1035. 01035                                 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1036. 01036                                 writeBuffer(taff_file, &attrvallen, &ritems, 1, sizeof(int), &wok);
  1037. 01037                             }
  1038. 01038                             else {
  1039. 01039                                 /* in this case write only one byte length */
  1040. 01040                                 wb[2]=(unsigned char)attrvallen;
  1041. 01041                                 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1042. 01042                             }
  1043. 01043                             writeBuffer(taff_file, attrVal, &ritems, 1, attrvallen, &wok);
  1044. 01044                         }
  1045. 01045                         else
  1046. 01046                         if (int_val_set) {
  1047. 01047                             // writing value as INTEGER
  1048. 01048                             size_t ritems;
  1049. 01049                             unsigned char wb[3];
  1050. 01050                             wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1051. 01051                             wb[1]=(unsigned char)attrid;
  1052. 01052                             wb[2]=sizeof(int);
  1053. 01053                             writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1054. 01054                             writeBuffer(taff_file, &int_val, &ritems, 1, sizeof(int), &wok);
  1055. 01055                         }
  1056. 01056                         else {
  1057. 01057                             // writing value as single BYTE
  1058. 01058                             size_t ritems;
  1059. 01059                             unsigned char wb[3];
  1060. 01060                             wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1061. 01061                             wb[1]=(unsigned char)attrid;
  1062. 01062                             wb[2]=sizeof(char);
  1063. 01063                             writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1064. 01064                             unsigned char byte_val = int_val;
  1065. 01065                             writeBuffer(taff_file, &byte_val, &ritems, 1, sizeof(char), &wok);
  1066. 01066                         }
  1067. 01067                     }
  1068. 01068                 }
  1069. 01069                 else {
  1070. 01070                     /* attribute is not defined, so we cannot found an ID of it */
  1071. 01071                     /* we store it with ID 0xff and its real name */
  1072. 01072                     if (this->trace)
  1073. 01073                         printf(" Attribute \"%s\" found without ID, value=\"%s\"\n", cur_attr->name, attrVal);
  1074. 01074
  1075. 01075                     if (this->print_warnings)
  1076. 01076                         printf("Warning: Attribute \"%s\" is not defined for tag \"%s\", line %d of file %s\n         We store it with the real name.\n",
  1077. 01077                                 cur_attr->name, cur_node->name, cur_node->line, external_filename.c_str());
  1078. 01078
  1079. 01079                     /* write attribute value */
  1080. 01080                     if (taff_file) {
  1081. 01081                         /* get the length of the value INCLUDING the 0x00 because of fast read & parse of the TAFF */
  1082. 01082                         int attrnamlen = xmlStrlen(cur_attr->name) + 1;
  1083. 01083                         int attrvallen = xmlStrlen(attrVal) + 1;
  1084. 01084
  1085. 01085                         size_t ritems;
  1086. 01086                         unsigned char wb[3];
  1087. 01087                         wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1088. 01088                         wb[1]=MMSTAFF_ATTR_WITHOUT_ID;
  1089. 01089                         writeBuffer(taff_file, wb, &ritems, 1, 2, &wok);
  1090. 01090                         writeBuffer(taff_file, &attrnamlen, &ritems, 1, sizeof(int), &wok);
  1091. 01091                         writeBuffer(taff_file, (char*)cur_attr->name, &ritems, 1, attrnamlen, &wok);
  1092. 01092                         if (attrvallen >= 0xff) {
  1093. 01093                             /* in this case set 0xff as mark and append the full integer */
  1094. 01094                             wb[0]=0xff;
  1095. 01095                             writeBuffer(taff_file, wb, &ritems, 1, 1, &wok);
  1096. 01096                             writeBuffer(taff_file, &attrvallen, &ritems, 1, sizeof(int), &wok);
  1097. 01097                         }
  1098. 01098                         else {
  1099. 01099                             /* in this case write only one byte length */
  1100. 01100                             wb[0]=(unsigned char)attrvallen;
  1101. 01101                             writeBuffer(taff_file, wb, &ritems, 1, 1, &wok);
  1102. 01102                         }
  1103. 01103                         writeBuffer(taff_file, attrVal, &ritems, 1, attrvallen, &wok);
  1104. 01104                     }
  1105. 01105                 }
  1106. 01106
  1107. 01107                 xmlFree(attrVal);
  1108. 01108             }
  1109. 01109
  1110. 01110             /* call recursive to find childs */
  1111. 01111             if (!convertXML2TAFF_throughDoc(depth+1, cur_node, taff_file))
  1112. 01112                 return false;
  1113. 01113
  1114. 01114             /* writing the close tag */
  1115. 01115             if (taff_file) {
  1116. 01116                 size_t ritems;
  1117. 01117                 unsigned char wb[2];
  1118. 01118                 wb[0]=MMSTAFF_TAGTABLE_TYPE_CLOSETAG;
  1119. 01119                 wb[1]=(unsigned char)tagid;
  1120. 01120                 writeBuffer(taff_file, wb, &ritems, 1, 2, &wok);
  1121. 01121             }
  1122. 01122         }
  1123. 01123         else {
  1124. 01124             if (xmlStrcmp(cur_node->name, (const xmlChar *)"text")&&xmlStrcmp(cur_node->name, (const xmlChar *)"comment")) {
  1125. 01125                 printf("Error: Tag \"%s\" is not defined, line %d of file %s\n", cur_node->name, cur_node->line, external_filename.c_str());
  1126. 01126                 return false;
  1127. 01127             }
  1128. 01128         }
  1129. 01129
  1130. 01130         if (depth==0)
  1131. 01131             break;
  1132. 01132         else
  1133. 01133             cur_node = cur_node->next;
  1134. 01134     }
  1135. 01135
  1136. 01136     // return with write status
  1137. 01137     return wok;
  1138. 01138 }
  1139. 01139
  1140. 01140 bool MMSTaffFile::convertXML2TAFF() {
  1141. 01141
  1142. 01142     bool   rc = false;
  1143. 01143     xmlDoc *parser = NULL;
  1144. 01144
  1145. 01145     LIBXML_TEST_VERSION
  1146. 01146
  1147. 01147     /* check input parameters */
  1148. 01148     if (!this->taff_desc || this->external_filename.empty()) {
  1149. 01149         return false;
  1150. 01150     }
  1151. 01151
  1152. 01152     /* read the XML file */
  1153. 01153     parser = xmlReadFile(this->external_filename.c_str(),
  1154. 01154             NULL,
  1155. 01155             XML_PARSE_PEDANTIC |
  1156. 01156             XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NODICT |
  1157. 01157             XML_PARSE_NOXINCNODE
  1158. 01158 #if LIBXML_VERSION >= 20700
  1159. 01159             | XML_PARSE_NOBASEFIX
  1160. 01160 #endif
  1161. 01161             );
  1162. 01162
  1163. 01163     if (parser) {
  1164. 01164
  1165. 01165         /* open binary destination file */
  1166. 01166         MMSFile *taff_file = NULL;
  1167. 01167         if (this->taff_filename!="") {
  1168. 01168             taff_file = new MMSFile(this->taff_filename.c_str(), MMSFM_WRITE);
  1169. 01169             size_t ritems;
  1170. 01170             bool wok = true;
  1171. 01171             writeBuffer(taff_file, (void*)TAFF_IDENT, &ritems, 1, strlen(TAFF_IDENT), &wok);
  1172. 01172             writeBuffer(taff_file, &(this->taff_desc->type), &ritems, 1, sizeof(this->taff_desc->type), &wok);
  1173. 01173             writeBuffer(taff_file, &(this->taff_desc->version), &ritems, 1, sizeof(this->taff_desc->version), &wok);
  1174. 01174             if (!wok) {
  1175. 01175                 // write error, close file and free
  1176. 01176                 delete taff_file;
  1177. 01177                 xmlFreeDoc(parser);
  1178. 01178
  1179. 01179                 // reset the file
  1180. 01180                 taff_file = new MMSFile(this->taff_filename.c_str(), MMSFM_WRITE);
  1181. 01181                 if (taff_file) delete taff_file;
  1182. 01182
  1183. 01183                 return false;
  1184. 01184             }
  1185. 01185         }
  1186. 01186
  1187. 01187         // get the first element
  1188. 01188         xmlNode* node = xmlDocGetRootElement(parser);
  1189. 01189
  1190. 01190         // through the doc
  1191. 01191         rc = convertXML2TAFF_throughDoc(0, node, taff_file);
  1192. 01192
  1193. 01193         // close file and free
  1194. 01194         if (taff_file)
  1195. 01195             delete taff_file;
  1196. 01196         xmlFreeDoc(parser);
  1197. 01197
  1198. 01198         if (!rc) {
  1199. 01199             // failed, reset the file
  1200. 01200             taff_file = new MMSFile(this->taff_filename.c_str(), MMSFM_WRITE);
  1201. 01201             if (taff_file) delete taff_file;
  1202. 01202         }
  1203. 01203     }
  1204. 01204     else {
  1205. 01205         printf("Error: cannot read external file %s\n", this->external_filename.c_str());
  1206. 01206     }
  1207. 01207
  1208. 01208     return rc;
  1209. 01209 }
  1210. 01210
  1211. 01211 bool MMSTaffFile::convertIMAGE2TAFF() {
  1212. 01212     bool    rc = false;
  1213. 01213     void    *imgBuf;
  1214. 01214     int     imgWidth;
  1215. 01215     int     imgHeight;
  1216. 01216     int     imgPitch;
  1217. 01217     int     imgSize;
  1218. 01218     bool    imgAlphaChannel;
  1219. 01219
  1220. 01220     /* check input parameters */
  1221. 01221     if (!this->taff_desc || this->external_filename.empty()) {
  1222. 01222         return false;
  1223. 01223     }
  1224. 01224
  1225. 01225     /* check file extension (if this fails try readPNG() and/or readJPEG() and/or readTIFF()) */
  1226. 01226     if(strToUpr(this->external_filename).rfind(".PNG") == this->external_filename.size() - 4) {
  1227. 01227 #ifdef __HAVE_PNG__
  1228. 01228         rc = readPNG(this->external_filename.c_str(), &imgBuf, &imgWidth, &imgHeight, &imgPitch, &imgSize, &imgAlphaChannel);
  1229. 01229 #else
  1230. 01230         cout << "Disko was built without PNG support: skipping " << this->external_filename << endl;
  1231. 01231         return false;
  1232. 01232 #endif
  1233. 01233     } else if((strToUpr(this->external_filename).rfind(".JPG") == this->external_filename.size() - 4) ||
  1234. 01234               (strToUpr(this->external_filename).rfind(".JPEG") == this->external_filename.size() - 5)) {
  1235. 01235 #ifdef __HAVE_JPEG__
  1236. 01236         rc = readJPEG(this->external_filename.c_str(), &imgBuf, &imgWidth, &imgHeight, &imgPitch, &imgSize, &imgAlphaChannel);
  1237. 01237 #else
  1238. 01238         cout << "Disko was built without JPEG support: skipping " << this->external_filename << endl;
  1239. 01239         return false;
  1240. 01240 #endif
  1241. 01241     } else if((strToUpr(this->external_filename).rfind(".TIF") == this->external_filename.size() - 4) ||
  1242. 01242               (strToUpr(this->external_filename).rfind(".TIFF") == this->external_filename.size() - 5)) {
  1243. 01243 #ifdef __HAVE_TIFF__
  1244. 01244         rc = readTIFF(this->external_filename.c_str(), &imgBuf, &imgWidth, &imgHeight, &imgPitch, &imgSize, &imgAlphaChannel);
  1245. 01245 #else
  1246. 01246         cout << "Disko was built without TIFF support: skipping " << this->external_filename << endl;
  1247. 01247         return false;
  1248. 01248 #endif
  1249. 01249     } else {
  1250. 01250 #ifdef __HAVE_PNG__
  1251. 01251         rc = readPNG(this->external_filename.c_str(), &imgBuf, &imgWidth, &imgHeight, &imgPitch, &imgSize, &imgAlphaChannel);
  1252. 01252 #endif
  1253. 01253 #ifdef __HAVE_JPEG__
  1254. 01254         if(!rc) {
  1255. 01255             rc = readJPEG(this->external_filename.c_str(), &imgBuf, &imgWidth, &imgHeight, &imgPitch, &imgSize, &imgAlphaChannel);
  1256. 01256         }
  1257. 01257 #endif
  1258. 01258 #ifdef __HAVE_TIFF__
  1259. 01259         if(!rc) {
  1260. 01260             rc = readTIFF(this->external_filename.c_str(), &imgBuf, &imgWidth, &imgHeight, &imgPitch, &imgSize, &imgAlphaChannel);
  1261. 01261         }
  1262. 01262 #endif
  1263. 01263     }
  1264. 01264
  1265. 01265     if(rc) {
  1266. 01266         // open binary destination file
  1267. 01267         MMSFile *taff_file = NULL;
  1268. 01268         bool wok = true;
  1269. 01269         size_t ritems;
  1270. 01270         if (!this->taff_filename.empty()) {
  1271. 01271             taff_file = new MMSFile(this->taff_filename.c_str(), MMSFM_WRITE);
  1272. 01272             writeBuffer(taff_file, (void*)TAFF_IDENT, &ritems, 1, strlen(TAFF_IDENT), &wok);
  1273. 01273         }
  1274. 01274
  1275. 01275         if (!taff_file) {
  1276. 01276             // no regular file, so setup the buffer so that we have not to resize it
  1277. 01277             this->taff_buf_size = imgSize + 256;
  1278. 01278             this->taff_buf_pos = 0;
  1279. 01279             if (this->taff_buf) free(this->taff_buf);
  1280. 01280             this->taff_buf = (unsigned char *)malloc(this->taff_buf_size);
  1281. 01281         }
  1282. 01282
  1283. 01283         // write type and version
  1284. 01284         writeBuffer(taff_file, &(this->taff_desc->type), &ritems, 1, sizeof(this->taff_desc->type), &wok);
  1285. 01285         writeBuffer(taff_file, &(this->taff_desc->version), &ritems, 1, sizeof(this->taff_desc->version), &wok);
  1286. 01286
  1287. 01287         // write the tag
  1288. 01288         unsigned char wb[3];
  1289. 01289         wb[0]=MMSTAFF_TAGTABLE_TYPE_TAG;
  1290. 01290         wb[1]=MMSTAFF_IMAGE_TAGTABLE_TAG_RAWIMAGE;
  1291. 01291         writeBuffer(taff_file, wb, &ritems, 1, 2, &wok);
  1292. 01292
  1293. 01293         // write attributes: width
  1294. 01294         wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1295. 01295         wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_width;
  1296. 01296         wb[2]=sizeof(int);
  1297. 01297         writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1298. 01298         writeBuffer(taff_file, &imgWidth, &ritems, 1, sizeof(int), &wok);
  1299. 01299
  1300. 01300         // write attributes: height
  1301. 01301         wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1302. 01302         wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_height;
  1303. 01303         wb[2]=sizeof(int);
  1304. 01304         writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1305. 01305         writeBuffer(taff_file, &imgHeight, &ritems, 1, sizeof(int), &wok);
  1306. 01306
  1307. 01307         // write attributes: pitch
  1308. 01308         wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1309. 01309         wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_pitch;
  1310. 01310         wb[2]=sizeof(int);
  1311. 01311         writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1312. 01312         writeBuffer(taff_file, &imgPitch, &ritems, 1, sizeof(int), &wok);
  1313. 01313
  1314. 01314         // write attributes: size
  1315. 01315         wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1316. 01316         wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_size;
  1317. 01317         wb[2]=sizeof(int);
  1318. 01318         writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1319. 01319         writeBuffer(taff_file, &imgSize, &ritems, 1, sizeof(int), &wok);
  1320. 01320
  1321. 01321         // write attributes: pixelformat
  1322. 01322         wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1323. 01323         wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_pixelformat;
  1324. 01324         wb[2]=sizeof(int);
  1325. 01325         writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1326. 01326         int pf = (int)this->destination_pixelformat;
  1327. 01327         writeBuffer(taff_file, &pf, &ritems, 1, sizeof(int), &wok);
  1328. 01328
  1329. 01329         // write attributes: premultiplied
  1330. 01330         wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1331. 01331         wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_premultiplied;
  1332. 01332         wb[2]=sizeof(bool);
  1333. 01333         writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1334. 01334         bool pm = (this->destination_premultiplied);
  1335. 01335         writeBuffer(taff_file, &pm, &ritems, 1, sizeof(bool), &wok);
  1336. 01336
  1337. 01337         // write attributes: mirror_size
  1338. 01338         wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1339. 01339         wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_mirror_size;
  1340. 01340         wb[2]=sizeof(int);
  1341. 01341         writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1342. 01342         int ms = (int)this->mirror_size;
  1343. 01343         writeBuffer(taff_file, &ms, &ritems, 1, sizeof(int), &wok);
  1344. 01344
  1345. 01345         // write attributes: alphachannel
  1346. 01346         wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1347. 01347         wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_alphachannel;
  1348. 01348         wb[2]=sizeof(bool);
  1349. 01349         writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1350. 01350         writeBuffer(taff_file, &imgAlphaChannel, &ritems, 1, sizeof(bool), &wok);
  1351. 01351
  1352. 01352         // write attributes: rotate_180
  1353. 01353         wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1354. 01354         wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_rotate_180;
  1355. 01355         wb[2]=sizeof(bool);
  1356. 01356         writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1357. 01357         bool rot = (this->rotate_180);
  1358. 01358         writeBuffer(taff_file, &rot, &ritems, 1, sizeof(bool), &wok);
  1359. 01359
  1360. 01360         // write attributes: data
  1361. 01361         wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
  1362. 01362         wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_data;
  1363. 01363         wb[2]=0xff;
  1364. 01364         writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
  1365. 01365         writeBuffer(taff_file, &imgSize, &ritems, 1, sizeof(int), &wok);
  1366. 01366         writeBuffer(taff_file, imgBuf, &ritems, 1, imgSize, &wok);
  1367. 01367
  1368. 01368         // write the close tag
  1369. 01369         wb[0]=MMSTAFF_TAGTABLE_TYPE_CLOSETAG;
  1370. 01370         wb[1]=MMSTAFF_IMAGE_TAGTABLE_TAG_RAWIMAGE;
  1371. 01371         writeBuffer(taff_file, wb, &ritems, 1, 2, &wok);
  1372. 01372
  1373. 01373         // set rc
  1374. 01374         rc = wok;
  1375. 01375
  1376. 01376         // close file and free
  1377. 01377         if (taff_file) {
  1378. 01378             delete taff_file;
  1379. 01379         }
  1380. 01380         else {
  1381. 01381             // no regular file, set buffer values
  1382. 01382             this->taff_buf_size = this->taff_buf_pos;
  1383. 01383             this->taff_buf_pos = 0;
  1384. 01384             getFirstTag();
  1385. 01385             this->loaded = true;
  1386. 01386         }
  1387. 01387         free(imgBuf);
  1388. 01388
  1389. 01389         if (!rc) {
  1390. 01390             // failed, reset the file
  1391. 01391             if (!this->taff_filename.empty()) {
  1392. 01392                 taff_file = new MMSFile(this->taff_filename.c_str(), MMSFM_WRITE);
  1393. 01393                 if (taff_file) delete taff_file;
  1394. 01394             }
  1395. 01395         }
  1396. 01396     }
  1397. 01397     else {
  1398. 01398         printf("Error: cannot read external file %s\n", this->external_filename.c_str());
  1399. 01399     }
  1400. 01400
  1401. 01401     return rc;
  1402. 01402 }
  1403. 01403
  1404. 01404 bool MMSTaffFile::convertExternal2TAFF() {
  1405. 01405     switch (this->external_type) {
  1406. 01406     case MMSTAFF_EXTERNAL_TYPE_XML:
  1407. 01407         return convertXML2TAFF();
  1408. 01408     case MMSTAFF_EXTERNAL_TYPE_IMAGE:
  1409. 01409         return convertIMAGE2TAFF();
  1410. 01410     }
  1411. 01411     return false;
  1412. 01412 }
  1413. 01413
  1414. 01414 bool MMSTaffFile::convertTAFF2XML_throughDoc(int depth, int tagid, MMSFile *external_file) {
  1415. 01415     size_t ritems;
  1416. 01416     char wb[8*1024];
  1417. 01417
  1418. 01418     TAFF_TAGTABLE *tagt = &(this->taff_desc->tagtable[tagid]);
  1419. 01419     TAFF_ATTRDESC *attr = tagt->attr;
  1420. 01420
  1421. 01421     if (this->trace)
  1422. 01422         printf("Tag \"%s\" found, ID=%d\n", tagt->name, tagid);
  1423. 01423
  1424. 01424     /* write tag */
  1425. 01425     if (external_file) {
  1426. 01426         *wb = '\n';
  1427. 01427         memset(&wb[1], ' ', depth*4);
  1428. 01428         sprintf(&wb[1+depth*4], "<%s", tagt->name);
  1429. 01429         writeBuffer(external_file, wb, &ritems, 1, strlen(wb));
  1430. 01430     }
  1431. 01431
  1432. 01432     /* write attributes */
  1433. 01433     char *attrval_str;
  1434. 01434     int  attrval_int;
  1435. 01435     char *attr_name;
  1436. 01436     int  attrid;
  1437. 01437     while ((attrid = getNextAttribute(&attrval_str, &attrval_int, &attr_name)) >= 0) {
  1438. 01438         if (attrid != MMSTAFF_ATTR_WITHOUT_ID) {
  1439. 01439             string attrval;
  1440. 01440             switch (attr[attrid].type) {
  1441. 01441             case TAFF_ATTRTYPE_BOOL:
  1442. 01442                 if (attrval_int)
  1443. 01443                     attrval = "true";
  1444. 01444                 else
  1445. 01445                     attrval = "false";
  1446. 01446                 break;
  1447. 01447             case TAFF_ATTRTYPE_UCHAR:
  1448. 01448             case TAFF_ATTRTYPE_UCHAR100:
  1449. 01449             case TAFF_ATTRTYPE_INT:
  1450. 01450                 attrval = iToStr(attrval_int);
  1451. 01451                 break;
  1452. 01452             case TAFF_ATTRTYPE_STATE:
  1453. 01453                 if ((attrval_int & 0xff) == 0x01)
  1454. 01454                     attrval = "auto";
  1455. 01455                 else
  1456. 01456                 if (attrval_int)
  1457. 01457                     attrval = "true";
  1458. 01458                 else
  1459. 01459                     attrval = "false";
  1460. 01460                 break;
  1461. 01461             case TAFF_ATTRTYPE_SEQUENCE_MODE:
  1462. 01462                 if ((attrval_int & 0xff) == 0x01)
  1463. 01463                     attrval = "linear";
  1464. 01464                 else
  1465. 01465                 if ((attrval_int & 0xff) == 0x02)
  1466. 01466                     attrval = "log";
  1467. 01467                 else
  1468. 01468                 if ((attrval_int & 0xff) == 0x03)
  1469. 01469                     attrval = "log_soft_start";
  1470. 01470                 else
  1471. 01471                 if ((attrval_int & 0xff) == 0x04)
  1472. 01472                     attrval = "log_soft_end";
  1473. 01473                 else
  1474. 01474                 if (attrval_int)
  1475. 01475                     attrval = "true";
  1476. 01476                 else
  1477. 01477                     attrval = "false";
  1478. 01478                 break;
  1479. 01479             case TAFF_ATTRTYPE_COLOR:
  1480. 01480                 attrval = getMMSFBColorString(MMSFBColor((unsigned int)attrval_int));
  1481. 01481                 break;
  1482. 01482             default:
  1483. 01483                 attrval = attrval_str;
  1484. 01484                 break;
  1485. 01485             }
  1486. 01486
  1487. 01487             if (this->trace)
  1488. 01488                 printf(" Attribute \"%s\" found, ID=%d, value=\"%s\"\n", attr[attrid].name, attrid, attrval.c_str());
  1489. 01489
  1490. 01490             if (external_file) {
  1491. 01491                 *wb = '\n';
  1492. 01492                 memset(&wb[1], ' ', depth*4+4);
  1493. 01493                 sprintf(&wb[1+depth*4+4], "%s = \"%s\"", attr[attrid].name, attrval.c_str());
  1494. 01494                 writeBuffer(external_file, wb, &ritems, 1, strlen(wb));
  1495. 01495             }
  1496. 01496         }
  1497. 01497         else {
  1498. 01498             if (this->trace)
  1499. 01499                 printf(" Attribute \"%s\" found without ID, value=\"%s\"\n", attr_name, attrval_str);
  1500. 01500
  1501. 01501             if (external_file) {
  1502. 01502                 *wb = '\n';
  1503. 01503                 memset(&wb[1], ' ', depth*4+4);
  1504. 01504                 sprintf(&wb[1+depth*4+4], "%s = \"%s\"", attr_name, attrval_str);
  1505. 01505                 writeBuffer(external_file, wb, &ritems, 1, strlen(wb));
  1506. 01506             }
  1507. 01507         }
  1508. 01508     }
  1509. 01509
  1510. 01510     /* close tag */
  1511. 01511     if (external_file) {
  1512. 01512         sprintf(wb, ">\n");
  1513. 01513         writeBuffer(external_file, wb, &ritems, 1, strlen(wb));
  1514. 01514     }
  1515. 01515
  1516. 01516     /* through my child tags */
  1517. 01517     while (1) {
  1518. 01518         bool eof;
  1519. 01519         int tid = getNextTag(eof);
  1520. 01520         if (tid < 0) {
  1521. 01521             /* close tag */
  1522. 01522             if (external_file) {
  1523. 01523                 memset(wb, ' ', depth*4);
  1524. 01524                 sprintf(&wb[depth*4], "</%s>\n", tagt->name);
  1525. 01525                 writeBuffer(external_file, wb, &ritems, 1, strlen(wb));
  1526. 01526             }
  1527. 01527             return true;
  1528. 01528         }
  1529. 01529         if (convertTAFF2XML_throughDoc(depth+1, tid, external_file)==false)
  1530. 01530             return false;
  1531. 01531     }
  1532. 01532 }
  1533. 01533
  1534. 01534 bool MMSTaffFile::convertTAFF2XML() {
  1535. 01535     if (!this->loaded) return false;
  1536. 01536
  1537. 01537     /* get root tag */
  1538. 01538     int tagid = getFirstTag();
  1539. 01539     if (tagid < 0) return false;
  1540. 01540
  1541. 01541     /* open binary destination file */
  1542. 01542     MMSFile *external_file = NULL;
  1543. 01543     if (this->external_filename!="")
  1544. 01544         external_file = new MMSFile(this->external_filename.c_str(), MMSFM_WRITE);
  1545. 01545
  1546. 01546     /* start with root */
  1547. 01547     bool rc = convertTAFF2XML_throughDoc(0, tagid, external_file);
  1548. 01548
  1549. 01549     if (external_file)
  1550. 01550         delete external_file;
  1551. 01551
  1552. 01552     return rc;
  1553. 01553 }
  1554. 01554
  1555. 01555 bool MMSTaffFile::convertTAFF2External() {
  1556. 01556     switch (this->external_type) {
  1557. 01557     case MMSTAFF_EXTERNAL_TYPE_XML:
  1558. 01558         return convertTAFF2XML();
  1559. 01559     case MMSTAFF_EXTERNAL_TYPE_IMAGE:
  1560. 01560         printf("TAFF: Currently we cannot convert taff to image\n");
  1561. 01561         return false;
  1562. 01562     }
  1563. 01563     return false;
  1564. 01564 }
  1565. 01565
  1566. 01566 bool MMSTaffFile::readFile() {
  1567. 01567     if (this->taff_buf) {
  1568. 01568         free(this->taff_buf);
  1569. 01569         this->taff_buf = NULL;
  1570. 01570     }
  1571. 01571     this->loaded = false;
  1572. 01572
  1573. 01573     if (!this->taff_desc) return false;
  1574. 01574     if (this->taff_filename=="") return false;
  1575. 01575
  1576. 01576     // load the file
  1577. 01577     MMSFile *taff_file = new MMSFile(this->taff_filename.c_str(), MMSFM_READ, false);
  1578. 01578     if (!taff_file) return false;
  1579. 01579     size_t ritems;
  1580. 01580     char taff_ident[32];
  1581. 01581     if (!taff_file->readBuffer((void*)taff_ident, &ritems, 1, strlen(TAFF_IDENT))) {
  1582. 01582         // read error
  1583. 01583         this->taff_buf = NULL;
  1584. 01584         delete taff_file;
  1585. 01585         return false;
  1586. 01586     }
  1587. 01587     if (ritems == 0) {
  1588. 01588         // file is empty
  1589. 01589         printf("TAFF: File is empty (%s)\n", this->taff_filename.c_str());
  1590. 01590         this->taff_buf = NULL;
  1591. 01591         delete taff_file;
  1592. 01592         return false;
  1593. 01593     }
  1594. 01594     if (memcmp(taff_ident, TAFF_IDENT, strlen(TAFF_IDENT))!=0) {
  1595. 01595         // the first bytes of the file are different from TAFF_IDENT
  1596. 01596         printf("TAFF: TAFF_IDENT mismatch (%s)\n", this->taff_filename.c_str());
  1597. 01597         this->taff_buf = NULL;
  1598. 01598         delete taff_file;
  1599. 01599         return false;
  1600. 01600     }
  1601. 01601     if (!taff_file->readBufferEx((void**)&(this->taff_buf), &ritems)) {
  1602. 01602         // read error
  1603. 01603         this->taff_buf = NULL;
  1604. 01604         delete taff_file;
  1605. 01605         return false;
  1606. 01606     }
  1607. 01607     delete taff_file;
  1608. 01608
  1609. 01609     if (ritems < 40) {
  1610. 01610         // wrong size
  1611. 01611         free(this->taff_buf);
  1612. 01612         this->taff_buf = NULL;
  1613. 01613         return false;
  1614. 01614     }
  1615. 01615
  1616. 01616     // check the version of the file
  1617. 01617     this->correct_version = false;
  1618. 01618     if (strcmp((char*)this->taff_buf, (char*)&(this->taff_desc->type))) {
  1619. 01619         // wrong type
  1620. 01620         printf("TAFF: Wrong TAFF type (%s)\n", this->taff_filename.c_str());
  1621. 01621         free(this->taff_buf);
  1622. 01622         this->taff_buf = NULL;
  1623. 01623         return false;
  1624. 01624     }
  1625. 01625     if (memcmp(this->taff_buf+sizeof(this->taff_desc->type), &(this->taff_desc->version), sizeof(this->taff_desc->version))) {
  1626. 01626         // wrong version
  1627. 01627         free(this->taff_buf);
  1628. 01628         this->taff_buf = NULL;
  1629. 01629         return false;
  1630. 01630     }
  1631. 01631     this->correct_version = true;
  1632. 01632
  1633. 01633     // compare the modification time of the taff and external file
  1634. 01634     if (this->external_filename!="") {
  1635. 01635         struct stat statbuf1;
  1636. 01636         struct stat statbuf2;
  1637. 01637         if (stat(this->taff_filename.c_str(), &statbuf1)!=0) {
  1638. 01638             free(this->taff_buf);
  1639. 01639             this->taff_buf = NULL;
  1640. 01640             return false;
  1641. 01641         }
  1642. 01642         if (stat(this->external_filename.c_str(), &statbuf2)==0) {
  1643. 01643             if (statbuf2.st_mtime <= time(NULL)) {
  1644. 01644                 // ok, external file created in the past
  1645. 01645                 if (statbuf2.st_mtime >= statbuf1.st_mtime) {
  1646. 01646                     // external file has been modified, therefore the taff file maybe not up-to-date
  1647. 01647                     free(this->taff_buf);
  1648. 01648                     this->taff_buf = NULL;
  1649. 01649                     return false;
  1650. 01650                 }
  1651. 01651             }
  1652. 01652         }
  1653. 01653     }
  1654. 01654
  1655. 01655     // all right
  1656. 01656     this->taff_buf_size = ritems;
  1657. 01657     getFirstTag();
  1658. 01658     this->loaded = true;
  1659. 01659     return true;
  1660. 01660 }
  1661. 01661
  1662. 01662 bool MMSTaffFile::isLoaded() {
  1663. 01663     return this->loaded;
  1664. 01664 }
  1665. 01665
  1666. 01666 bool MMSTaffFile::checkVersion() {
  1667. 01667     return this->correct_version;
  1668. 01668 }
  1669. 01669
  1670. 01670 void MMSTaffFile::setExternal(string external_filename, MMSTAFF_EXTERNAL_TYPE external_type) {
  1671. 01671     this->external_filename = external_filename;
  1672. 01672     this->external_type = external_type;
  1673. 01673 }
  1674. 01674
  1675. 01675 void MMSTaffFile::setTrace(bool trace) {
  1676. 01676     this->trace = trace;
  1677. 01677 }
  1678. 01678
  1679. 01679 void MMSTaffFile::setPrintWarnings(bool print_warnings) {
  1680. 01680     this->print_warnings = print_warnings;
  1681. 01681 }
  1682. 01682
  1683. 01683 void MMSTaffFile::setDestinationPixelFormat(MMSTAFF_PF pixelformat, bool premultiplied) {
  1684. 01684     this->destination_pixelformat = pixelformat;
  1685. 01685     this->destination_premultiplied = premultiplied;
  1686. 01686 }
  1687. 01687
  1688. 01688 void MMSTaffFile::setMirrorEffect(int size) {
  1689. 01689     this->mirror_size = size;
  1690. 01690 }
  1691. 01691
  1692. 01692 void MMSTaffFile::rotate180(bool rotate_180) {
  1693. 01693     this->rotate_180 = rotate_180;
  1694. 01694 }
  1695. 01695
  1696. 01696 int MMSTaffFile::getFirstTag() {
  1697. 01697     this->taff_buf_pos = sizeof(this->taff_desc->type) + sizeof(this->taff_desc->version);
  1698. 01698     this->current_tag = -1;
  1699. 01699     this->current_tag_pos = 0;
  1700. 01700
  1701. 01701     if (this->taff_buf[this->taff_buf_pos] == MMSTAFF_TAGTABLE_TYPE_TAG) {
  1702. 01702         bool eof;
  1703. 01703         return getNextTag(eof);
  1704. 01704     }
  1705. 01705
  1706. 01706     return this->current_tag;
  1707. 01707 }
  1708. 01708
  1709. 01709 int MMSTaffFile::getNextTag(bool &eof) {
  1710. 01710     /* searching for next tag */
  1711. 01711     eof = false;
  1712. 01712     while (this->taff_buf_pos < this->taff_buf_size) {
  1713. 01713         switch (this->taff_buf[this->taff_buf_pos]) {
  1714. 01714         case MMSTAFF_TAGTABLE_TYPE_TAG:
  1715. 01715             this->current_tag = this->taff_buf[this->taff_buf_pos+1];
  1716. 01716             this->current_tag_pos = this->taff_buf_pos;
  1717. 01717             this->taff_buf_pos+=2;
  1718. 01718             return this->current_tag;
  1719. 01719         case MMSTAFF_TAGTABLE_TYPE_ATTR: {
  1720. 01720                 this->taff_buf_pos+=2;
  1721. 01721                 int len;
  1722. 01722
  1723. 01723                 /* check if name of attribute is stored instead of id */
  1724. 01724                 if (this->taff_buf[this->taff_buf_pos-1] == MMSTAFF_ATTR_WITHOUT_ID) {
  1725. 01725                     len = MMSTAFF_INT32_FROM_UCHAR_STREAM(&this->taff_buf[this->taff_buf_pos]);
  1726. 01726                     this->taff_buf_pos+=sizeof(int);
  1727. 01727                     this->taff_buf_pos+=len;
  1728. 01728                 }
  1729. 01729
  1730. 01730                 /* get the length of the value */
  1731. 01731                 len = (int)this->taff_buf[this->taff_buf_pos];
  1732. 01732                 this->taff_buf_pos++;
  1733. 01733                 if (len >= 0xff) {
  1734. 01734                     len = MMSTAFF_INT32_FROM_UCHAR_STREAM(&this->taff_buf[this->taff_buf_pos]);
  1735. 01735                     this->taff_buf_pos+=sizeof(int);
  1736. 01736                 }
  1737. 01737                 this->taff_buf_pos+=len;
  1738. 01738             }
  1739. 01739             break;
  1740. 01740         case MMSTAFF_TAGTABLE_TYPE_CLOSETAG:
  1741. 01741             this->current_tag = -1;
  1742. 01742             this->taff_buf_pos+=2;
  1743. 01743             eof = false;
  1744. 01744             return this->current_tag;
  1745. 01745         default:
  1746. 01746             this->current_tag = -1;
  1747. 01747             this->current_tag_pos = 0;
  1748. 01748             eof = true;
  1749. 01749             return this->current_tag;
  1750. 01750         }
  1751. 01751     }
  1752. 01752     this->current_tag = -1;
  1753. 01753     this->current_tag_pos = 0;
  1754. 01754     eof = true;
  1755. 01755     return this->current_tag;
  1756. 01756 }
  1757. 01757
  1758. 01758 int MMSTaffFile::getCurrentTag(const char **name) {
  1759. 01759     if (name) *name = this->taff_desc->tagtable[this->current_tag].name;
  1760. 01760     return this->current_tag;
  1761. 01761 }
  1762. 01762
  1763. 01763 const char *MMSTaffFile::getCurrentTagName() {
  1764. 01764     return this->taff_desc->tagtable[this->current_tag].name;
  1765. 01765 }
  1766. 01766
  1767. 01767 MMSTaffFile *MMSTaffFile::copyCurrentTag() {
  1768. 01768     MMSTaffFile *mytafff = NULL;
  1769. 01769     int tag_cnt, closetag_cnt;
  1770. 01770
  1771. 01771     if (!this->current_tag_pos)
  1772. 01772         return NULL;
  1773. 01773
  1774. 01774     /* save buffer positions */
  1775. 01775     int saved_taff_buf_pos = this->taff_buf_pos;
  1776. 01776     int saved_current_tag = this->current_tag;
  1777. 01777     int saved_current_tag_pos = this->current_tag_pos;
  1778. 01778
  1779. 01779     /* go to the position after the current tag */
  1780. 01780     this->taff_buf_pos = this->current_tag_pos;
  1781. 01781
  1782. 01782     /* searching the close tag of this tag */
  1783. 01783     tag_cnt = 0;
  1784. 01784     closetag_cnt = 0;
  1785. 01785     do {
  1786. 01786         bool eof;
  1787. 01787         if (getNextTag(eof) < 0) {
  1788. 01788             if (eof) break;
  1789. 01789             closetag_cnt++;
  1790. 01790         }
  1791. 01791         else
  1792. 01792             tag_cnt++;
  1793. 01793     } while (tag_cnt > closetag_cnt);
  1794. 01794
  1795. 01795     /* all right? */
  1796. 01796     if (tag_cnt == closetag_cnt) {
  1797. 01797         /* yes, allocate memory and copy buffer */
  1798. 01798         mytafff = new MMSTaffFile("", this->taff_desc, "", this->external_type,
  1799. 01799                                   this->ignore_blank_values, this->trace, false);
  1800. 01800         if (mytafff) {
  1801. 01801             int len = this->taff_buf_pos - saved_current_tag_pos;
  1802. 01802             mytafff->taff_buf_size = sizeof(this->taff_desc->type) + sizeof(this->taff_desc->version) + len;
  1803. 01803             mytafff->taff_buf = (unsigned char *)malloc(mytafff->taff_buf_size);
  1804. 01804             if (mytafff->taff_buf) {
  1805. 01805                 /* copy & init */
  1806. 01806                 memcpy(mytafff->taff_buf, this->taff_buf, sizeof(this->taff_desc->type) + sizeof(this->taff_desc->version));
  1807. 01807                 memcpy(&(mytafff->taff_buf[sizeof(this->taff_desc->type) + sizeof(this->taff_desc->version)]),
  1808. 01808                        &(this->taff_buf[saved_current_tag_pos]), len);
  1809. 01809                 mytafff->getFirstTag();
  1810. 01810                 mytafff->loaded = true;
  1811. 01811                 mytafff->correct_version = true;
  1812. 01812             }
  1813. 01813             else {
  1814. 01814                 /* out of memory */
  1815. 01815                 delete mytafff;
  1816. 01816                 mytafff = NULL;
  1817. 01817             }
  1818. 01818         }
  1819. 01819     }
  1820. 01820
  1821. 01821     /* restore the old buffer positions */
  1822. 01822     this->taff_buf_pos = saved_taff_buf_pos;
  1823. 01823     this->current_tag = saved_current_tag;
  1824. 01824     this->current_tag_pos = saved_current_tag_pos;
  1825. 01825
  1826. 01826     return mytafff;
  1827. 01827 }
  1828. 01828
  1829. 01829
  1830. 01830 bool MMSTaffFile::hasAttributes() {
  1831. 01831     char *value_str;
  1832. 01832     int value_int;
  1833. 01833     char *name;
  1834. 01834     return (getFirstAttribute(&value_str, &value_int, &name) >= 0);
  1835. 01835 }
  1836. 01836
  1837. 01837
  1838. 01838 int MMSTaffFile::getFirstAttribute(char **value_str, int *value_int, char **name) {
  1839. 01839     if (!this->current_tag_pos)
  1840. 01840         return -1;
  1841. 01841
  1842. 01842     /* go to the position after the current tag */
  1843. 01843     this->taff_buf_pos = this->current_tag_pos;
  1844. 01844     this->taff_buf_pos+=2;
  1845. 01845
  1846. 01846     /* get the attribute */
  1847. 01847     if (this->taff_buf[this->taff_buf_pos] == MMSTAFF_TAGTABLE_TYPE_ATTR)
  1848. 01848         return getNextAttribute(value_str, value_int, name);
  1849. 01849
  1850. 01850     return -1;
  1851. 01851 }
  1852. 01852
  1853. 01853 int MMSTaffFile::getNextAttribute(char **value_str, int *value_int, char **name) {
  1854. 01854     /* searching for next attribute */
  1855. 01855     do {
  1856. 01856         switch (this->taff_buf[this->taff_buf_pos]) {
  1857. 01857         case MMSTAFF_TAGTABLE_TYPE_ATTR: {
  1858. 01858                 int attrid = (int)this->taff_buf[this->taff_buf_pos+1];
  1859. 01859                 int len;
  1860. 01860                 this->taff_buf_pos+=2;
  1861. 01861
  1862. 01862                 /* check if name of attribute is stored instead of id */
  1863. 01863                 if (attrid == MMSTAFF_ATTR_WITHOUT_ID) {
  1864. 01864                     len = MMSTAFF_INT32_FROM_UCHAR_STREAM(&this->taff_buf[this->taff_buf_pos]);
  1865. 01865                     this->taff_buf_pos+=sizeof(int);
  1866. 01866                     if (name)
  1867. 01867                         *name = (char*)&this->taff_buf[this->taff_buf_pos];
  1868. 01868                     this->taff_buf_pos+=len;
  1869. 01869                 }
  1870. 01870                 else
  1871. 01871                     if (name) *name=NULL;
  1872. 01872
  1873. 01873                 /* get the length of the value */
  1874. 01874                 len = (int)this->taff_buf[this->taff_buf_pos];
  1875. 01875                 this->taff_buf_pos++;
  1876. 01876                 if (len >= 0xff) {
  1877. 01877                     len = MMSTAFF_INT32_FROM_UCHAR_STREAM(&this->taff_buf[this->taff_buf_pos]);
  1878. 01878                     this->taff_buf_pos+=sizeof(int);
  1879. 01879                 }
  1880. 01880
  1881. 01881                 /* check the type of value and set the return values */
  1882. 01882                 if (attrid != MMSTAFF_ATTR_WITHOUT_ID) {
  1883. 01883                     TAFF_ATTRDESC *attr = this->taff_desc->tagtable[current_tag].attr;
  1884. 01884                     switch (attr[attrid].type) {
  1885. 01885                     case TAFF_ATTRTYPE_BOOL:
  1886. 01886                     case TAFF_ATTRTYPE_UCHAR:
  1887. 01887                     case TAFF_ATTRTYPE_UCHAR100:
  1888. 01888                     case TAFF_ATTRTYPE_STATE:
  1889. 01889                     case TAFF_ATTRTYPE_SEQUENCE_MODE:
  1890. 01890                         *value_str = NULL;
  1891. 01891                         {   unsigned char v = this->taff_buf[this->taff_buf_pos];
  1892. 01892                             *value_int = (int)v; }
  1893. 01893                         break;
  1894. 01894                     case TAFF_ATTRTYPE_INT:
  1895. 01895                     case TAFF_ATTRTYPE_COLOR:
  1896. 01896                         *value_str = NULL;
  1897. 01897                         *value_int = MMSTAFF_INT32_FROM_UCHAR_STREAM(&this->taff_buf[this->taff_buf_pos]);
  1898. 01898                         break;
  1899. 01899                     default:
  1900. 01900                         *value_str = (char*)&this->taff_buf[this->taff_buf_pos];
  1901. 01901                         break;
  1902. 01902                     }
  1903. 01903                 }
  1904. 01904                 else
  1905. 01905                 if (name) {
  1906. 01906                     *value_str = (char*)&this->taff_buf[this->taff_buf_pos];
  1907. 01907                 }
  1908. 01908                 this->taff_buf_pos+=len;
  1909. 01909
  1910. 01910                 if (!((attrid == MMSTAFF_ATTR_WITHOUT_ID)&&(!name)))
  1911. 01911                     /* return attribute ID */
  1912. 01912                     return attrid;
  1913. 01913
  1914. 01914                 /* attribute has no ID and name is not set, go to the next attribute */
  1915. 01915                 break;
  1916. 01916             }
  1917. 01917             break;
  1918. 01918         default:
  1919. 01919             return -1;
  1920. 01920         }
  1921. 01921     } while (this->taff_buf_pos < this->taff_buf_size);
  1922. 01922     return -1;
  1923. 01923 }
  1924. 01924
  1925. 01925 bool MMSTaffFile::getAttribute(int id, char **value_str, int *value_int) {
  1926. 01926     char *attr_name;
  1927. 01927     int attrid = getFirstAttribute(value_str, value_int, &attr_name);
  1928. 01928     while (attrid >= 0) {
  1929. 01929         if (attrid == id)
  1930. 01930             return true;
  1931. 01931         attrid = getNextAttribute(value_str, value_int, &attr_name);
  1932. 01932     }
  1933. 01933     return false;
  1934. 01934 }
  1935. 01935
  1936. 01936 char *MMSTaffFile::getAttributeString(int id) {
  1937. 01937     char *value_str = NULL;
  1938. 01938     int  value_int;
  1939. 01939     if (getAttribute(id, &value_str, &value_int))
  1940. 01940         if (value_str)
  1941. 01941             return value_str;
  1942. 01942     return NULL;
  1943. 01943 }
  1944. 01944
  1945. 01945
  1946. 01946 TAFF_ATTRDESC MMSTAFF_IMAGE_RAWIMAGE_ATTR_I[]   = MMSTAFF_IMAGE_RAWIMAGE_ATTR_INIT;
  1947. 01947
  1948. 01948 TAFF_TAGTABLE mmstaff_image_taff_tagtable[] = {
  1949. 01949     {   "rawimage",     NULL,   NULL,           MMSTAFF_IMAGE_RAWIMAGE_ATTR_I   },
  1950. 01950     {   NULL,           NULL,   NULL,           NULL                            }
  1951. 01951 };
  1952. 01952
  1953. 01953 TAFF_DESCRIPTION mmstaff_image_taff_description = { "mmstaff_image", 4, mmstaff_image_taff_tagtable };
  1954. 01954
  1955. 01955
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement