summaryrefslogtreecommitdiffstats
path: root/src/imageedit/sq_converter.cpp
diff options
context:
space:
mode:
authorMichele Calgaro <[email protected]>2025-02-10 15:10:13 +0900
committerMichele Calgaro <[email protected]>2025-02-10 15:10:13 +0900
commit203fcb8d90752b546c672c625927a136b959fcfb (patch)
treea899621e4cb63e2cdd9b94f889ee9d0ae8561bf0 /src/imageedit/sq_converter.cpp
parent98c274834c63c7fa4a9a494fdf7cd483336714d5 (diff)
downloadksquirrel-203fcb8d90752b546c672c625927a136b959fcfb.tar.gz
ksquirrel-203fcb8d90752b546c672c625927a136b959fcfb.zip
Rename 'ksquirrel' folder to 'src'
Signed-off-by: Michele Calgaro <[email protected]>
Diffstat (limited to 'src/imageedit/sq_converter.cpp')
-rw-r--r--src/imageedit/sq_converter.cpp444
1 files changed, 444 insertions, 0 deletions
diff --git a/src/imageedit/sq_converter.cpp b/src/imageedit/sq_converter.cpp
new file mode 100644
index 0000000..04ab3aa
--- /dev/null
+++ b/src/imageedit/sq_converter.cpp
@@ -0,0 +1,444 @@
+/***************************************************************************
+ sq_converter.cpp - description
+ -------------------
+ begin : ??? Mar 3 2005
+ copyright : (C) 2005 by Baryshev Dmitry
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <tqapplication.h>
+#include <tqfile.h>
+
+#include <tdemessagebox.h>
+#include <kstringhandler.h>
+#include <kstandarddirs.h>
+#include <tdetempfile.h>
+#include <tdelocale.h>
+
+#include "ksquirrel.h"
+#include "sq_converter.h"
+#include "sq_widgetstack.h"
+#include "sq_diroperator.h"
+#include "sq_libraryhandler.h"
+#include "sq_config.h"
+#include "sq_errorstring.h"
+#include "sq_imageloader.h"
+#include "sq_imageconvert.h"
+
+SQ_Converter * SQ_Converter::m_sing = 0;
+
+SQ_Converter::SQ_Converter(TQObject *parent) : TQObject(parent)
+{
+ m_sing = this;
+
+ err_internal = i18n("internal error") + '\n';
+ err_failed = i18n("failed") + '\n';
+
+ special_action = i18n("Converting");
+
+ image = 0;
+}
+
+SQ_Converter::~SQ_Converter()
+{
+ if(image) free(image);
+}
+
+void SQ_Converter::slotStartEdit()
+{
+ files.clear();
+
+ KFileItemList *items = (KFileItemList *)SQ_WidgetStack::instance()->selectedItems();
+
+ if(!items || !items->count())
+ {
+ KMessageBox::information(KSquirrel::app(), i18n("Select files to edit"));
+ return;
+ }
+ else if(!items->first()->url().isLocalFile())
+ {
+ KMessageBox::information(KSquirrel::app(), i18n("Converter cannot work with remote files.\nSorry"));
+ return;
+ }
+
+ KFileItem *i = items->first();
+
+ for(;i;i = items->next())
+ {
+ if(i->isFile())
+ files.append(i->url().path());
+ }
+
+ startEditPrivate();
+}
+
+TQString SQ_Converter::adjustFileName(const TQString &globalprefix, const TQString &name1, int replace, TQString putto, bool paged, int page)
+{
+ TQFileInfo ff(name1);
+ TQString name = ff.dirPath() + '/' + (replace == 0 ? globalprefix : (replace == 2 ? TQString() : globalprefix)) + ff.fileName();
+ ff = TQFileInfo(name);
+
+ TQString result, inner, filter = lw->filter;
+ TQString ext = ff.extension(false);
+ TQString prefix, suffix, name2 = name;
+ TQString spage = TQString::fromLatin1("page_%1.").arg((TQString::fromLatin1("%1").arg(page)).rightJustify(3, '0'));
+
+ if(!putto.isEmpty())
+ {
+ if(TQFile::exists(putto))
+ name2 = putto + '/' + ff.fileName();
+ }
+
+ prefix = name2;
+
+ prefix.truncate(name2.length() - ext.length());
+
+ suffix = (SQ_LibraryHandler::instance()->knownExtension(TQString::fromLatin1("*.") + ext))
+ ? TQString(lw->codec->extension(32)) : ext;
+
+ if(replace == 0 || replace == 2)
+ result = (!paged) ? (prefix + inner + suffix) : (prefix + spage + inner + suffix);
+ else
+ {
+ result = (!paged) ? (prefix + inner + suffix) : (prefix + spage + inner + suffix);
+
+ if(TQFile::exists(result))
+ {
+ inner = TQString::fromLatin1("1.");
+ result = (!paged) ? (prefix + inner + suffix) : (prefix + spage + inner + suffix);
+ }
+ }
+
+ return result;
+}
+
+void SQ_Converter::errorjmp(jmp_buf jmp, const int code)
+{
+ error_code = code;
+ longjmp(jmp, 1);
+}
+
+void SQ_Converter::decodingCycle()
+{
+ int i, j;
+ TQString name;
+ jmp_buf jmp;
+ RGBA *scan;
+ int errors, gerrors = 0, current;
+ TQString putto;
+ int replace = imageopt.where_to_put;
+ bool brk;
+
+ SQ_Config::instance()->setGroup("Edit tools");
+
+ int allpages = SQ_Config::instance()->readNumEntry("load_pages", 0);
+ int pages_num = SQ_Config::instance()->readNumEntry("load_pages_number", 1);
+
+ if(pages_num < 1) pages_num = 1;
+
+ altw = SQ_LibraryHandler::instance()->libraryByName(SQ_Config::instance()->readEntry("altlibrary", "Portable Network Graphics"));
+ multi = SQ_Config::instance()->readBoolEntry("multi", true);
+
+ tempfile = new KTempFile;
+ tempfile->setAutoDelete(true);
+
+ if(tempfile->status())
+ {
+ KMessageBox::error(KSquirrel::app(), i18n("Temporary file creation failed"));
+ return;
+ }
+
+ tempfile->close();
+
+ TQStringList::iterator last_it = files.fromLast();
+ TQStringList::iterator itEnd = files.end();
+ convert->startConvertion(files.count());
+
+ putto = imageopt.putto;
+
+ for(TQStringList::iterator it = files.begin();it != itEnd;++it)
+ {
+ currentFile = *it;
+ last = (it == last_it);
+
+ TQFileInfo ff(*it);
+
+ emit convertText(special_action + ' ' + KStringHandler::rsqueeze(ff.fileName()) + "... ", false);
+
+ if((lr = SQ_LibraryHandler::instance()->libraryForFile(*it)))
+ {
+ lw = SQ_LibraryHandler::instance()->libraryByName(convopt.libname);
+
+ if(!lr || !lw)
+ {
+ gerrors++;
+ emit convertText(err_internal, true);
+ emit oneFileProcessed();
+ continue;
+ }
+
+ name = TQFile::encodeName(*it);
+
+ i = lr->codec->read_init(name.ascii());
+
+ if(setjmp(jmp))
+ {
+ gerrors++;
+
+ lr->codec->read_close();
+
+ emit convertText(SQ_ErrorString::instance()->stringSN(error_code), true);
+ emit oneFileProcessed();
+
+ continue;
+ }
+
+ if(i != SQE_OK)
+ errorjmp(jmp, i);
+
+ errors = 0;
+ current = 0;
+
+ while(true)
+ {
+ brk = (allpages == 1 && current) || (allpages == 2 && current == pages_num);
+
+ i = lr->codec->read_next();
+
+ im = lr->codec->image(current-1);
+
+ if(i != SQE_OK || brk)
+ {
+ if(i == SQE_NOTOK || brk)
+ {
+ if(current == 1)
+ name = adjustFileName(prefix, *it, replace, putto);
+ else
+ name = adjustFileName(prefix, *it, replace, putto, true, current);
+
+ lastFrame = last;
+
+ i = manipAndWriteDecodedImage(tempfile->name(), im);
+
+ emit convertText(errors ? (i18n("1 error", "%n errors", errors)+'\n') : SQ_ErrorString::instance()->stringSN(SQE_OK), true);
+ emit oneFileProcessed();
+
+ i = SQE_OK;
+
+ if(replace == 2)
+ {
+ emit convertText(i18n("Removing") + KStringHandler::rsqueeze(ff.fileName()) + TQString("... "), false);
+
+ bool b = TQFile::remove(*it);
+
+ emit convertText(b ? SQ_ErrorString::instance()->stringSN(SQE_OK) : err_failed, true);
+ emit oneFileProcessed();
+ }
+
+ i = copyFile(tempfile->name(), name);
+
+ break;
+ }
+ else
+ errorjmp(jmp, i);
+ }
+
+ if(current)
+ {
+ name = adjustFileName(prefix, *it, replace, putto, true, current);
+
+ lastFrame = false;
+
+ manipAndWriteDecodedImage(tempfile->name(), im);
+ i = copyFile(tempfile->name(), name);
+ }
+
+ im = lr->codec->image(current);
+
+ image = (RGBA *)realloc(image, im->w * im->h * sizeof(RGBA));
+
+ if(!image)
+ {
+ i = SQE_R_NOMEMORY;
+ errorjmp(jmp, i);
+ }
+
+ for(int pass = 0;pass < im->passes;pass++)
+ {
+ lr->codec->read_next_pass();
+
+ for(j = 0;j < im->h;j++)
+ {
+ scan = image + j * im->w;
+ i = lr->codec->read_scanline(scan);
+ errors += (int)(i != SQE_OK);
+ }
+ }
+
+ if(im->needflip)
+ fmt_utils::flipv((char *)image, im->w * sizeof(RGBA), im->h);
+
+ convert->fillWriteOptions(&opt, lw->opt);
+
+ opt.alpha = im->hasalpha;
+
+ current++;
+ }
+
+ lr->codec->read_close();
+ }
+ else
+ {
+ emit convertText(SQ_ErrorString::instance()->stringSN(SQE_R_NOTSUPPORTED), true);
+ emit oneFileProcessed();
+ }
+ }
+
+ if(image)
+ {
+ free(image);
+ image = 0;
+ }
+
+ delete convert;
+ delete tempfile;
+
+ if(imageopt.close && !gerrors)
+ emit done(true);
+ else
+ emit done(false);
+}
+
+int SQ_Converter::manipAndWriteDecodedImage(const TQString &name, fmt_image *im)
+{
+ int passes = opt.interlaced ? lw->opt.passes : 1;
+ int s, j, err;
+ RGBA *scan = 0;
+
+ scan = new RGBA [im->w];
+
+ if(!scan)
+ return SQE_W_NOMEMORY;
+
+ err = lw->codec->write_init(name.ascii(), *im, opt);
+
+ if(err != SQE_OK)
+ goto error_exit;
+
+ err = lw->codec->write_next();
+
+ if(err != SQE_OK)
+ goto error_exit;
+
+ for(s = 0;s < passes;s++)
+ {
+ err = lw->codec->write_next_pass();
+
+ if(err != SQE_OK)
+ goto error_exit;
+
+ for(j = 0;j < im->h;j++)
+ {
+ if(lw->opt.needflip)
+ determineNextScan(*im, scan, im->h-j-1);
+ else
+ determineNextScan(*im, scan, j);
+
+ err = lw->codec->write_scanline(scan);
+
+ if(err != SQE_OK)
+ goto error_exit;
+ }
+ }
+
+ err = SQE_OK;
+
+ error_exit:
+
+ lw->codec->write_close();
+
+ delete scan;
+
+ return err;
+}
+
+int SQ_Converter::copyFile(const TQString &src, const TQString &dst) const
+{
+ TQFile f_src(src), f_dst(dst);
+ TQ_LONG read;
+ char data[4096];
+
+ if(!f_src.open(IO_ReadOnly))
+ return SQE_R_NOFILE;
+
+ if(!f_dst.open(IO_WriteOnly))
+ {
+ f_src.close();
+ return SQE_W_NOFILE;
+ }
+
+ while(!f_src.atEnd())
+ {
+ read = f_src.readBlock(data, sizeof(data));
+
+ f_dst.writeBlock(data, read);
+
+ if(f_dst.status() != IO_Ok || f_src.status() != IO_Ok)
+ {
+ f_src.close();
+ f_dst.close();
+
+ return SQE_W_ERROR;
+ }
+ }
+
+ f_src.close();
+ f_dst.close();
+
+ return SQE_OK;
+}
+
+void SQ_Converter::determineNextScan(const fmt_image &im, RGBA *scan, int y)
+{
+ memcpy(scan, image + y * im.w, im.w * sizeof(RGBA));
+}
+
+void SQ_Converter::startEditPrivate()
+{
+ convert = new SQ_ImageConvert(KSquirrel::app());
+ convert->setCaption(i18n("Convert 1 file", "Convert %n files", files.count()));
+
+ connect(convert, TQ_SIGNAL(convert(SQ_ImageOptions*, SQ_ImageConvertOptions*)), this, TQ_SLOT(slotStartConvert(SQ_ImageOptions*, SQ_ImageConvertOptions*)));
+ connect(this, TQ_SIGNAL(convertText(const TQString &, bool)), convert, TQ_SLOT(slotDebugText(const TQString &, bool)));
+ connect(this, TQ_SIGNAL(oneFileProcessed()), convert, TQ_SLOT(slotOneProcessed()));
+ connect(this, TQ_SIGNAL(done(bool)), convert, TQ_SLOT(slotDone(bool)));
+
+ convert->exec();
+}
+
+void SQ_Converter::slotStartConvert(SQ_ImageOptions *o, SQ_ImageConvertOptions *copt)
+{
+ imageopt = *o;
+ convopt = *copt;
+
+ decodingCycle();
+}
+
+#include "sq_converter.moc"