Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 00001 /***************************************************************************
- 00002 * Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider, *
- 00003 * Matthias Hardt, Guido Madaus *
- 00004 * *
- 00005 * Copyright (C) 2007-2008 BerLinux Solutions GbR *
- 00006 * Stefan Schwarzer & Guido Madaus *
- 00007 * *
- 00008 * Copyright (C) 2009-2012 BerLinux Solutions GmbH *
- 00009 * *
- 00010 * Authors: *
- 00011 * Stefan Schwarzer <stefan.schwarzer@diskohq.org>, *
- 00012 * Matthias Hardt <matthias.hardt@diskohq.org>, *
- 00013 * Jens Schneider <jens.schneider@diskohq.org>, *
- 00014 * Guido Madaus <guido.madaus@diskohq.org>, *
- 00015 * Patrick Helterhoff <patrick.helterhoff@diskohq.org>, *
- 00016 * René Bählkow <rene.baehlkow@diskohq.org> *
- 00017 * *
- 00018 * This library is free software; you can redistribute it and/or *
- 00019 * modify it under the terms of the GNU Lesser General Public *
- 00020 * License version 2.1 as published by the Free Software Foundation. *
- 00021 * *
- 00022 * This library is distributed in the hope that it will be useful, *
- 00023 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- 00024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- 00025 * Lesser General Public License for more details. *
- 00026 * *
- 00027 * You should have received a copy of the GNU Lesser General Public *
- 00028 * License along with this library; if not, write to the *
- 00029 * Free Software Foundation, Inc., *
- 00030 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- 00031 **************************************************************************/
- 00032
- 00033 #include "mmstools/mmstafffile.h"
- 00034 #include "mmstools/tools.h"
- 00035 #include <sys/types.h>
- 00036 #include <sys/stat.h>
- 00037 #include <unistd.h>
- 00038 #include <libxml/parser.h>
- 00039 #include <libxml/tree.h>
- 00040 #include <cstring>
- 00041 #include <iostream>
- 00042
- 00043 #ifdef __HAVE_PNG__
- 00044 #include <png.h>
- 00045 #endif
- 00046
- 00047 #ifdef __HAVE_JPEG__
- 00048 #include <csetjmp>
- 00049 extern "C" {
- 00050 #include <jpeglib.h>
- 00051 }
- 00052 #endif
- 00053
- 00054 #ifdef __HAVE_TIFF__
- 00055 extern "C" {
- 00056 #include <tiffio.h>
- 00057 }
- 00058 #endif
- 00059
- 00060 MMSTaffFile::MMSTaffFile(string taff_filename, TAFF_DESCRIPTION *taff_desc,
- 00061 string external_filename, MMSTAFF_EXTERNAL_TYPE external_type,
- 00062 bool ignore_blank_values, bool trace, bool print_warnings,
- 00063 bool force_rewrite_taff, bool auto_rewrite_taff) {
- 00064 this->taff_filename = taff_filename;
- 00065 this->taff_desc = taff_desc;
- 00066 this->taff_buf = NULL;
- 00067 this->taff_buf_size = 0;
- 00068 this->taff_buf_pos = 0;
- 00069 this->loaded = false;
- 00070 this->correct_version = false;
- 00071 this->external_filename = external_filename;
- 00072 this->external_type = external_type;
- 00073 this->ignore_blank_values = ignore_blank_values;
- 00074 this->trace = trace;
- 00075 this->print_warnings = print_warnings;
- 00076 this->destination_pixelformat = MMSTAFF_PF_ARGB;
- 00077 this->destination_premultiplied = true;
- 00078 this->mirror_size = 0;
- 00079 this->rotate_180 = false;
- 00080 this->correct_version = false;
- 00081 this->current_tag = -1;
- 00082 this->current_tag_pos = 0;
- 00083
- 00084 if (!this->taff_desc)
- 00085 if (this->external_type == MMSTAFF_EXTERNAL_TYPE_IMAGE)
- 00086 this->taff_desc = &mmstaff_image_taff_description;
- 00087
- 00088 if ((this->taff_filename == "")&&(this->external_filename == ""))
- 00089 return;
- 00090
- 00091 // read the file into taff_buf
- 00092 bool ret = false;
- 00093 if (!force_rewrite_taff)
- 00094 ret = readFile();
- 00095 if (!ret)
- 00096 // failed or rewrite, try to convert from external_filename
- 00097 if ((force_rewrite_taff)||(auto_rewrite_taff)) {
- 00098 if (convertExternal2TAFF()) {
- 00099 if (this->taff_filename != "") {
- 00100 // auto read in
- 00101 readFile();
- 00102 }
- 00103 }
- 00104 }
- 00105 }
- 00106
- 00107 MMSTaffFile::~MMSTaffFile() {
- 00108 if (this->taff_buf)
- 00109 free(this->taff_buf);
- 00110 }
- 00111
- 00112 bool MMSTaffFile::writeBuffer(MMSFile *mmsfile, void *ptr, size_t *ritems, size_t size, size_t nitems, bool *write_status) {
- 00113
- 00114 if (mmsfile) {
- 00115 // writing to file
- 00116 if (!mmsfile->writeBuffer(ptr, ritems, size, nitems)) {
- 00117 // error while writing file
- 00118 printf("TAFF: Error while writing to file %s\n", mmsfile->getName().c_str());
- 00119 if (write_status) *write_status = false;
- 00120 return false;
- 00121 }
- 00122 }
- 00123 else {
- 00124 // writing to taff_buf
- 00125 memcpy(&this->taff_buf[taff_buf_pos], ptr, size * nitems);
- 00126 this->taff_buf_pos+= size * nitems;
- 00127
- 00128 //TODO: check the taff_buf_size and realloc the buffer if taff_buf_size is to small
- 00129 }
- 00130
- 00131 return true;
- 00132 }
- 00133
- 00134 bool MMSTaffFile::postprocessImage(void **buf, int *width, int *height, int *pitch,
- 00135 int *size, bool *alphachannel) {
- 00136
- 00137 // should i pre-multiply with alpha channel?
- 00138 if (this->destination_premultiplied && (*alphachannel == true)) {
- 00139 unsigned int *src = (unsigned int*)*buf;
- 00140 for (int i = *width * *height; i > 0; i--) {
- 00141 register unsigned int s = *src;
- 00142 register unsigned int sa = s >> 24;
- 00143 if (sa != 0xff)
- 00144 // source alpha is > 0x00 and < 0xff
- 00145 *src = ((((s & 0x00ff00ff) * sa) >> 8) & 0x00ff00ff) |
- 00146 ((((s & 0x0000ff00) * sa) >> 8) & 0x0000ff00) |
- 00147 ((((s & 0xff000000))));
- 00148 src++;
- 00149 }
- 00150 }
- 00151
- 00152 // should create a mirror effect?
- 00153 if (this->mirror_size > 0) {
- 00154 // yes
- 00155 unsigned int *dst = (unsigned int*)*buf;
- 00156 dst+=*width * *height;
- 00157 unsigned int *src = dst - *width;
- 00158 unsigned int alpha = 170;
- 00159 unsigned int alphaX = 0x050 / this->mirror_size;
- 00160 if (0x050 % this->mirror_size >= (this->mirror_size >> 1))
- 00161 alphaX++;
- 00162 if (alphaX == 0) alphaX = 1;
- 00163 for (int i = 0; i < this->mirror_size; i++) {
- 00164 for (int j = 0; j < *width; j++) {
- 00165 register unsigned int s = *src;
- 00166 register unsigned int sa = s >> 24;
- 00167 *dst = (s & 0x00ffffff) | (((sa > alpha)?(sa-alpha):0)<<24);
- 00168 dst++;
- 00169 src++;
- 00170 }
- 00171 src-=(*width) << 1;
- 00172 alpha+=alphaX;
- 00173 }
- 00174
- 00175 // set new values
- 00176 *height = (*height) + this->mirror_size;
- 00177 *size = (*pitch) * (*height);
- 00178 }
- 00179
- 00180 if (this->rotate_180) {
- 00181 // rotate the image by 180 degree
- 00182 rotateUIntBuffer180((unsigned int*)*buf, *pitch, *width, *height);
- 00183 }
- 00184
- 00185 // have to convert the pixelformat?
- 00186 bool has_alpha = false;
- 00187 switch (this->destination_pixelformat) {
- 00188 case MMSTAFF_PF_ARGB:
- 00189 if (*alphachannel) {
- 00190 // no convertion, only have to check if we have really an alpha channel
- 00191 unsigned int *src = (unsigned int*)*buf;
- 00192 for (int i = *width * *height; i > 0; i--) {
- 00193 register unsigned int s = *src;
- 00194 s = s >> 24;
- 00195 if (s != 0xff) has_alpha = true;
- 00196 if (has_alpha) break;
- 00197 src++;
- 00198 }
- 00199 }
- 00200 break;
- 00201 case MMSTAFF_PF_AiRGB: {
- 00202 // invert the alpha channel
- 00203 unsigned int *src = (unsigned int*)*buf;
- 00204 for (int i = *width * *height; i > 0; i--) {
- 00205 register unsigned int s = *src;
- 00206 register unsigned int a = s;
- 00207 a = ~a;
- 00208 a = a & 0xff000000;
- 00209 if (a && !has_alpha) has_alpha = true;
- 00210 s = s & 0x00ffffff;
- 00211 s = s | a;
- 00212 *src = s;
- 00213 src++;
- 00214 }
- 00215 }
- 00216 break;
- 00217 case MMSTAFF_PF_AYUV: {
- 00218 // convert RGB to YUV color space
- 00219 unsigned int *src = (unsigned int*)*buf;
- 00220 for (int i = *width * *height; i > 0; i--) {
- 00221 register unsigned int s = *src;
- 00222 register int r = (s >> 16) & 0xff;
- 00223 register int g = (s >> 8) & 0xff;
- 00224 register int b = s & 0xff;
- 00225 if (!has_alpha)
- 00226 if ((s >> 24) != 0xff) has_alpha = true;
- 00227 s = s & 0xff000000; //A
- 00228 if (s) {
- 00229 s = s | (((((66*r+129*g+25*b+128)>>8)+16) & 0xff) << 16); //Y
- 00230 s = s | (((((-38*r-74*g+112*b+128)>>8)+128) & 0xff) << 8); //U (Cb)
- 00231 s = s | ((((112*r-94*g-18*b+128)>>8)+128) & 0xff); //V (Cr)
- 00232 }
- 00233 *src = s;
- 00234 src++;
- 00235 }
- 00236 }
- 00237 break;
- 00238 case MMSTAFF_PF_ARGB4444: {
- 00239 // divide ARGB data into halves
- 00240 *pitch = (*pitch) >> 1;
- 00241 *size = (*size) >> 1;
- 00242 void *newbuf = malloc(*size);
- 00243 if (!newbuf) {
- 00244 free(*buf);
- 00245 *buf = NULL;
- 00246 return false;
- 00247 }
- 00248
- 00249 // convert it
- 00250 unsigned int *src = (unsigned int*)*buf;
- 00251 unsigned short int *dst = (unsigned short int*)newbuf;
- 00252 for (int i = *width * *height; i > 0; i--) {
- 00253 register unsigned int s = *src;
- 00254 register unsigned short int d;
- 00255 if (!has_alpha)
- 00256 if ((s >> 28) != 0x0f) has_alpha = true;
- 00257 d = ((s & 0xf0000000) >> 16)
- 00258 | ((s & 0x00f00000) >> 12)
- 00259 | ((s & 0x0000f000) >> 8)
- 00260 | ((s & 0x000000f0) >> 4);
- 00261 *dst = d;
- 00262 src++;
- 00263 dst++;
- 00264 }
- 00265
- 00266 // switch buffers
- 00267 free(*buf);
- 00268 *buf = newbuf;
- 00269 }
- 00270 break;
- 00271 case MMSTAFF_PF_RGB16: {
- 00272 // convert into RGB16 format (remove alpha channel)
- 00273 *pitch = (*pitch) >> 1;
- 00274 *size = (*size) >> 1;
- 00275 void *newbuf = malloc(*size);
- 00276 if (!newbuf) {
- 00277 free(*buf);
- 00278 *buf = NULL;
- 00279 return false;
- 00280 }
- 00281
- 00282 // convert it
- 00283 unsigned int *src = (unsigned int*)*buf;
- 00284 unsigned short int *dst = (unsigned short int*)newbuf;
- 00285 for (int i = *width * *height; i > 0; i--) {
- 00286 // get src
- 00287 register unsigned int SRC = *src;
- 00288 register unsigned int A = SRC >> 24;
- 00289 register unsigned int SA= 0x100 - A;
- 00290 register unsigned short int d;
- 00291
- 00292 // set background color to black
- 00293 unsigned int r = 0;
- 00294 unsigned int g = 0;
- 00295 unsigned int b = 0;
- 00296
- 00297 // invert src alpha
- 00298 r = SA * r;
- 00299 g = SA * g;
- 00300 b = (SA * b) >> 5;
- 00301
- 00302 // add src to dst
- 00303 r += (A*(SRC & 0xf80000)) >> 19;
- 00304 g += (A*(SRC & 0xfc00)) >> 5;
- 00305 b += (A*(SRC & 0xf8)) >> 8;
- 00306 d = ((r & 0xffe000) ? 0xf800 : ((r >> 8) << 11))
- 00307 | ((g & 0xfff80000) ? 0x07e0 : ((g >> 13) << 5))
- 00308 | ((b & 0xff00) ? 0x1f : (b >> 3));
- 00309 *dst = d;
- 00310 src++;
- 00311 dst++;
- 00312 }
- 00313
- 00314 // switch buffers
- 00315 free(*buf);
- 00316 *buf = newbuf;
- 00317 }
- 00318 break;
- 00319 case MMSTAFF_PF_ABGR: {
- 00320 // change the positions of red and blue
- 00321 // for example disko's ABGR is equal to GL_RGBA in OpenGL
- 00322 unsigned int *src = (unsigned int*)*buf;
- 00323 for (int i = *width * *height; i > 0; i--) {
- 00324 register unsigned int s = *src;
- 00325 register unsigned int rb = s & 0x00ff00ff;
- 00326 if (!has_alpha)
- 00327 if ((s >> 24) != 0xff) has_alpha = true;
- 00328 s = s & 0xff00ff00;
- 00329 s = s | (rb << 16);
- 00330 s = s | (rb >> 16);
- 00331 *src = s;
- 00332 src++;
- 00333 }
- 00334 }
- 00335 break;
- 00336 default: break;
- 00337 }
- 00338
- 00339 if (*alphachannel) {
- 00340 // per input parameter we assumed, that we have an alpha channel
- 00341 // here we overwrite it with the result from the previous check
- 00342 // so it can be, that we have an image with alpha channel but all alpha values are 0xff
- 00343 // in this case we mark the image with "no alpha channel"
- 00344 *alphachannel = has_alpha;
- 00345 }
- 00346
- 00347 return true;
- 00348 }
- 00349
- 00350
- 00351
- 00352 #ifdef __HAVE_PNG__
- 00353 // PNG callback function (read)
- 00354 // so we are able to read data with MMSFile class instead of standard FILE*
- 00355 void MMSTaff_read_png_data_callback(png_structp png_ptr, png_bytep data, png_size_t length) {
- 00356 MMSFile *file = (MMSFile *)png_get_io_ptr(png_ptr);
- 00357 size_t ritems;
- 00358 file->readBuffer((void *)data, &ritems, 1, length);
- 00359 }
- 00360 #endif
- 00361
- 00362
- 00363
- 00364 bool MMSTaffFile::readPNG(const char *filename, void **buf, int *width, int *height, int *pitch,
- 00365 int *size, bool *alphachannel) {
- 00366 #ifdef __HAVE_PNG__
- 00367 MMSFile *file;
- 00368 char png_sig[8];
- 00369 png_structp png_ptr = NULL;
- 00370 png_infop info_ptr = NULL;
- 00371 png_infop end_info_ptr = NULL;
- 00372 png_bytep *row_pointers = NULL;
- 00373
- 00374 // check if file does exist and if it is an png format
- 00375 *buf = NULL;
- 00376 file = new MMSFile(filename);
- 00377 if (!file) {
- 00378 return false;
- 00379 }
- 00380 if (file->getLastError()) {
- 00381 return false;
- 00382 }
- 00383
- 00384 size_t ritems = 0;
- 00385 if (file->readBuffer(png_sig, &ritems, 1, sizeof(png_sig))) {
- 00386 if (ritems != sizeof(png_sig)) {
- 00387 delete file;
- 00388 return false;
- 00389 }
- 00390 }
- 00391 else {
- 00392 delete file;
- 00393 return false;
- 00394 }
- 00395
- 00396 #if PNG_LIBPNG_VER_MINOR == 2
- 00397 if (!png_check_sig((png_byte*)png_sig, sizeof(png_sig))) {
- 00398 #else
- 00399 if (png_sig_cmp((png_byte*)png_sig, 0, sizeof(png_sig)) != 0) {
- 00400 #endif
- 00401 delete file;
- 00402 return false;
- 00403 }
- 00404
- 00405
- 00406 // init png structs and abend handler
- 00407 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- 00408 if (!png_ptr) {
- 00409 delete file;
- 00410 return false;
- 00411 }
- 00412 png_set_sig_bytes(png_ptr, sizeof(png_sig));
- 00413
- 00414 // set read callback function
- 00415 png_set_read_fn(png_ptr, file, MMSTaff_read_png_data_callback);
- 00416
- 00417 if(setjmp(png_jmpbuf(png_ptr))) {
- 00418 // abend from libpng
- 00419 printf("png read error\n");
- 00420 png_destroy_read_struct(&png_ptr, (info_ptr)?&info_ptr:NULL, (end_info_ptr)?&end_info_ptr:NULL);
- 00421 if (row_pointers) free(row_pointers);
- 00422 if (*buf) free(*buf);
- 00423 *buf = NULL;
- 00424 delete file;
- 00425 return false;
- 00426 }
- 00427
- 00428 info_ptr = png_create_info_struct(png_ptr);
- 00429 if (!info_ptr) {
- 00430 png_destroy_read_struct(&png_ptr, NULL, NULL);
- 00431 delete file;
- 00432 return false;
- 00433 }
- 00434
- 00435 end_info_ptr = png_create_info_struct(png_ptr);
- 00436 if (!end_info_ptr) {
- 00437 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- 00438 delete file;
- 00439 return false;
- 00440 }
- 00441
- 00442 // read png infos
- 00443 png_read_info(png_ptr, info_ptr);
- 00444 png_uint_32 w;
- 00445 png_uint_32 h;
- 00446 int bit_depth;
- 00447 int color_type;
- 00448 png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, NULL, NULL, NULL);
- 00449
- 00450 // check the png format
- 00451 if ((bit_depth != 8 && bit_depth != 16)
- 00452 || (color_type != PNG_COLOR_TYPE_PALETTE && color_type != PNG_COLOR_TYPE_GRAY
- 00453 && color_type != PNG_COLOR_TYPE_RGB && color_type != PNG_COLOR_TYPE_RGB_ALPHA)) {
- 00454 // format not supported
- 00455 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);
- 00456 delete file;
- 00457 return false;
- 00458 }
- 00459
- 00460 // set input transformations
- 00461 if (bit_depth == 16) {
- 00462 // strip to 8 bit channels
- 00463 png_set_strip_16(png_ptr);
- 00464 }
- 00465 png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER);
- 00466
- 00467 #if __BYTE_ORDER == __BIG_ENDIAN
- 00468 png_set_swap_alpha(png_ptr);
- 00469 #else
- 00470 png_set_bgr(png_ptr);
- 00471 #endif
- 00472
- 00473 png_set_interlace_handling(png_ptr);
- 00474 if (color_type == PNG_COLOR_TYPE_PALETTE) {
- 00475 // convert palette to rgb data
- 00476 png_set_palette_to_rgb(png_ptr);
- 00477 }
- 00478 if (color_type == PNG_COLOR_TYPE_GRAY) {
- 00479 // convert grayscale to rgb data
- 00480 png_set_gray_to_rgb(png_ptr);
- 00481 }
- 00482
- 00483 *alphachannel = true;
- 00484 if (color_type != PNG_COLOR_TYPE_RGB_ALPHA && color_type != PNG_COLOR_TYPE_GRAY_ALPHA) {
- 00485 // image has no alpha channel, add alpha channel 0xff
- 00486 *alphachannel = false;
- 00487 png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
- 00488 }
- 00489
- 00490 png_read_update_info(png_ptr, info_ptr);
- 00491
- 00492 // allocate memory for row pointers
- 00493 *width = w;
- 00494 *height = h;
- 00495 *pitch = 4 * w;
- 00496 *size = *pitch * h;
- 00497 row_pointers = (png_bytep*)malloc(*height * sizeof(png_bytep));
- 00498 if (!row_pointers) {
- 00499 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);
- 00500 delete file;
- 00501 return false;
- 00502 }
- 00503
- 00504 // allocate memory for image data
- 00505 if (this->mirror_size > *height) this->mirror_size = *height;
- 00506 *buf = malloc((*size) + (*pitch) * this->mirror_size);
- 00507 if (!*buf) {
- 00508 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);
- 00509 free(row_pointers);
- 00510 delete file;
- 00511 return false;
- 00512 }
- 00513 char *b = (char*)*buf;
- 00514 for (int i = 0; i < *height; i++) {
- 00515 row_pointers[i]=(png_byte*)b;
- 00516 b+=*pitch;
- 00517 }
- 00518
- 00519 // read the image data
- 00520 png_read_image(png_ptr, row_pointers);
- 00521 png_read_end(png_ptr, end_info_ptr);
- 00522
- 00523 // all right, freeing helpers
- 00524 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);
- 00525 free(row_pointers);
- 00526 delete file;
- 00527
- 00528 // at this point we have ARGB (MMSTAFF_PF_ARGB) pixels ********
- 00529 // so check now if i have to convert it
- 00530
- 00531 // create mirror, rotate and convert to target pixelformat
- 00532 return postprocessImage(buf, width, height, pitch, size, alphachannel);
- 00533 #else
- 00534 return false;
- 00535 #endif
- 00536 }
- 00537
- 00538
- 00539
- 00540 #ifdef __HAVE_JPEG__
- 00541 struct JPEGErrorManager {
- 00542 struct jpeg_error_mgr pub; /**< "public" fields */
- 00543 jmp_buf setjmpBuffer; /**< for return to caller */
- 00544 };
- 00545
- 00546 METHODDEF(void) JPEGErrorExit(j_common_ptr cinfo) {
- 00547 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
- 00548 struct JPEGErrorManager *myerr = (struct JPEGErrorManager*)cinfo->err;
- 00549
- 00550 /* Always display the message. */
- 00551 /* We could postpone this until after returning, if we chose. */
- 00552 (*cinfo->err->output_message)(cinfo);
- 00553
- 00554 /* Return control to the setjmp point */
- 00555 longjmp(myerr->setjmpBuffer, 1);
- 00556 }
- 00557 #endif
- 00558
- 00559 bool MMSTaffFile::readJPEG(const char *filename, void **buf, int *width, int *height, int *pitch,
- 00560 int *size, bool *alphachannel) {
- 00561 #ifdef __HAVE_JPEG__
- 00562 struct jpeg_decompress_struct cinfo;
- 00563 struct JPEGErrorManager jerr;
- 00564 FILE *fp;
- 00565 JSAMPARRAY rowBuf; /**< Output row buffer */
- 00566 int rowStride; /**< physical row width in output buffer */
- 00567
- 00568 MMSFile *file=NULL;
- 00569 size_t ritems = 0;
- 00570 char *fileBuffer=NULL;
- 00571
- 00572 if (strToUpr(string(filename).substr(0,7)) == "HTTP://") {
- 00573 // check if file does exist and if it is an png format
- 00574 file = new MMSFile(filename);
- 00575 if (!file) {
- 00576 return false;
- 00577 }
- 00578 if (file->getLastError()) {
- 00579 return false;
- 00580 }
- 00581
- 00582 if (!file->readBufferEx((void **)&fileBuffer, &ritems)) {
- 00583 delete file;
- 00584 return false;
- 00585 }
- 00586
- 00587 if((fp = fmemopen(fileBuffer, ritems, "rb")) == NULL) {
- 00588 free(fileBuffer);
- 00589 fileBuffer = NULL;
- 00590 delete file;
- 00591 return false;
- 00592 }
- 00593 } else {
- 00594 if((fp = fopen(filename, "rb")) == NULL) {
- 00595 return false;
- 00596 }
- 00597 }
- 00598
- 00599 cinfo.err = jpeg_std_error(&jerr.pub);
- 00600 jerr.pub.error_exit = JPEGErrorExit;
- 00601 if(setjmp(jerr.setjmpBuffer)) {
- 00602 jpeg_destroy_decompress(&cinfo);
- 00603 fclose(fp);
- 00604 if (file) {
- 00605 if (fileBuffer)
- 00606 free(fileBuffer);
- 00607 fileBuffer = NULL;
- 00608 delete file;
- 00609 }
- 00610 return false;
- 00611 }
- 00612 jpeg_create_decompress(&cinfo);
- 00613 jpeg_stdio_src(&cinfo, fp);
- 00614
- 00615 if(jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK) {
- 00616 fclose(fp);
- 00617 if (file) {
- 00618 if (fileBuffer)
- 00619 free(fileBuffer);
- 00620 fileBuffer = NULL;
- 00621 delete file;
- 00622 }
- 00623 return false;
- 00624 }
- 00625
- 00626 /* dimension filled by jpeg_read_header() */
- 00627 *width = (int)cinfo.image_width;
- 00628 *height = (int)cinfo.image_height;
- 00629 *pitch = *width * 4;
- 00630 *size = *pitch * *height;
- 00631
- 00632 // jpeg generally has no alpha channel
- 00633 *alphachannel = false;
- 00634
- 00635 /* setting decompression parameters */
- 00636 cinfo.out_color_space = JCS_RGB; /**< setting output colorspace to RGB */
- 00637
- 00638 /* start decompression */
- 00639 jpeg_start_decompress(&cinfo);
- 00640
- 00641 rowStride = cinfo.output_width * cinfo.output_components;
- 00642 rowBuf = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowStride, 1);
- 00643
- 00644 /* allocate memory for ARGB output */
- 00645 if(this->mirror_size > *height) this->mirror_size = *height;
- 00646 *buf = malloc((*size) + (*pitch) * this->mirror_size);
- 00647 if(!*buf) {
- 00648 jpeg_finish_decompress(&cinfo);
- 00649 jpeg_destroy_decompress(&cinfo);
- 00650 fclose(fp);
- 00651 if (file) {
- 00652 if (fileBuffer)
- 00653 free(fileBuffer);
- 00654 fileBuffer = NULL;
- 00655 delete file;
- 00656 }
- 00657 return false;
- 00658 }
- 00659
- 00660 unsigned int *src = (unsigned int*)*buf;
- 00661 while(cinfo.output_scanline < cinfo.output_height) {
- 00662 jpeg_read_scanlines(&cinfo, rowBuf, 1);
- 00663 unsigned char *b = *rowBuf;
- 00664 for(unsigned int i = 0; i < cinfo.output_width; ++i) {
- 00665 *src = 0xff000000 + (b[0] << 16) + (b[1] << 8) + b[2];
- 00666 b += 3;
- 00667 src++;
- 00668 }
- 00669 }
- 00670
- 00671 jpeg_finish_decompress(&cinfo);
- 00672 jpeg_destroy_decompress(&cinfo);
- 00673 fclose(fp);
- 00674 if (file) {
- 00675 if (fileBuffer)
- 00676 free(fileBuffer);
- 00677 fileBuffer = NULL;
- 00678 delete file;
- 00679 }
- 00680
- 00681 /* create mirror, rotate and convert to target pixelformat */
- 00682 return postprocessImage(buf, width, height, pitch, size, alphachannel);
- 00683 #else
- 00684 return false;
- 00685 #endif
- 00686 }
- 00687
- 00688 bool MMSTaffFile::readTIFF(const char *filename, void **buf, int *width, int *height, int *pitch,
- 00689 int *size, bool *alphachannel) {
- 00690 #ifdef __HAVE_TIFF__
- 00691 TIFF* tiff;
- 00692
- 00693 if((tiff = TIFFOpen(filename, "rb")) == NULL) {
- 00694 return false;
- 00695 }
- 00696
- 00697 TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, width);
- 00698 TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, height);
- 00699 *pitch = *width * 4;
- 00700 *size = *pitch * *height;
- 00701
- 00702 // we assume that we have an alpha channel
- 00703 *alphachannel = true;
- 00704
- 00705 /* allocate memory for ARGB output */
- 00706 if(this->mirror_size > *height) this->mirror_size = *height;
- 00707 //*buf = (unsigned int*)_TIFFmalloc((*size) + (*pitch) * this->mirror_size);
- 00708 *buf = malloc((*size) + (*pitch) * this->mirror_size);
- 00709 if(!*buf) {
- 00710 TIFFClose(tiff);
- 00711 return false;
- 00712 }
- 00713
- 00714 if(TIFFReadRGBAImageOriented(tiff, *width, *height, (uint32*)*buf, ORIENTATION_TOPLEFT, 0) == 0) {
- 00715 TIFFClose(tiff);
- 00716 return false;
- 00717 }
- 00718
- 00719 /* convert from BGRA to ARGB */
- 00720 unsigned int *src = (unsigned int*)*buf;
- 00721 unsigned int nPixels = *width * *height;
- 00722 for(unsigned int i = 0; i < nPixels; ++i) {
- 00723 register unsigned int s = (*src ^ (*src >> 16)) & 0xff;
- 00724 *src = *src ^ (s | (s << 16));
- 00725 src++;
- 00726 }
- 00727
- 00728 //_TIFFfree(*buf);
- 00729 TIFFClose(tiff);
- 00730
- 00731 /* create mirror, rotate and convert to target pixelformat */
- 00732 return postprocessImage(buf, width, height, pitch, size, alphachannel);
- 00733 #else
- 00734 return false;
- 00735 #endif
- 00736 }
- 00737
- 00738
- 00739 bool MMSTaffFile::convertString2TaffAttributeType(TAFF_ATTRTYPE attrType, char *attrValStr, bool *attrValStr_valid,
- 00740 bool *int_val_set, bool *byte_val_set, int *int_val,
- 00741 const char *attrname, int attrid, const char *nodename, int nodeline) {
- 00742 xmlChar *attrVal = (xmlChar *)attrValStr;
- 00743 if (!attrValStr) return false;
- 00744 if (!attrValStr_valid) return false;
- 00745 *attrValStr_valid = true;
- 00746 if (int_val_set) *int_val_set = false;
- 00747 if (byte_val_set) *byte_val_set = false;
- 00748
- 00749 bool check_ok = true;
- 00750
- 00751
- 00752 string validvals = "";
- 00753 bool badval = false;
- 00754 switch (attrType) {
- 00755 case TAFF_ATTRTYPE_NONE:
- 00756 case TAFF_ATTRTYPE_STRING:
- 00757 case TAFF_ATTRTYPE_BINDATA:
- 00758 break;
- 00759
- 00760 case TAFF_ATTRTYPE_NE_STRING:
- 00761 badval = (!*attrVal);
- 00762 if (badval) {
- 00763 validvals = "any characters, but not empty";
- 00764 check_ok = false;
- 00765 }
- 00766 break;
- 00767
- 00768 case TAFF_ATTRTYPE_BOOL:
- 00769 if (!byte_val_set || !int_val) return false;
- 00770 badval = ((xmlStrcmp(attrVal, (xmlChar *)"true"))&&(xmlStrcmp(attrVal, (xmlChar *)"false")));
- 00771 if (badval) {
- 00772 validvals = "\"true\", \"false\"";
- 00773 check_ok = false;
- 00774 }
- 00775 else {
- 00776 *byte_val_set = true;
- 00777 if (xmlStrcmp(attrVal, (xmlChar *)"true")==0)
- 00778 *int_val = 0xff;
- 00779 else
- 00780 *int_val = 0;
- 00781 }
- 00782 break;
- 00783
- 00784 case TAFF_ATTRTYPE_UCHAR:
- 00785 case TAFF_ATTRTYPE_UCHAR100:
- 00786 if (!byte_val_set || !int_val) return false;
- 00787 badval = ((xmlStrlen(attrVal) < 1)||(xmlStrlen(attrVal) > 3));
- 00788 if (!badval) {
- 00789 char iv[3+1];
- 00790 *int_val = atoi((char*)attrVal);
- 00791 sprintf(iv, "%d", *int_val);
- 00792 badval = (xmlStrcmp(attrVal, (xmlChar *)iv));
- 00793 if (!badval) {
- 00794 if (attrType == TAFF_ATTRTYPE_UCHAR100)
- 00795 badval = (*int_val<0||*int_val>100);
- 00796 else
- 00797 badval = (*int_val<0||*int_val>255);
- 00798 }
- 00799 *byte_val_set = !badval;
- 00800 }
- 00801 if (badval) {
- 00802 if (attrType == TAFF_ATTRTYPE_UCHAR100)
- 00803 validvals = "\"0\"..\"100\"";
- 00804 else
- 00805 validvals = "\"0\"..\"255\"";
- 00806 check_ok = false;
- 00807 }
- 00808 break;
- 00809
- 00810 case TAFF_ATTRTYPE_INT:
- 00811 if (!int_val_set || !int_val) return false;
- 00812 char iv[11+1];
- 00813 *int_val = atoi((char*)attrVal);
- 00814 sprintf(iv, "%d", *int_val);
- 00815 badval = (xmlStrcmp(attrVal, (xmlChar *)iv));
- 00816 *int_val_set = !badval;
- 00817 if (badval) {
- 00818 validvals = "\"-2147483648\"..\"2147483647\"";
- 00819 check_ok = false;
- 00820 }
- 00821 break;
- 00822
- 00823 case TAFF_ATTRTYPE_STATE:
- 00824 if (!byte_val_set || !int_val) return false;
- 00825 badval = ((xmlStrcmp(attrVal, (xmlChar *)"true"))&&(xmlStrcmp(attrVal, (xmlChar *)"false"))
- 00826 &&(xmlStrcmp(attrVal, (xmlChar *)"auto")));
- 00827 if (badval) {
- 00828 validvals = "\"true\", \"false\", \"auto\"";
- 00829 check_ok = false;
- 00830 }
- 00831 else {
- 00832 *byte_val_set = true;
- 00833 if (xmlStrcmp(attrVal, (xmlChar *)"true")==0)
- 00834 *int_val = 0xff;
- 00835 else
- 00836 if (xmlStrcmp(attrVal, (xmlChar *)"auto")==0)
- 00837 *int_val = 0x01;
- 00838 else
- 00839 *int_val = 0;
- 00840 }
- 00841 break;
- 00842
- 00843 case TAFF_ATTRTYPE_SEQUENCE_MODE: {
- 00844 if (!byte_val_set || !int_val) return false;
- 00845 bool sm_true = !xmlStrcmp(attrVal, (xmlChar *)"true");
- 00846 bool sm_false = !xmlStrcmp(attrVal, (xmlChar *)"false");
- 00847 bool sm_linear = !xmlStrcmp(attrVal, (xmlChar *)"linear");
- 00848 bool sm_log = !xmlStrcmp(attrVal, (xmlChar *)"log");
- 00849 bool sm_log_soft_start = !xmlStrcmp(attrVal, (xmlChar *)"log_soft_start");
- 00850 bool sm_log_soft_end = !xmlStrcmp(attrVal, (xmlChar *)"log_soft_end");
- 00851 badval = (!sm_true && !sm_false && !sm_linear && !sm_log && !sm_log_soft_start && !sm_log_soft_end);
- 00852 if (badval) {
- 00853 validvals = "\"true\", \"false\", \"linear\", \"log\", \"log_soft_start\", \"log_soft_end\"";
- 00854 check_ok = false;
- 00855 }
- 00856 else {
- 00857 *byte_val_set = true;
- 00858 if (sm_true)
- 00859 *int_val = 0xff;
- 00860 else
- 00861 if (sm_linear)
- 00862 *int_val = 0x01;
- 00863 else
- 00864 if (sm_log)
- 00865 *int_val = 0x02;
- 00866 else
- 00867 if (sm_log_soft_start)
- 00868 *int_val = 0x03;
- 00869 else
- 00870 if (sm_log_soft_end)
- 00871 *int_val = 0x04;
- 00872 else
- 00873 *int_val = 0;
- 00874 }
- 00875 }
- 00876 break;
- 00877
- 00878 case TAFF_ATTRTYPE_COLOR:
- 00879 if (!int_val_set || !int_val) return false;
- 00880 MMSFBColor color;
- 00881 badval = (!getMMSFBColorFromString((const char*)attrVal, &color));
- 00882 if (badval) {
- 00883 validvals = "argb values in hex format, syntax: \"#rrggbbaa\"";
- 00884 check_ok = false;
- 00885 }
- 00886 else {
- 00887 *int_val_set = true;
- 00888 *int_val = (int)color.getARGB();
- 00889 }
- 00890 break;
- 00891 }
- 00892
- 00893 // check if the value is blank and i have to ignore it
- 00894 if (this->ignore_blank_values) {
- 00895 if (!*attrVal) {
- 00896 *attrValStr_valid = false;
- 00897 if (int_val_set) *int_val_set = false;
- 00898 if (byte_val_set) *byte_val_set = false;
- 00899 return true;
- 00900 }
- 00901 }
- 00902
- 00903 if (!check_ok) {
- 00904 printf("Error: Value \"%s\" is invalid for the attribute \"%s\" of tag \"%s\", line %d of file %s\n valid values: %s\n",
- 00905 attrVal, (attrname)?attrname:"?", (nodename)?nodename:"?", nodeline, external_filename.c_str(), validvals.c_str());
- 00906 *attrValStr_valid = false;
- 00907 if (int_val_set) *int_val_set = false;
- 00908 if (byte_val_set) *byte_val_set = false;
- 00909 return false;
- 00910 }
- 00911
- 00912 // all right
- 00913 if (this->trace)
- 00914 printf(" Attribute \"%s\" found, ID=%d, value=\"%s\"\n", (attrname)?attrname:"?", attrid, attrVal);
- 00915
- 00916 return true;
- 00917 }
- 00918
- 00919
- 00920 bool MMSTaffFile::convertXML2TAFF_throughDoc(int depth, void *void_node, MMSFile *taff_file) {
- 00921
- 00922 bool wok = true;
- 00923 xmlNode *node = (xmlNode*) void_node;
- 00924 xmlNode *cur_node;
- 00925 if (depth==0)
- 00926 /* work with root */
- 00927 cur_node = node;
- 00928 else
- 00929 /* iterate through childs */
- 00930 cur_node = node->children;
- 00931
- 00932 while (cur_node) {
- 00933
- 00934 int tagid = 0;
- 00935 bool tag_found = false;
- 00936
- 00937 while (this->taff_desc->tagtable[tagid].name) {
- 00938 if (xmlStrcmp(cur_node->name, (const xmlChar *)this->taff_desc->tagtable[tagid].name)==0) {
- 00939 /* tag found in XML and tagtable, check the type? */
- 00940 if (this->taff_desc->tagtable[tagid].typeattr)
- 00941 {
- 00942 /* searching the typeattr and type */
- 00943 for (xmlAttr *cur_attr = cur_node->properties; cur_attr; cur_attr = cur_attr->next) {
- 00944 if (xmlStrcmp(cur_attr->name, (const xmlChar *)this->taff_desc->tagtable[tagid].typeattr)==0) {
- 00945 xmlChar *attrVal = xmlGetProp(cur_node, cur_attr->name);
- 00946 if (attrVal) {
- 00947 if (xmlStrcmp(attrVal, (const xmlChar *)this->taff_desc->tagtable[tagid].type)==0) {
- 00948 tag_found = true;
- 00949 break;
- 00950 }
- 00951 xmlFree(attrVal);
- 00952 }
- 00953 }
- 00954 }
- 00955 }
- 00956 else
- 00957 tag_found = true;
- 00958
- 00959 if (tag_found)
- 00960 break;
- 00961 }
- 00962 tagid++;
- 00963 }
- 00964
- 00965 if (tag_found) {
- 00966
- 00967 if (this->trace)
- 00968 printf("Tag \"%s\" found, ID=%d\n", cur_node->name, tagid);
- 00969
- 00970 /* writing the new tag */
- 00971 if (taff_file) {
- 00972 size_t ritems;
- 00973 unsigned char wb[2];
- 00974 wb[0]=MMSTAFF_TAGTABLE_TYPE_TAG;
- 00975 wb[1]=(unsigned char)tagid;
- 00976 writeBuffer(taff_file, wb, &ritems, 1, 2, &wok);
- 00977 }
- 00978
- 00979 /* get variables */
- 00980 for (xmlAttr *cur_attr = cur_node->properties; cur_attr; cur_attr = cur_attr->next) {
- 00981
- 00982 int attrid = 0;
- 00983 TAFF_ATTRDESC *attr = this->taff_desc->tagtable[tagid].attr;
- 00984 bool attr_found = false;
- 00985
- 00986 if (!attr) continue;
- 00987
- 00988 xmlChar *attrVal = xmlGetProp(cur_node, cur_attr->name);
- 00989 if (!attrVal) continue;
- 00990
- 00991 while (attr[attrid].name)
- 00992 {
- 00993 if (xmlStrcmp(cur_attr->name, (const xmlChar *)attr[attrid].name)==0) {
- 00994 attr_found = true;
- 00995 break;
- 00996 }
- 00997 attrid++;
- 00998 }
- 00999
- 01000 if (attr_found) {
- 01001
- 01002 // now check the type of the variable
- 01003 bool attrValStr_valid;
- 01004 bool int_val_set;
- 01005 bool byte_val_set;
- 01006 int int_val;
- 01007
- 01008 if (!convertString2TaffAttributeType(attr[attrid].type, (char *)attrVal, &attrValStr_valid,
- 01009 &int_val_set, &byte_val_set, &int_val,
- 01010 (const char *)cur_attr->name, attrid,
- 01011 (const char *)cur_node->name, cur_node->line)) {
- 01012 // check failed
- 01013 return false;
- 01014 }
- 01015
- 01016 if (!attrValStr_valid && !int_val_set && !byte_val_set) {
- 01017 // no values to process
- 01018 continue;
- 01019 }
- 01020
- 01021
- 01022 // attribute value is determined, write it now
- 01023 if (taff_file) {
- 01024 if (!int_val_set && !byte_val_set) {
- 01025 /* get the length of the value INCLUDING the 0x00 because of fast read & parse of the TAFF */
- 01026 int attrvallen = xmlStrlen(attrVal) + 1;
- 01027
- 01028 size_t ritems;
- 01029 unsigned char wb[3];
- 01030 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01031 wb[1]=(unsigned char)attrid;
- 01032 if (attrvallen >= 0xff) {
- 01033 /* in this case set 0xff as mark and append the full integer */
- 01034 wb[2]=0xff;
- 01035 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01036 writeBuffer(taff_file, &attrvallen, &ritems, 1, sizeof(int), &wok);
- 01037 }
- 01038 else {
- 01039 /* in this case write only one byte length */
- 01040 wb[2]=(unsigned char)attrvallen;
- 01041 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01042 }
- 01043 writeBuffer(taff_file, attrVal, &ritems, 1, attrvallen, &wok);
- 01044 }
- 01045 else
- 01046 if (int_val_set) {
- 01047 // writing value as INTEGER
- 01048 size_t ritems;
- 01049 unsigned char wb[3];
- 01050 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01051 wb[1]=(unsigned char)attrid;
- 01052 wb[2]=sizeof(int);
- 01053 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01054 writeBuffer(taff_file, &int_val, &ritems, 1, sizeof(int), &wok);
- 01055 }
- 01056 else {
- 01057 // writing value as single BYTE
- 01058 size_t ritems;
- 01059 unsigned char wb[3];
- 01060 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01061 wb[1]=(unsigned char)attrid;
- 01062 wb[2]=sizeof(char);
- 01063 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01064 unsigned char byte_val = int_val;
- 01065 writeBuffer(taff_file, &byte_val, &ritems, 1, sizeof(char), &wok);
- 01066 }
- 01067 }
- 01068 }
- 01069 else {
- 01070 /* attribute is not defined, so we cannot found an ID of it */
- 01071 /* we store it with ID 0xff and its real name */
- 01072 if (this->trace)
- 01073 printf(" Attribute \"%s\" found without ID, value=\"%s\"\n", cur_attr->name, attrVal);
- 01074
- 01075 if (this->print_warnings)
- 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",
- 01077 cur_attr->name, cur_node->name, cur_node->line, external_filename.c_str());
- 01078
- 01079 /* write attribute value */
- 01080 if (taff_file) {
- 01081 /* get the length of the value INCLUDING the 0x00 because of fast read & parse of the TAFF */
- 01082 int attrnamlen = xmlStrlen(cur_attr->name) + 1;
- 01083 int attrvallen = xmlStrlen(attrVal) + 1;
- 01084
- 01085 size_t ritems;
- 01086 unsigned char wb[3];
- 01087 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01088 wb[1]=MMSTAFF_ATTR_WITHOUT_ID;
- 01089 writeBuffer(taff_file, wb, &ritems, 1, 2, &wok);
- 01090 writeBuffer(taff_file, &attrnamlen, &ritems, 1, sizeof(int), &wok);
- 01091 writeBuffer(taff_file, (char*)cur_attr->name, &ritems, 1, attrnamlen, &wok);
- 01092 if (attrvallen >= 0xff) {
- 01093 /* in this case set 0xff as mark and append the full integer */
- 01094 wb[0]=0xff;
- 01095 writeBuffer(taff_file, wb, &ritems, 1, 1, &wok);
- 01096 writeBuffer(taff_file, &attrvallen, &ritems, 1, sizeof(int), &wok);
- 01097 }
- 01098 else {
- 01099 /* in this case write only one byte length */
- 01100 wb[0]=(unsigned char)attrvallen;
- 01101 writeBuffer(taff_file, wb, &ritems, 1, 1, &wok);
- 01102 }
- 01103 writeBuffer(taff_file, attrVal, &ritems, 1, attrvallen, &wok);
- 01104 }
- 01105 }
- 01106
- 01107 xmlFree(attrVal);
- 01108 }
- 01109
- 01110 /* call recursive to find childs */
- 01111 if (!convertXML2TAFF_throughDoc(depth+1, cur_node, taff_file))
- 01112 return false;
- 01113
- 01114 /* writing the close tag */
- 01115 if (taff_file) {
- 01116 size_t ritems;
- 01117 unsigned char wb[2];
- 01118 wb[0]=MMSTAFF_TAGTABLE_TYPE_CLOSETAG;
- 01119 wb[1]=(unsigned char)tagid;
- 01120 writeBuffer(taff_file, wb, &ritems, 1, 2, &wok);
- 01121 }
- 01122 }
- 01123 else {
- 01124 if (xmlStrcmp(cur_node->name, (const xmlChar *)"text")&&xmlStrcmp(cur_node->name, (const xmlChar *)"comment")) {
- 01125 printf("Error: Tag \"%s\" is not defined, line %d of file %s\n", cur_node->name, cur_node->line, external_filename.c_str());
- 01126 return false;
- 01127 }
- 01128 }
- 01129
- 01130 if (depth==0)
- 01131 break;
- 01132 else
- 01133 cur_node = cur_node->next;
- 01134 }
- 01135
- 01136 // return with write status
- 01137 return wok;
- 01138 }
- 01139
- 01140 bool MMSTaffFile::convertXML2TAFF() {
- 01141
- 01142 bool rc = false;
- 01143 xmlDoc *parser = NULL;
- 01144
- 01145 LIBXML_TEST_VERSION
- 01146
- 01147 /* check input parameters */
- 01148 if (!this->taff_desc || this->external_filename.empty()) {
- 01149 return false;
- 01150 }
- 01151
- 01152 /* read the XML file */
- 01153 parser = xmlReadFile(this->external_filename.c_str(),
- 01154 NULL,
- 01155 XML_PARSE_PEDANTIC |
- 01156 XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NODICT |
- 01157 XML_PARSE_NOXINCNODE
- 01158 #if LIBXML_VERSION >= 20700
- 01159 | XML_PARSE_NOBASEFIX
- 01160 #endif
- 01161 );
- 01162
- 01163 if (parser) {
- 01164
- 01165 /* open binary destination file */
- 01166 MMSFile *taff_file = NULL;
- 01167 if (this->taff_filename!="") {
- 01168 taff_file = new MMSFile(this->taff_filename.c_str(), MMSFM_WRITE);
- 01169 size_t ritems;
- 01170 bool wok = true;
- 01171 writeBuffer(taff_file, (void*)TAFF_IDENT, &ritems, 1, strlen(TAFF_IDENT), &wok);
- 01172 writeBuffer(taff_file, &(this->taff_desc->type), &ritems, 1, sizeof(this->taff_desc->type), &wok);
- 01173 writeBuffer(taff_file, &(this->taff_desc->version), &ritems, 1, sizeof(this->taff_desc->version), &wok);
- 01174 if (!wok) {
- 01175 // write error, close file and free
- 01176 delete taff_file;
- 01177 xmlFreeDoc(parser);
- 01178
- 01179 // reset the file
- 01180 taff_file = new MMSFile(this->taff_filename.c_str(), MMSFM_WRITE);
- 01181 if (taff_file) delete taff_file;
- 01182
- 01183 return false;
- 01184 }
- 01185 }
- 01186
- 01187 // get the first element
- 01188 xmlNode* node = xmlDocGetRootElement(parser);
- 01189
- 01190 // through the doc
- 01191 rc = convertXML2TAFF_throughDoc(0, node, taff_file);
- 01192
- 01193 // close file and free
- 01194 if (taff_file)
- 01195 delete taff_file;
- 01196 xmlFreeDoc(parser);
- 01197
- 01198 if (!rc) {
- 01199 // failed, reset the file
- 01200 taff_file = new MMSFile(this->taff_filename.c_str(), MMSFM_WRITE);
- 01201 if (taff_file) delete taff_file;
- 01202 }
- 01203 }
- 01204 else {
- 01205 printf("Error: cannot read external file %s\n", this->external_filename.c_str());
- 01206 }
- 01207
- 01208 return rc;
- 01209 }
- 01210
- 01211 bool MMSTaffFile::convertIMAGE2TAFF() {
- 01212 bool rc = false;
- 01213 void *imgBuf;
- 01214 int imgWidth;
- 01215 int imgHeight;
- 01216 int imgPitch;
- 01217 int imgSize;
- 01218 bool imgAlphaChannel;
- 01219
- 01220 /* check input parameters */
- 01221 if (!this->taff_desc || this->external_filename.empty()) {
- 01222 return false;
- 01223 }
- 01224
- 01225 /* check file extension (if this fails try readPNG() and/or readJPEG() and/or readTIFF()) */
- 01226 if(strToUpr(this->external_filename).rfind(".PNG") == this->external_filename.size() - 4) {
- 01227 #ifdef __HAVE_PNG__
- 01228 rc = readPNG(this->external_filename.c_str(), &imgBuf, &imgWidth, &imgHeight, &imgPitch, &imgSize, &imgAlphaChannel);
- 01229 #else
- 01230 cout << "Disko was built without PNG support: skipping " << this->external_filename << endl;
- 01231 return false;
- 01232 #endif
- 01233 } else if((strToUpr(this->external_filename).rfind(".JPG") == this->external_filename.size() - 4) ||
- 01234 (strToUpr(this->external_filename).rfind(".JPEG") == this->external_filename.size() - 5)) {
- 01235 #ifdef __HAVE_JPEG__
- 01236 rc = readJPEG(this->external_filename.c_str(), &imgBuf, &imgWidth, &imgHeight, &imgPitch, &imgSize, &imgAlphaChannel);
- 01237 #else
- 01238 cout << "Disko was built without JPEG support: skipping " << this->external_filename << endl;
- 01239 return false;
- 01240 #endif
- 01241 } else if((strToUpr(this->external_filename).rfind(".TIF") == this->external_filename.size() - 4) ||
- 01242 (strToUpr(this->external_filename).rfind(".TIFF") == this->external_filename.size() - 5)) {
- 01243 #ifdef __HAVE_TIFF__
- 01244 rc = readTIFF(this->external_filename.c_str(), &imgBuf, &imgWidth, &imgHeight, &imgPitch, &imgSize, &imgAlphaChannel);
- 01245 #else
- 01246 cout << "Disko was built without TIFF support: skipping " << this->external_filename << endl;
- 01247 return false;
- 01248 #endif
- 01249 } else {
- 01250 #ifdef __HAVE_PNG__
- 01251 rc = readPNG(this->external_filename.c_str(), &imgBuf, &imgWidth, &imgHeight, &imgPitch, &imgSize, &imgAlphaChannel);
- 01252 #endif
- 01253 #ifdef __HAVE_JPEG__
- 01254 if(!rc) {
- 01255 rc = readJPEG(this->external_filename.c_str(), &imgBuf, &imgWidth, &imgHeight, &imgPitch, &imgSize, &imgAlphaChannel);
- 01256 }
- 01257 #endif
- 01258 #ifdef __HAVE_TIFF__
- 01259 if(!rc) {
- 01260 rc = readTIFF(this->external_filename.c_str(), &imgBuf, &imgWidth, &imgHeight, &imgPitch, &imgSize, &imgAlphaChannel);
- 01261 }
- 01262 #endif
- 01263 }
- 01264
- 01265 if(rc) {
- 01266 // open binary destination file
- 01267 MMSFile *taff_file = NULL;
- 01268 bool wok = true;
- 01269 size_t ritems;
- 01270 if (!this->taff_filename.empty()) {
- 01271 taff_file = new MMSFile(this->taff_filename.c_str(), MMSFM_WRITE);
- 01272 writeBuffer(taff_file, (void*)TAFF_IDENT, &ritems, 1, strlen(TAFF_IDENT), &wok);
- 01273 }
- 01274
- 01275 if (!taff_file) {
- 01276 // no regular file, so setup the buffer so that we have not to resize it
- 01277 this->taff_buf_size = imgSize + 256;
- 01278 this->taff_buf_pos = 0;
- 01279 if (this->taff_buf) free(this->taff_buf);
- 01280 this->taff_buf = (unsigned char *)malloc(this->taff_buf_size);
- 01281 }
- 01282
- 01283 // write type and version
- 01284 writeBuffer(taff_file, &(this->taff_desc->type), &ritems, 1, sizeof(this->taff_desc->type), &wok);
- 01285 writeBuffer(taff_file, &(this->taff_desc->version), &ritems, 1, sizeof(this->taff_desc->version), &wok);
- 01286
- 01287 // write the tag
- 01288 unsigned char wb[3];
- 01289 wb[0]=MMSTAFF_TAGTABLE_TYPE_TAG;
- 01290 wb[1]=MMSTAFF_IMAGE_TAGTABLE_TAG_RAWIMAGE;
- 01291 writeBuffer(taff_file, wb, &ritems, 1, 2, &wok);
- 01292
- 01293 // write attributes: width
- 01294 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01295 wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_width;
- 01296 wb[2]=sizeof(int);
- 01297 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01298 writeBuffer(taff_file, &imgWidth, &ritems, 1, sizeof(int), &wok);
- 01299
- 01300 // write attributes: height
- 01301 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01302 wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_height;
- 01303 wb[2]=sizeof(int);
- 01304 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01305 writeBuffer(taff_file, &imgHeight, &ritems, 1, sizeof(int), &wok);
- 01306
- 01307 // write attributes: pitch
- 01308 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01309 wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_pitch;
- 01310 wb[2]=sizeof(int);
- 01311 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01312 writeBuffer(taff_file, &imgPitch, &ritems, 1, sizeof(int), &wok);
- 01313
- 01314 // write attributes: size
- 01315 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01316 wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_size;
- 01317 wb[2]=sizeof(int);
- 01318 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01319 writeBuffer(taff_file, &imgSize, &ritems, 1, sizeof(int), &wok);
- 01320
- 01321 // write attributes: pixelformat
- 01322 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01323 wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_pixelformat;
- 01324 wb[2]=sizeof(int);
- 01325 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01326 int pf = (int)this->destination_pixelformat;
- 01327 writeBuffer(taff_file, &pf, &ritems, 1, sizeof(int), &wok);
- 01328
- 01329 // write attributes: premultiplied
- 01330 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01331 wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_premultiplied;
- 01332 wb[2]=sizeof(bool);
- 01333 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01334 bool pm = (this->destination_premultiplied);
- 01335 writeBuffer(taff_file, &pm, &ritems, 1, sizeof(bool), &wok);
- 01336
- 01337 // write attributes: mirror_size
- 01338 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01339 wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_mirror_size;
- 01340 wb[2]=sizeof(int);
- 01341 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01342 int ms = (int)this->mirror_size;
- 01343 writeBuffer(taff_file, &ms, &ritems, 1, sizeof(int), &wok);
- 01344
- 01345 // write attributes: alphachannel
- 01346 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01347 wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_alphachannel;
- 01348 wb[2]=sizeof(bool);
- 01349 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01350 writeBuffer(taff_file, &imgAlphaChannel, &ritems, 1, sizeof(bool), &wok);
- 01351
- 01352 // write attributes: rotate_180
- 01353 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01354 wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_rotate_180;
- 01355 wb[2]=sizeof(bool);
- 01356 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01357 bool rot = (this->rotate_180);
- 01358 writeBuffer(taff_file, &rot, &ritems, 1, sizeof(bool), &wok);
- 01359
- 01360 // write attributes: data
- 01361 wb[0]=MMSTAFF_TAGTABLE_TYPE_ATTR;
- 01362 wb[1]=MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_data;
- 01363 wb[2]=0xff;
- 01364 writeBuffer(taff_file, wb, &ritems, 1, 3, &wok);
- 01365 writeBuffer(taff_file, &imgSize, &ritems, 1, sizeof(int), &wok);
- 01366 writeBuffer(taff_file, imgBuf, &ritems, 1, imgSize, &wok);
- 01367
- 01368 // write the close tag
- 01369 wb[0]=MMSTAFF_TAGTABLE_TYPE_CLOSETAG;
- 01370 wb[1]=MMSTAFF_IMAGE_TAGTABLE_TAG_RAWIMAGE;
- 01371 writeBuffer(taff_file, wb, &ritems, 1, 2, &wok);
- 01372
- 01373 // set rc
- 01374 rc = wok;
- 01375
- 01376 // close file and free
- 01377 if (taff_file) {
- 01378 delete taff_file;
- 01379 }
- 01380 else {
- 01381 // no regular file, set buffer values
- 01382 this->taff_buf_size = this->taff_buf_pos;
- 01383 this->taff_buf_pos = 0;
- 01384 getFirstTag();
- 01385 this->loaded = true;
- 01386 }
- 01387 free(imgBuf);
- 01388
- 01389 if (!rc) {
- 01390 // failed, reset the file
- 01391 if (!this->taff_filename.empty()) {
- 01392 taff_file = new MMSFile(this->taff_filename.c_str(), MMSFM_WRITE);
- 01393 if (taff_file) delete taff_file;
- 01394 }
- 01395 }
- 01396 }
- 01397 else {
- 01398 printf("Error: cannot read external file %s\n", this->external_filename.c_str());
- 01399 }
- 01400
- 01401 return rc;
- 01402 }
- 01403
- 01404 bool MMSTaffFile::convertExternal2TAFF() {
- 01405 switch (this->external_type) {
- 01406 case MMSTAFF_EXTERNAL_TYPE_XML:
- 01407 return convertXML2TAFF();
- 01408 case MMSTAFF_EXTERNAL_TYPE_IMAGE:
- 01409 return convertIMAGE2TAFF();
- 01410 }
- 01411 return false;
- 01412 }
- 01413
- 01414 bool MMSTaffFile::convertTAFF2XML_throughDoc(int depth, int tagid, MMSFile *external_file) {
- 01415 size_t ritems;
- 01416 char wb[8*1024];
- 01417
- 01418 TAFF_TAGTABLE *tagt = &(this->taff_desc->tagtable[tagid]);
- 01419 TAFF_ATTRDESC *attr = tagt->attr;
- 01420
- 01421 if (this->trace)
- 01422 printf("Tag \"%s\" found, ID=%d\n", tagt->name, tagid);
- 01423
- 01424 /* write tag */
- 01425 if (external_file) {
- 01426 *wb = '\n';
- 01427 memset(&wb[1], ' ', depth*4);
- 01428 sprintf(&wb[1+depth*4], "<%s", tagt->name);
- 01429 writeBuffer(external_file, wb, &ritems, 1, strlen(wb));
- 01430 }
- 01431
- 01432 /* write attributes */
- 01433 char *attrval_str;
- 01434 int attrval_int;
- 01435 char *attr_name;
- 01436 int attrid;
- 01437 while ((attrid = getNextAttribute(&attrval_str, &attrval_int, &attr_name)) >= 0) {
- 01438 if (attrid != MMSTAFF_ATTR_WITHOUT_ID) {
- 01439 string attrval;
- 01440 switch (attr[attrid].type) {
- 01441 case TAFF_ATTRTYPE_BOOL:
- 01442 if (attrval_int)
- 01443 attrval = "true";
- 01444 else
- 01445 attrval = "false";
- 01446 break;
- 01447 case TAFF_ATTRTYPE_UCHAR:
- 01448 case TAFF_ATTRTYPE_UCHAR100:
- 01449 case TAFF_ATTRTYPE_INT:
- 01450 attrval = iToStr(attrval_int);
- 01451 break;
- 01452 case TAFF_ATTRTYPE_STATE:
- 01453 if ((attrval_int & 0xff) == 0x01)
- 01454 attrval = "auto";
- 01455 else
- 01456 if (attrval_int)
- 01457 attrval = "true";
- 01458 else
- 01459 attrval = "false";
- 01460 break;
- 01461 case TAFF_ATTRTYPE_SEQUENCE_MODE:
- 01462 if ((attrval_int & 0xff) == 0x01)
- 01463 attrval = "linear";
- 01464 else
- 01465 if ((attrval_int & 0xff) == 0x02)
- 01466 attrval = "log";
- 01467 else
- 01468 if ((attrval_int & 0xff) == 0x03)
- 01469 attrval = "log_soft_start";
- 01470 else
- 01471 if ((attrval_int & 0xff) == 0x04)
- 01472 attrval = "log_soft_end";
- 01473 else
- 01474 if (attrval_int)
- 01475 attrval = "true";
- 01476 else
- 01477 attrval = "false";
- 01478 break;
- 01479 case TAFF_ATTRTYPE_COLOR:
- 01480 attrval = getMMSFBColorString(MMSFBColor((unsigned int)attrval_int));
- 01481 break;
- 01482 default:
- 01483 attrval = attrval_str;
- 01484 break;
- 01485 }
- 01486
- 01487 if (this->trace)
- 01488 printf(" Attribute \"%s\" found, ID=%d, value=\"%s\"\n", attr[attrid].name, attrid, attrval.c_str());
- 01489
- 01490 if (external_file) {
- 01491 *wb = '\n';
- 01492 memset(&wb[1], ' ', depth*4+4);
- 01493 sprintf(&wb[1+depth*4+4], "%s = \"%s\"", attr[attrid].name, attrval.c_str());
- 01494 writeBuffer(external_file, wb, &ritems, 1, strlen(wb));
- 01495 }
- 01496 }
- 01497 else {
- 01498 if (this->trace)
- 01499 printf(" Attribute \"%s\" found without ID, value=\"%s\"\n", attr_name, attrval_str);
- 01500
- 01501 if (external_file) {
- 01502 *wb = '\n';
- 01503 memset(&wb[1], ' ', depth*4+4);
- 01504 sprintf(&wb[1+depth*4+4], "%s = \"%s\"", attr_name, attrval_str);
- 01505 writeBuffer(external_file, wb, &ritems, 1, strlen(wb));
- 01506 }
- 01507 }
- 01508 }
- 01509
- 01510 /* close tag */
- 01511 if (external_file) {
- 01512 sprintf(wb, ">\n");
- 01513 writeBuffer(external_file, wb, &ritems, 1, strlen(wb));
- 01514 }
- 01515
- 01516 /* through my child tags */
- 01517 while (1) {
- 01518 bool eof;
- 01519 int tid = getNextTag(eof);
- 01520 if (tid < 0) {
- 01521 /* close tag */
- 01522 if (external_file) {
- 01523 memset(wb, ' ', depth*4);
- 01524 sprintf(&wb[depth*4], "</%s>\n", tagt->name);
- 01525 writeBuffer(external_file, wb, &ritems, 1, strlen(wb));
- 01526 }
- 01527 return true;
- 01528 }
- 01529 if (convertTAFF2XML_throughDoc(depth+1, tid, external_file)==false)
- 01530 return false;
- 01531 }
- 01532 }
- 01533
- 01534 bool MMSTaffFile::convertTAFF2XML() {
- 01535 if (!this->loaded) return false;
- 01536
- 01537 /* get root tag */
- 01538 int tagid = getFirstTag();
- 01539 if (tagid < 0) return false;
- 01540
- 01541 /* open binary destination file */
- 01542 MMSFile *external_file = NULL;
- 01543 if (this->external_filename!="")
- 01544 external_file = new MMSFile(this->external_filename.c_str(), MMSFM_WRITE);
- 01545
- 01546 /* start with root */
- 01547 bool rc = convertTAFF2XML_throughDoc(0, tagid, external_file);
- 01548
- 01549 if (external_file)
- 01550 delete external_file;
- 01551
- 01552 return rc;
- 01553 }
- 01554
- 01555 bool MMSTaffFile::convertTAFF2External() {
- 01556 switch (this->external_type) {
- 01557 case MMSTAFF_EXTERNAL_TYPE_XML:
- 01558 return convertTAFF2XML();
- 01559 case MMSTAFF_EXTERNAL_TYPE_IMAGE:
- 01560 printf("TAFF: Currently we cannot convert taff to image\n");
- 01561 return false;
- 01562 }
- 01563 return false;
- 01564 }
- 01565
- 01566 bool MMSTaffFile::readFile() {
- 01567 if (this->taff_buf) {
- 01568 free(this->taff_buf);
- 01569 this->taff_buf = NULL;
- 01570 }
- 01571 this->loaded = false;
- 01572
- 01573 if (!this->taff_desc) return false;
- 01574 if (this->taff_filename=="") return false;
- 01575
- 01576 // load the file
- 01577 MMSFile *taff_file = new MMSFile(this->taff_filename.c_str(), MMSFM_READ, false);
- 01578 if (!taff_file) return false;
- 01579 size_t ritems;
- 01580 char taff_ident[32];
- 01581 if (!taff_file->readBuffer((void*)taff_ident, &ritems, 1, strlen(TAFF_IDENT))) {
- 01582 // read error
- 01583 this->taff_buf = NULL;
- 01584 delete taff_file;
- 01585 return false;
- 01586 }
- 01587 if (ritems == 0) {
- 01588 // file is empty
- 01589 printf("TAFF: File is empty (%s)\n", this->taff_filename.c_str());
- 01590 this->taff_buf = NULL;
- 01591 delete taff_file;
- 01592 return false;
- 01593 }
- 01594 if (memcmp(taff_ident, TAFF_IDENT, strlen(TAFF_IDENT))!=0) {
- 01595 // the first bytes of the file are different from TAFF_IDENT
- 01596 printf("TAFF: TAFF_IDENT mismatch (%s)\n", this->taff_filename.c_str());
- 01597 this->taff_buf = NULL;
- 01598 delete taff_file;
- 01599 return false;
- 01600 }
- 01601 if (!taff_file->readBufferEx((void**)&(this->taff_buf), &ritems)) {
- 01602 // read error
- 01603 this->taff_buf = NULL;
- 01604 delete taff_file;
- 01605 return false;
- 01606 }
- 01607 delete taff_file;
- 01608
- 01609 if (ritems < 40) {
- 01610 // wrong size
- 01611 free(this->taff_buf);
- 01612 this->taff_buf = NULL;
- 01613 return false;
- 01614 }
- 01615
- 01616 // check the version of the file
- 01617 this->correct_version = false;
- 01618 if (strcmp((char*)this->taff_buf, (char*)&(this->taff_desc->type))) {
- 01619 // wrong type
- 01620 printf("TAFF: Wrong TAFF type (%s)\n", this->taff_filename.c_str());
- 01621 free(this->taff_buf);
- 01622 this->taff_buf = NULL;
- 01623 return false;
- 01624 }
- 01625 if (memcmp(this->taff_buf+sizeof(this->taff_desc->type), &(this->taff_desc->version), sizeof(this->taff_desc->version))) {
- 01626 // wrong version
- 01627 free(this->taff_buf);
- 01628 this->taff_buf = NULL;
- 01629 return false;
- 01630 }
- 01631 this->correct_version = true;
- 01632
- 01633 // compare the modification time of the taff and external file
- 01634 if (this->external_filename!="") {
- 01635 struct stat statbuf1;
- 01636 struct stat statbuf2;
- 01637 if (stat(this->taff_filename.c_str(), &statbuf1)!=0) {
- 01638 free(this->taff_buf);
- 01639 this->taff_buf = NULL;
- 01640 return false;
- 01641 }
- 01642 if (stat(this->external_filename.c_str(), &statbuf2)==0) {
- 01643 if (statbuf2.st_mtime <= time(NULL)) {
- 01644 // ok, external file created in the past
- 01645 if (statbuf2.st_mtime >= statbuf1.st_mtime) {
- 01646 // external file has been modified, therefore the taff file maybe not up-to-date
- 01647 free(this->taff_buf);
- 01648 this->taff_buf = NULL;
- 01649 return false;
- 01650 }
- 01651 }
- 01652 }
- 01653 }
- 01654
- 01655 // all right
- 01656 this->taff_buf_size = ritems;
- 01657 getFirstTag();
- 01658 this->loaded = true;
- 01659 return true;
- 01660 }
- 01661
- 01662 bool MMSTaffFile::isLoaded() {
- 01663 return this->loaded;
- 01664 }
- 01665
- 01666 bool MMSTaffFile::checkVersion() {
- 01667 return this->correct_version;
- 01668 }
- 01669
- 01670 void MMSTaffFile::setExternal(string external_filename, MMSTAFF_EXTERNAL_TYPE external_type) {
- 01671 this->external_filename = external_filename;
- 01672 this->external_type = external_type;
- 01673 }
- 01674
- 01675 void MMSTaffFile::setTrace(bool trace) {
- 01676 this->trace = trace;
- 01677 }
- 01678
- 01679 void MMSTaffFile::setPrintWarnings(bool print_warnings) {
- 01680 this->print_warnings = print_warnings;
- 01681 }
- 01682
- 01683 void MMSTaffFile::setDestinationPixelFormat(MMSTAFF_PF pixelformat, bool premultiplied) {
- 01684 this->destination_pixelformat = pixelformat;
- 01685 this->destination_premultiplied = premultiplied;
- 01686 }
- 01687
- 01688 void MMSTaffFile::setMirrorEffect(int size) {
- 01689 this->mirror_size = size;
- 01690 }
- 01691
- 01692 void MMSTaffFile::rotate180(bool rotate_180) {
- 01693 this->rotate_180 = rotate_180;
- 01694 }
- 01695
- 01696 int MMSTaffFile::getFirstTag() {
- 01697 this->taff_buf_pos = sizeof(this->taff_desc->type) + sizeof(this->taff_desc->version);
- 01698 this->current_tag = -1;
- 01699 this->current_tag_pos = 0;
- 01700
- 01701 if (this->taff_buf[this->taff_buf_pos] == MMSTAFF_TAGTABLE_TYPE_TAG) {
- 01702 bool eof;
- 01703 return getNextTag(eof);
- 01704 }
- 01705
- 01706 return this->current_tag;
- 01707 }
- 01708
- 01709 int MMSTaffFile::getNextTag(bool &eof) {
- 01710 /* searching for next tag */
- 01711 eof = false;
- 01712 while (this->taff_buf_pos < this->taff_buf_size) {
- 01713 switch (this->taff_buf[this->taff_buf_pos]) {
- 01714 case MMSTAFF_TAGTABLE_TYPE_TAG:
- 01715 this->current_tag = this->taff_buf[this->taff_buf_pos+1];
- 01716 this->current_tag_pos = this->taff_buf_pos;
- 01717 this->taff_buf_pos+=2;
- 01718 return this->current_tag;
- 01719 case MMSTAFF_TAGTABLE_TYPE_ATTR: {
- 01720 this->taff_buf_pos+=2;
- 01721 int len;
- 01722
- 01723 /* check if name of attribute is stored instead of id */
- 01724 if (this->taff_buf[this->taff_buf_pos-1] == MMSTAFF_ATTR_WITHOUT_ID) {
- 01725 len = MMSTAFF_INT32_FROM_UCHAR_STREAM(&this->taff_buf[this->taff_buf_pos]);
- 01726 this->taff_buf_pos+=sizeof(int);
- 01727 this->taff_buf_pos+=len;
- 01728 }
- 01729
- 01730 /* get the length of the value */
- 01731 len = (int)this->taff_buf[this->taff_buf_pos];
- 01732 this->taff_buf_pos++;
- 01733 if (len >= 0xff) {
- 01734 len = MMSTAFF_INT32_FROM_UCHAR_STREAM(&this->taff_buf[this->taff_buf_pos]);
- 01735 this->taff_buf_pos+=sizeof(int);
- 01736 }
- 01737 this->taff_buf_pos+=len;
- 01738 }
- 01739 break;
- 01740 case MMSTAFF_TAGTABLE_TYPE_CLOSETAG:
- 01741 this->current_tag = -1;
- 01742 this->taff_buf_pos+=2;
- 01743 eof = false;
- 01744 return this->current_tag;
- 01745 default:
- 01746 this->current_tag = -1;
- 01747 this->current_tag_pos = 0;
- 01748 eof = true;
- 01749 return this->current_tag;
- 01750 }
- 01751 }
- 01752 this->current_tag = -1;
- 01753 this->current_tag_pos = 0;
- 01754 eof = true;
- 01755 return this->current_tag;
- 01756 }
- 01757
- 01758 int MMSTaffFile::getCurrentTag(const char **name) {
- 01759 if (name) *name = this->taff_desc->tagtable[this->current_tag].name;
- 01760 return this->current_tag;
- 01761 }
- 01762
- 01763 const char *MMSTaffFile::getCurrentTagName() {
- 01764 return this->taff_desc->tagtable[this->current_tag].name;
- 01765 }
- 01766
- 01767 MMSTaffFile *MMSTaffFile::copyCurrentTag() {
- 01768 MMSTaffFile *mytafff = NULL;
- 01769 int tag_cnt, closetag_cnt;
- 01770
- 01771 if (!this->current_tag_pos)
- 01772 return NULL;
- 01773
- 01774 /* save buffer positions */
- 01775 int saved_taff_buf_pos = this->taff_buf_pos;
- 01776 int saved_current_tag = this->current_tag;
- 01777 int saved_current_tag_pos = this->current_tag_pos;
- 01778
- 01779 /* go to the position after the current tag */
- 01780 this->taff_buf_pos = this->current_tag_pos;
- 01781
- 01782 /* searching the close tag of this tag */
- 01783 tag_cnt = 0;
- 01784 closetag_cnt = 0;
- 01785 do {
- 01786 bool eof;
- 01787 if (getNextTag(eof) < 0) {
- 01788 if (eof) break;
- 01789 closetag_cnt++;
- 01790 }
- 01791 else
- 01792 tag_cnt++;
- 01793 } while (tag_cnt > closetag_cnt);
- 01794
- 01795 /* all right? */
- 01796 if (tag_cnt == closetag_cnt) {
- 01797 /* yes, allocate memory and copy buffer */
- 01798 mytafff = new MMSTaffFile("", this->taff_desc, "", this->external_type,
- 01799 this->ignore_blank_values, this->trace, false);
- 01800 if (mytafff) {
- 01801 int len = this->taff_buf_pos - saved_current_tag_pos;
- 01802 mytafff->taff_buf_size = sizeof(this->taff_desc->type) + sizeof(this->taff_desc->version) + len;
- 01803 mytafff->taff_buf = (unsigned char *)malloc(mytafff->taff_buf_size);
- 01804 if (mytafff->taff_buf) {
- 01805 /* copy & init */
- 01806 memcpy(mytafff->taff_buf, this->taff_buf, sizeof(this->taff_desc->type) + sizeof(this->taff_desc->version));
- 01807 memcpy(&(mytafff->taff_buf[sizeof(this->taff_desc->type) + sizeof(this->taff_desc->version)]),
- 01808 &(this->taff_buf[saved_current_tag_pos]), len);
- 01809 mytafff->getFirstTag();
- 01810 mytafff->loaded = true;
- 01811 mytafff->correct_version = true;
- 01812 }
- 01813 else {
- 01814 /* out of memory */
- 01815 delete mytafff;
- 01816 mytafff = NULL;
- 01817 }
- 01818 }
- 01819 }
- 01820
- 01821 /* restore the old buffer positions */
- 01822 this->taff_buf_pos = saved_taff_buf_pos;
- 01823 this->current_tag = saved_current_tag;
- 01824 this->current_tag_pos = saved_current_tag_pos;
- 01825
- 01826 return mytafff;
- 01827 }
- 01828
- 01829
- 01830 bool MMSTaffFile::hasAttributes() {
- 01831 char *value_str;
- 01832 int value_int;
- 01833 char *name;
- 01834 return (getFirstAttribute(&value_str, &value_int, &name) >= 0);
- 01835 }
- 01836
- 01837
- 01838 int MMSTaffFile::getFirstAttribute(char **value_str, int *value_int, char **name) {
- 01839 if (!this->current_tag_pos)
- 01840 return -1;
- 01841
- 01842 /* go to the position after the current tag */
- 01843 this->taff_buf_pos = this->current_tag_pos;
- 01844 this->taff_buf_pos+=2;
- 01845
- 01846 /* get the attribute */
- 01847 if (this->taff_buf[this->taff_buf_pos] == MMSTAFF_TAGTABLE_TYPE_ATTR)
- 01848 return getNextAttribute(value_str, value_int, name);
- 01849
- 01850 return -1;
- 01851 }
- 01852
- 01853 int MMSTaffFile::getNextAttribute(char **value_str, int *value_int, char **name) {
- 01854 /* searching for next attribute */
- 01855 do {
- 01856 switch (this->taff_buf[this->taff_buf_pos]) {
- 01857 case MMSTAFF_TAGTABLE_TYPE_ATTR: {
- 01858 int attrid = (int)this->taff_buf[this->taff_buf_pos+1];
- 01859 int len;
- 01860 this->taff_buf_pos+=2;
- 01861
- 01862 /* check if name of attribute is stored instead of id */
- 01863 if (attrid == MMSTAFF_ATTR_WITHOUT_ID) {
- 01864 len = MMSTAFF_INT32_FROM_UCHAR_STREAM(&this->taff_buf[this->taff_buf_pos]);
- 01865 this->taff_buf_pos+=sizeof(int);
- 01866 if (name)
- 01867 *name = (char*)&this->taff_buf[this->taff_buf_pos];
- 01868 this->taff_buf_pos+=len;
- 01869 }
- 01870 else
- 01871 if (name) *name=NULL;
- 01872
- 01873 /* get the length of the value */
- 01874 len = (int)this->taff_buf[this->taff_buf_pos];
- 01875 this->taff_buf_pos++;
- 01876 if (len >= 0xff) {
- 01877 len = MMSTAFF_INT32_FROM_UCHAR_STREAM(&this->taff_buf[this->taff_buf_pos]);
- 01878 this->taff_buf_pos+=sizeof(int);
- 01879 }
- 01880
- 01881 /* check the type of value and set the return values */
- 01882 if (attrid != MMSTAFF_ATTR_WITHOUT_ID) {
- 01883 TAFF_ATTRDESC *attr = this->taff_desc->tagtable[current_tag].attr;
- 01884 switch (attr[attrid].type) {
- 01885 case TAFF_ATTRTYPE_BOOL:
- 01886 case TAFF_ATTRTYPE_UCHAR:
- 01887 case TAFF_ATTRTYPE_UCHAR100:
- 01888 case TAFF_ATTRTYPE_STATE:
- 01889 case TAFF_ATTRTYPE_SEQUENCE_MODE:
- 01890 *value_str = NULL;
- 01891 { unsigned char v = this->taff_buf[this->taff_buf_pos];
- 01892 *value_int = (int)v; }
- 01893 break;
- 01894 case TAFF_ATTRTYPE_INT:
- 01895 case TAFF_ATTRTYPE_COLOR:
- 01896 *value_str = NULL;
- 01897 *value_int = MMSTAFF_INT32_FROM_UCHAR_STREAM(&this->taff_buf[this->taff_buf_pos]);
- 01898 break;
- 01899 default:
- 01900 *value_str = (char*)&this->taff_buf[this->taff_buf_pos];
- 01901 break;
- 01902 }
- 01903 }
- 01904 else
- 01905 if (name) {
- 01906 *value_str = (char*)&this->taff_buf[this->taff_buf_pos];
- 01907 }
- 01908 this->taff_buf_pos+=len;
- 01909
- 01910 if (!((attrid == MMSTAFF_ATTR_WITHOUT_ID)&&(!name)))
- 01911 /* return attribute ID */
- 01912 return attrid;
- 01913
- 01914 /* attribute has no ID and name is not set, go to the next attribute */
- 01915 break;
- 01916 }
- 01917 break;
- 01918 default:
- 01919 return -1;
- 01920 }
- 01921 } while (this->taff_buf_pos < this->taff_buf_size);
- 01922 return -1;
- 01923 }
- 01924
- 01925 bool MMSTaffFile::getAttribute(int id, char **value_str, int *value_int) {
- 01926 char *attr_name;
- 01927 int attrid = getFirstAttribute(value_str, value_int, &attr_name);
- 01928 while (attrid >= 0) {
- 01929 if (attrid == id)
- 01930 return true;
- 01931 attrid = getNextAttribute(value_str, value_int, &attr_name);
- 01932 }
- 01933 return false;
- 01934 }
- 01935
- 01936 char *MMSTaffFile::getAttributeString(int id) {
- 01937 char *value_str = NULL;
- 01938 int value_int;
- 01939 if (getAttribute(id, &value_str, &value_int))
- 01940 if (value_str)
- 01941 return value_str;
- 01942 return NULL;
- 01943 }
- 01944
- 01945
- 01946 TAFF_ATTRDESC MMSTAFF_IMAGE_RAWIMAGE_ATTR_I[] = MMSTAFF_IMAGE_RAWIMAGE_ATTR_INIT;
- 01947
- 01948 TAFF_TAGTABLE mmstaff_image_taff_tagtable[] = {
- 01949 { "rawimage", NULL, NULL, MMSTAFF_IMAGE_RAWIMAGE_ATTR_I },
- 01950 { NULL, NULL, NULL, NULL }
- 01951 };
- 01952
- 01953 TAFF_DESCRIPTION mmstaff_image_taff_description = { "mmstaff_image", 4, mmstaff_image_taff_tagtable };
- 01954
- 01955
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement