Perceptual Color

iohandlerfactory.h
1// SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com>
2// SPDX-License-Identifier: BSD-2-Clause OR MIT
3
4#ifndef IOHANDLERFACTORY_H
5#define IOHANDLERFACTORY_H
6
7#include "lcms2.h"
8#include <qglobal.h>
9#include <qstring.h>
10
11namespace PerceptualColor
12{
13/** @internal
14 *
15 * @brief Portable and Unicode-enabled file access for
16 * LittleCMS IO handlers.
17 *
18 * @internal
19 *
20 * This class is necessary because LittleCMS does not provide portable
21 * support for Unicode file names.
22 *
23 * - LittleCMS allows to open profiles directly from file names, but with
24 * a <tt>char*</tt> as argument for the file name. This leads to non-portable
25 * behaviour because the file name encoding differs between operation
26 * systems. And on Windows, apparently, you even need to use wide-characters
27 * to get support for Unicode file names. This does not work for us because
28 * LittleCMS requires narrow-characters for the file name. For the same
29 * reason, QFile::decodeName() and QFile::encodeName() would not help us
30 * either doing this conversion. And we would have to use either <tt>/</tt>
31 * or <tt>\</tt> as directory separator, depending on the OS. C itself
32 * does not seem to provide any portable methods for working with Unicode
33 * file names. So this solution is both: not portable and not comfortable.
34 *
35 * - LittleCMS allows to open profiles directly from <tt>FILE *</tt>. We
36 * could open a file in <tt>QFile</tt>, call <tt>QFile::handle()</tt>
37 * to get a file descriptor, and use <tt>dup</tt> to create a duplicate.
38 * Then, close the <tt>QFile</tt>, and use <tt>fdopen</tt> to create a
39 * <tt>FILE *</tt> from the duplicate file descriptor. (We need to create
40 * a duplicate of the file handle because otherwise, during the following
41 * calls, fclose() might be called by LittleCMS before QFile::close is
42 * called. This leads to undefined behaviour in some rare cases:
43 * https://stackoverflow.com/questions/9465727/convert-qfile-to-file)
44 * However, <tt>fdopen()</tt> and <tt>dup()</tt> are not part of C, but
45 * of Posix; this might not be portable. Windows, for example, has
46 * no <tt>fdopen()</tt> function but a <tt>_fdopen()</tt> function.
47 * Other systems might not have them at all. So this solution is
48 * not portable.
49 *
50 * - C++17 has <tt>filesystem::path</tt>, which seams to open files with
51 * Unicode file names. But it does not allow to generate C-Standard
52 * <tt>FILE</tt> handles, which would be necessary to connect with
53 * LittleCMS, which has a C-only interface.
54 * - Using an external library (maybe the boost library) for portable
55 * file name handling would introduce another external dependency,
56 * what we do not want.
57
58 * - LittleCMS allows to open profiles directly from a memory buffer.
59 * We could use <tt>QFile</tt> for portability, load the hole file into
60 * a memory buffer and let LittleCMS work with the memory buffer.
61 * The disadvantage would be that it raises our memory usage. This might
62 * be problematic if the ICC profile has various megabytes. It might
63 * produce a crash, when by mistake the file name points to a 10-GB
64 * video file, which would have to load completely into the buffer before
65 * being rejected.
66 *
67 * Therefore, this class provides a custom LittleCMS IO handler which
68 * internally (but invisible for LittleCMS) relies on QFile. This gives
69 * us Qt’s portability and avoids the above-mentioned disadvantages. */
70class IOHandlerFactory
71{
72public:
73 [[nodiscard]] static cmsIOHANDLER *createReadOnly(cmsContext ContextID, const QString &fileName);
74
75private:
76 Q_DISABLE_COPY(IOHandlerFactory)
77
78 /** @internal
79 *
80 * @brief No constructor, because no objects of this class are
81 * necessary. */
82 IOHandlerFactory() = delete;
83
84 static cmsBool close(cmsIOHANDLER *iohandler);
85 static cmsUInt32Number read(cmsIOHANDLER *iohandler, void *Buffer, cmsUInt32Number size, cmsUInt32Number count);
86 static cmsBool seek(cmsIOHANDLER *iohandler, cmsUInt32Number offset);
87 [[nodiscard]] static cmsUInt32Number tell(cmsIOHANDLER *iohandler);
88 static cmsBool write(cmsIOHANDLER *iohandler, cmsUInt32Number size, const void *Buffer);
89};
90
91} // namespace PerceptualColor
92
93#endif // IOHANDLERFACTORY_H
The namespace of this library.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:36 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.