diff options
Diffstat (limited to 'src/sq_utils.cpp')
| -rw-r--r-- | src/sq_utils.cpp | 188 | 
1 files changed, 188 insertions, 0 deletions
diff --git a/src/sq_utils.cpp b/src/sq_utils.cpp new file mode 100644 index 0000000..20eea42 --- /dev/null +++ b/src/sq_utils.cpp @@ -0,0 +1,188 @@ +/*************************************************************************** +                          sq_utils.cpp  -  description +                             ------------------- +    begin                : Thu Aug 2 2007 +    copyright            : (C) 2007 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 <tqstring.h> + +#include <ksquirrel-libs/fmt_defs.h> + +#include "sq_libraryhandler.h" +#include "sq_utils.h" + +#ifndef KSQUIRREL_PART +#include <kurl.h> +#include "sq_imageloader.h" +#include "sq_thumbnailinfo.h" +#include "sq_thumbnailsize.h" +#endif + +#ifdef SQ_HAVE_KEXIF +#include <libkexif/kexifdata.h> +#endif + +void SQ_Utils::exifRotate(const TQString &file, TQImage &im, int o) +{ +#ifdef SQ_HAVE_KEXIF +    im = im.xForm(SQ_Utils::exifGetMatrix(file, o)); +#endif +} + +TQWMatrix SQ_Utils::exifGetMatrix(const TQString &file, int o) +{ +    TQWMatrix matrix; + +#ifdef SQ_HAVE_KEXIF +    int O; + +    if(o == -1) +    { +        KExifData data; +        data.readFromFile(file); +        O = data.getImageQt::Orientation(); +    } +    else +        O = o; + +    switch(O) +    { +        case KExifData::HFLIP:        matrix.scale(-1,1); break; +        case KExifData::ROT_180:      matrix.rotate(180); break; +        case KExifData::VFLIP:        matrix.scale(1,-1); break; +        case KExifData::ROT_90_HFLIP: matrix.scale(-1,1); matrix.rotate(90); break; +        case KExifData::ROT_90:       matrix.rotate(90);  break; +        case KExifData::ROT_90_VFLIP: matrix.scale(1,-1); matrix.rotate(90); break; +        case KExifData::ROT_270:      matrix.rotate(270); break; + +        // normal rotation or unspecified +        default: ; +    } + +#endif + +    return matrix; +} + +TQImage SQ_Utils::scaleImage(unsigned char *im, int w, int h, int fitwithin) +{ +    if(w <= fitwithin && h <= fitwithin) +    { +        TQImage scaled(im, w, h, 32, 0, 0, TQImage::LittleEndian); +        scaled.setAlphaBuffer(true); +        return scaled.copy(); +    } + +    TQImage orig(im, w, h, 32, 0, 0, TQImage::LittleEndian); +    orig.setAlphaBuffer(true); + +    // return scaled image +    return SQ_Utils::scale(orig, fitwithin, fitwithin, SQ_Utils::SMOOTH_FAST, TQImage::ScaleMin); +} + +#ifndef KSQUIRREL_PART +bool SQ_Utils::loadThumbnail(const KURL &pixPath, SQ_Thumbnail &t) +{ +    SQ_LIBRARY *lib = 0; + +#ifdef SQ_HAVE_KEXIF +    lib = SQ_LibraryHandler::instance()->libraryForFile(pixPath.path()); +    bool th = false; + +    if(lib) +    { +        KExifData data; +        data.readFromFile(pixPath.path()); +        TQImage im = data.getThumbnail(); + +        if(!im.isNull()) +        { +            SQ_Utils::exifRotate(TQString(), im, data.getImageQt::Orientation()); + +            th = true; +            t.w = 0; +            t.h = 0; +            t.mime = lib->mime; + +            TQString w, h; +            w = im.text("Thumb::Image::Width"); +            h = im.text("Thumb::Image::Height"); +            t.w = w.toInt(); +            t.h = h.toInt(); + +            if(!t.w || !t.h) +                SQ_ImageLoader::instance()->tasteImage(pixPath.path(), &t.w, &t.h, lib); + +            t.thumbnail = SQ_Utils::scaleImage((unsigned char *)im.bits(), im.width(), +                im.height(), SQ_ThumbnailSize::biggest()); +            t.thumbnail = t.thumbnail.swapRGB(); +        } +    } +    else +        return false; + +    // thumbnail loaded - nothing to do, +    // or load thumbnail by hands otherwise. +    if(th) +        return true; +#endif + +    fmt_info *finfo; + +    RGBA *all; + +    bool b = SQ_ImageLoader::instance()->loadImage(pixPath.path(), SQ_CodecSettings::ThumbnailLoader); + +    finfo = SQ_ImageLoader::instance()->info(); +    all = SQ_ImageLoader::instance()->bits(); + +    // memory allocation failed in SQ_ImageLoader::loadImage() +    if(!all) +        return false; + +    // another error occured... +    if(!b) +    { +        // if our image is partially corrupted - show it. The image +        // is partially corrupted, if number of errors < number of scanlines +        // and at least one page was loaded. +        if(!finfo->image.size() +            || (SQ_ImageLoader::instance()->errors() == finfo->image[0].h && finfo->image.size() == 1)) +        { +            SQ_ImageLoader::instance()->cleanup(); +            return false; +        } +    } + +    if(!lib) lib = SQ_LibraryHandler::instance()->libraryForFile(pixPath.path()); + +    t.w = finfo->image[0].w; +    t.h = finfo->image[0].h; +    t.mime = lib->mime; + +    t.thumbnail = SQ_Utils::scaleImage((unsigned char *)all, finfo->image[0].w, +            finfo->image[0].h, SQ_ThumbnailSize::biggest()); + +    SQ_ImageLoader::instance()->cleanup(); + +    // finally, rotate thumbnail using EXIF +    SQ_Utils::exifRotate(pixPath.path(), t.thumbnail); + +    return true; +} +#endif  | 
