/* ============================================================ * * This file is a part of kipi-plugins project * http://www.kipi-plugins.org * * Date : 2003-10-14 * Description : batch image rotation * * Copyright (C) 2003-2005 by Renchi Raju * Copyright (C) 2004-2007 by Marcel Wiesweg * Copyright (C) 2006-2007 by Gilles Caulier * * NOTE: Do not use kdDebug() in this implementation because * it will be multithreaded. Use tqDebug() instead. * See B.K.O #133026 for details. * * 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, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #define XMD_H // C++ includes. #include // C Ansi includes. extern "C" { #include #include #include } // TQt includes. #include #include #include #include // KDE includes. #include #include #include #include // Local includes. #include "utils.h" #include "transupp.h" #include "jpegtransform.h" #include "imagerotate.h" #include "imagerotate.moc" namespace KIPIJPEGLossLessPlugin { ImageRotate::ImageRotate() : TQObject() { m_tmpFile = new KTempFile(TQString(), TQString("kipiplugin-rotate")); m_tmpFile->setAutoDelete(true); } ImageRotate::~ImageRotate() { delete m_tmpFile; } bool ImageRotate::rotate(const TQString& src, RotateAction angle, TQString& err) { TQFileInfo fi(src); if (!fi.exists() || !fi.isReadable() || !fi.isWritable()) { err = i18n("Error in opening input file"); return false; } if ( !m_tmpFile->file() ) { err = i18n("Error in opening temporary file"); return false; } TQString tmp = m_tmpFile->name(); if (Utils::isRAW(src)) { err = i18n("Cannot rotate RAW file"); return false; } else if (Utils::isJPEG(src)) { if (!rotateJPEG(src, tmp, angle, err)) { if (err == "nothing to do") { err=TQString(); return true; } return false; } } else { // B.K.O #123499 : we using Image Magick API here instead QT API // else TIFF/PNG 16 bits image are broken! if (!rotateImageMagick(src, tmp, angle, err)) return false; // We update metadata on new image. Utils tools(this); if (!tools.updateMetadataImageMagick(tmp, err)) return false; } // Move back to original file if (!Utils::MoveFile(tmp, src)) { err = i18n("Cannot update source image"); return false; } return true; } bool ImageRotate::rotateJPEG(const TQString& src, const TQString& dest, RotateAction angle, TQString& err) { Matrix transform=Matrix::none; switch(angle) { case (Rot90): { transform = Matrix::rotate90; break; } case (Rot180): { transform = Matrix::rotate180; break; } case (Rot270): { transform = Matrix::rotate270; break; } case (Rot0): { transform = Matrix::none; break; } default: { tqDebug("ImageRotate: Nonstandard rotation angle"); err = i18n("Nonstandard rotation angle"); return false; } } return transformJPEG(src, dest, transform, err); } bool ImageRotate::rotateImageMagick(const TQString& src, const TQString& dest, RotateAction angle, TQString& err) { TDEProcess process; process.clearArguments(); process << "convert"; process << "-verbose"; process << "-rotate"; switch(angle) { case (Rot90): { process << "90"; break; } case (Rot180): { process << "180"; break; } case (Rot270): { process << "270"; break; } case (Rot0): { break; } default: { tqDebug("ImageRotate: Nonstandard rotation angle"); err = i18n("Nonstandard rotation angle"); return false; } } process << src + TQString("[0]") << dest; tqDebug("ImageMagick Command line args:"); TQValueList args = process.args(); for (TQValueList::iterator it = args.begin(); it != args.end(); ++it) tqDebug("%s", (const char*)(*it)); connect(&process, TQT_SIGNAL(receivedStderr(TDEProcess *, char*, int)), this, TQT_SLOT(slotReadStderr(TDEProcess*, char*, int))); if (!process.start(TDEProcess::Block, TDEProcess::Stderr)) return false; if (!process.normalExit()) return false; switch (process.exitStatus()) { case 0: // Process finished successfully ! { return true; break; } case 15: // process aborted ! { return false; break; } } // Processing error ! err = i18n("Cannot rotate: %1").arg(m_stdErr.replace('\n', ' ')); return false; } void ImageRotate::slotReadStderr(TDEProcess*, char* buffer, int buflen) { m_stdErr.append(TQString::fromLocal8Bit(buffer, buflen)); } } // NameSpace KIPIJPEGLossLessPlugin