/*************************************************************************** sq_imageloader.cpp - description ------------------- begin : Tue Sep 20 2005 copyright : (C) 2005 by Baryshev Dmitry email : ksquirrel.iv@gmail.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "sq_imageloader.h" #include "sq_libraryhandler.h" #include #include #include #include SQ_ImageLoader * SQ_ImageLoader::m_instance = 0; SQ_ImageLoader::SQ_ImageLoader(TQObject *parent) : TQObject(parent), m_errors(0) { m_instance = this; m_image = 0; dumbscan = 0; finfo = new fmt_info; } SQ_ImageLoader::~SQ_ImageLoader() { delete finfo; if(dumbscan) free(dumbscan); if(m_image) free(m_image); } /* * Try to determine image dimensions. */ bool SQ_ImageLoader::tasteImage(const TQString &path, int *w, int *h, SQ_LIBRARY *_lib) { SQ_LIBRARY *lib; int res; fmt_codec_base *codeK; // determine library for file lib = _lib ? _lib : SQ_LibraryHandler::instance()->libraryForFile(path); if(!lib) return false; // determine codec codeK = lib->codec_il; if(!codeK) return false; // init... res = codeK->read_init(TQString(TQFile::encodeName(path)).ascii()); // error in init()! if(res != SQE_OK) { codeK->read_close(); return false; } // advance to next page res = codeK->read_next(); if(res != SQE_OK) { codeK->read_close(); return false; } else { fmt_image *image; image = codeK->image(0); *w = image->w; *h = image->h; codeK->read_close(); return true; } } /* * Try to load image and store a pointer to decoded image data in m_image. Aslo * store information about the image in finfo. */ bool SQ_ImageLoader::loadImage(const TQString &pixPath, const SQ_CodecSettings::settings &sett, bool multi, int nomorethan) { SQ_LIBRARY *lib; int res, current = 0, i, j; RGBA *scan; fmt_codec_base *codeK; fmt_image *image; finfo->image.clear(); finfo->meta.clear(); #define SQ_SAVE_INF \ *finfo = codeK->information(); \ codeK->read_close(); // reset error count m_errors = 0; // determine library for file lib = SQ_LibraryHandler::instance()->libraryForFile(pixPath); if(!lib) return false; // determine codec codeK = lib->codec_il; if(!codeK) return false; if(sett != SQ_CodecSettings::None) SQ_CodecSettings::applySettings(lib, sett); // init... res = codeK->read_init(TQString(TQFile::encodeName(pixPath)).ascii()); // error in init()! if(res != SQE_OK) { codeK->read_close(); return false; } // read all pages in image... while(true) { if(m_errors || (!multi && current) || (multi && current == nomorethan)) break; // advance to next page i = codeK->read_next(); // error occured while decoding first page if(i != SQE_OK && i != SQE_NOTOK && !current) { codeK->read_close(); return false; } else if((i != SQE_OK && i != SQE_NOTOK && current) || (i == SQE_NOTOK && current)) break; image = codeK->image(current); // realloc memory if(!current) { const int S = image->w * image->h * sizeof(RGBA); m_image = (RGBA *)realloc(m_image, S); if(!m_image) { codeK->read_close(); return false; } memset(m_image, 255, S); } else { dumbscan = (RGBA *)realloc(dumbscan, image->w * image->h * sizeof(RGBA)); if(!dumbscan) { SQ_SAVE_INF return false; } } // read all passes for(int pass = 0;pass < image->passes;pass++) { codeK->read_next_pass(); if(!current) { for(j = 0;j < image->h;j++) { scan = m_image + j * image->w; i = codeK->read_scanline(scan); m_errors += (i != SQE_OK); } } else { for(j = 0;j < image->h;j++) { i = codeK->read_scanline(dumbscan); SQ_SAVE_INF return (i == SQE_OK); } } } // flip decoded image, if needed if(image->needflip && !current) fmt_utils::flipv((char *)m_image, image->w * sizeof(RGBA), image->h); current++; } SQ_SAVE_INF // all done! return true; } // Delete buffers... void SQ_ImageLoader::cleanup(bool del) { if(dumbscan) free(dumbscan); if(del && m_image) free(m_image); dumbscan = 0; m_image = 0; } /* * Return decoded image as TQImage. */ TQImage SQ_ImageLoader::image() const { TQImage image((unsigned char*)bits(), finfo->image[0].w, finfo->image[0].h, 32, 0, 0, TQImage::LittleEndian); // if the image has alpha channel, let TQImage know it if(finfo->image[0].hasalpha) image.setAlphaBuffer(true); return image.swapRGB(); }