File indexing completed on 2024-04-21 15:12:13

0001 /************************************************************************
0002  *                                  *
0003  *  This file is part of Kooka, a scanning/OCR application using    *
0004  *  Qt <http://www.qt.io> and KDE Frameworks <http://www.kde.org>.  *
0005  *                                  *
0006  *  Copyright (C) 1999-2016 Klaas Freitag <freitag@suse.de>     *
0007  *                          Jonathan Marten <jjm@keelhaul.me.uk>    *
0008  *                                  *
0009  *  Kooka is free software; you can redistribute it and/or modify it    *
0010  *  under the terms of the GNU Library General Public License as    *
0011  *  published by the Free Software Foundation and appearing in the  *
0012  *  file COPYING included in the packaging of this file;  either    *
0013  *  version 2 of the License, or (at your option) any later version.    *
0014  *                                  *
0015  *  As a special exception, permission is given to link this program    *
0016  *  with any version of the KADMOS OCR/ICR engine (a product of     *
0017  *  reRecognition GmbH, Kreuzlingen), and distribute the resulting  *
0018  *  executable without including the source code for KADMOS in the  *
0019  *  source distribution.                        *
0020  *                                  *
0021  *  This program is distributed in the hope that it will be useful, *
0022  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *
0023  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   *
0024  *  GNU General Public License for more details.            *
0025  *                                  *
0026  *  You should have received a copy of the GNU General Public       *
0027  *  License along with this program;  see the file COPYING.  If     *
0028  *  not, see <http://www.gnu.org/licenses/>.                *
0029  *                                  *
0030  ************************************************************************/
0031 
0032 #ifndef SCANIMAGE_H
0033 #define SCANIMAGE_H
0034 
0035 #include <qimage.h>
0036 #include <qurl.h>
0037 #include <qsharedpointer.h>
0038 
0039 #include "kookascan_export.h"
0040 
0041 
0042 /**
0043  * @short An image representing scanned results or loaded from the gallery.
0044  *
0045  * @author Klaas Freitag
0046  * @author Jonathan Marten
0047  *
0048  * A class that represents an image, based on @c QImage with extensions for
0049  * image meta-information and supporting image formats that can contain
0050  * multiple pages.
0051  */
0052 
0053 class KOOKASCAN_EXPORT ScanImage : public QImage
0054 {
0055 public:
0056     /**
0057      * A pointer to a @c ScanImage.  Always use this to pass around an image,
0058      * do not use a plain pointer or assume that it is a QImage unless it can
0059      * be assured that it will only be used for immediate reference and will
0060      * not be retained, copied or deleted.  The shared pointer can be copied,
0061      * the @c QSharedPointer will manage reference counting and deletion.
0062      **/
0063     typedef QSharedPointer<ScanImage> Ptr;
0064 
0065     /**
0066      * An image type.  This is not the detailed format of the image
0067      * data (which is available via @c QImage::Format), but a general
0068      * category which an application or its user will be interested in.
0069      **/
0070     enum ImageType
0071     {
0072         None        = 0x00,             ///< None, unknown or not resolved yet
0073         BlackWhite  = 0x01,             ///< Black/white bitmap
0074         Greyscale   = 0x02,             ///< Grey scale
0075         LowColour   = 0x04,             ///< Low colour (indexed with palette)
0076         HighColour  = 0x08,             ///< High colour (RGB)
0077         Preview     = 0x10              ///< Preview image
0078     };
0079     Q_DECLARE_FLAGS(ImageTypes, ImageType)
0080 
0081     /**
0082      * Constructor.  Creates an image from a @c QImage.
0083      * A shallow copy is made of the image data, which as with @c QImage
0084      * is automatically detached if it is modified.
0085      *
0086      * @see QImage::QImage(const QImage &)
0087      **/
0088     explicit ScanImage(const QImage &img);
0089 
0090     /**
0091      * Constructor.  Creates an image and loads it from a file.
0092      *
0093      * If the URL has a numeric fragment, then this requests the specified
0094      * subimage from the containing file.  Otherwise,  the main image is read
0095      * and the count of subimages, if it has any, is set.
0096      *
0097      * @param url URL of the file to be loaded
0098      * @note If there was an error loading the file, then @c errorString() can
0099      * be used to obtain the error message.
0100      * @see QImage::QImage(const QString &, const char *)
0101      **/
0102     explicit ScanImage(const QUrl &url);
0103 
0104     /**
0105      * Constructor.  Creates an image with the specified size and @p format.
0106      **/
0107     ScanImage(int width, int height, QImage::Format format);
0108 
0109     /**
0110      * Destructor.
0111      **/
0112     ~ScanImage() = default;
0113 
0114     /**
0115      * Get an error message from the image load operation.
0116      *
0117      * @return the error string, or a null string if there was no error.
0118      **/
0119     QString errorString() const             { return (m_errorString); }
0120 
0121     /**
0122      * The number of subimages.
0123      *
0124      * @return the subimage count, or 0 if there are no subimages
0125      **/
0126     int subImagesCount() const              { return (m_subImages); }
0127 
0128     /**
0129      * Check whether this image is a subimage.
0130      *
0131      * @return @c true if this image is a subimage
0132      **/
0133     bool isSubImage() const;
0134 
0135     /**
0136      * The URL of the image.
0137      *
0138      * @return the image URL, or an invalid URL if it was not loaded from a file.
0139      **/
0140     QUrl url() const                    { return (m_url); }
0141 
0142     /**
0143      * Checks whether the image is file bound;
0144      * that is, if it was originally loaded from a file.
0145      *
0146      * @return @c true if the image was loaded from a file
0147      **/
0148     bool isFileBound() const;
0149 
0150     /**
0151      * Set the name of the scanner that was used to generate the image.
0152      *
0153      * @param scanner the new scanner name
0154      **/
0155     void setScannerName(const QByteArray &scanner);
0156 
0157     /**
0158      * Get the scanner name that was set for the image.
0159      *
0160      * @return the scanner name
0161      * @see setScannerName
0162      **/
0163     QByteArray getScannerName() const;
0164 
0165     /**
0166      * Set the X resolution of the image in dots per inch.
0167      *
0168      * @param res the new X resolution
0169      * @see getXResolution
0170      **/
0171     void setXResolution(int res);
0172 
0173     /**
0174      * Set the Y resolution of the image in dots per inch.
0175      *
0176      * @param res the new Y resolution
0177      * @see getXResolution
0178      **/
0179     void setYResolution(int res);
0180 
0181     /**
0182      * Get the X resolution of the image in dots per inch.
0183      *
0184      * @return the X resolution, or the QImage default if it has not been set.
0185      * @see setXResolution
0186      **/
0187     int getXResolution() const;
0188 
0189     /**
0190      * Get the Y resolution of the image in dots per inch.
0191      *
0192      * @return the Y resolution, or the QImage default if it has not been set.
0193      * @see setYResolution
0194      **/
0195     int getYResolution() const;
0196 
0197     /**
0198      * Set the image type.
0199 
0200      * This is used when an image is being created to receive scan results,
0201      * if it can be deduced from the SANE parameters.
0202      *
0203      * @param type The image type
0204      **/
0205     void setImageType(ScanImage::ImageType type)    { mImageType = type; }
0206 
0207     /**
0208      * Get the image type.
0209      *
0210      * If the image type was initially set from the SANE parameters
0211      * via @c setImageType(), then that is returned.  If no image type has
0212      * been set then the type is deduced from the image data.
0213      *
0214      * @return the image type.
0215      **/
0216     ScanImage::ImageType imageType() const;
0217 
0218 private:
0219     void init();
0220     QString loadTiffDir(const QString &file, int subno);
0221 
0222 private:
0223     Q_DISABLE_COPY(ScanImage)
0224 
0225     int m_subImages;
0226     QUrl m_url;
0227     QString m_errorString;
0228     ScanImage::ImageType mImageType;
0229 };
0230 
0231 // Not doing Q_DECLARE_OPERATORS_FOR_FLAGS(ScanImage::ImageTypes) here.
0232 // The only place that uses an OR-ed combination of types is FormatDialog,
0233 // so the operators are declared there.
0234 
0235 // Allow the shared pointer to be stored in a QVariant.
0236 Q_DECLARE_METATYPE(ScanImage::Ptr)
0237 
0238 /**
0239  * Conversion between resolutions in dots-per-inch (used by SANE and the scanner GUI)
0240  * and dots-per-metre (used by QImage).
0241  **/
0242 #define DPM_TO_DPI(d)       qRound((d)*2.54/100)    // dots/metre -> dots/inch
0243 #define DPI_TO_DPM(d)       qRound((d)*100/2.54)    // dots/inch -> dots/metre
0244 
0245 
0246 #endif                          // SCANIMAGE_H