[Development] Fwd: Imageformats v2

Иван Комиссаров abbapoh at gmail.com
Wed May 20 12:46:18 CEST 2015

---------- Forwarded message ----------
From: André Somers <andre at familiesomers.nl>
Date: 2015-05-20 13:19 GMT+03:00
Subject: Re: [Development] Imageformats v2
To: Иван Комиссаров <abbapoh at gmail.com>

 Иван Комиссаров schreef op 20-5-2015 om 11:06:

2015-05-20 10:05 GMT+03:00 André Somers <andre at familiesomers.nl>:

>  Иван Комиссаров schreef op 19-5-2015 om 19:43:
 ImageDocument doesn't need to inherit QObject in order to listen to
> QIODevice signals of course. First of all, it could have rather than be a
> QObject, and second of all you can connect to almost anything callable
> nowadays. I'm not saying that being a QObject is a bad thing per se, just
> that your argument for it isn't all that convincing to me.
>  Are you sure a QString as an error() is the best choice? There are other
> places in the Qt API where an enum is used instead. I think an enum would
> probably be a better choice: it is easier to deal with in errorhanding (no
> string comparisons needed; localization issues).

 Please, provide me an example how to handle QImageReader::DeviceError,
QImageReader::UnsupportedFormatError or QImageReader::InvalidDataError.

Show different error messages for instance. Invalid data points to a
corrupted file. That is not the same as just not recognizing the file
format or having a network connection break in the middle of reading.

 Would it then not be better to be explicit about this, and just call it
> like that: bool readHeader()? I don't think it is a good idea to try to
> emulate the QIODevice API for something that isn't one. It is just
> confusing IMHO. What happens if the ImageDocument can, but the underlying
> QIODevice cannot write?

 What happens if user forgot to call to readHeader()? In case document is
not opened, it's quite easy - we reject any further operations. For now,
open() checks open flags of the device and tries to reopen device in write
mode if necessary. It fails if device cannot be opened.

Perhaps it should just read the header directly when opening from
file/iodevice and have an isValid() method or something like that?

>  So what does it actually do?

 Nothing for now:) But it can write end markers of the file and close the

Not sure if that is a good idea. If you didn't open the device, you should
not close it.

      capabilities() method returns capabilities (yep) of a format, see
> CapabilityFlag enum.
>  Hmm? The capabilities of the document? Don't the capabilities belong to
> the format instead? Judging from the API you have presented so far, I got
> the impression that an ImageDocument could represent image containers in
> any format. Now, it seems like the capabilities of the format are leaking
> into the document. How do you construct a document from scratch then? Where
> do the capabilities come from? Can I use ImageDocument to convert between
> two different formats?

 So, do you suggest move those options to ImageIoHandler? I don't think
this is good idea. Right now, users are forced to use "private" class
QImageIOHandler only for option flags enum. I think, that class should be
used only to create new handlers and typical user of a Document shouldn't
know about it.

Fair enough. But that means I think that an ImageDocument should have a
clear type at any time. That means you either create it with that type, get
the type from the image you are reading, or convert to that type.

  Typicall usecase is - open document for writing, check what capabilities
are present and add resources to the document. But you can add various
resources first, then open for writing and call write().

Well, you can if you know the capabilities of the file you want to create,
I'd say. I don't think I would allow adding resources to a file if the
format can't support those resources.

  Yes, this is possible to resave document in the other format, hanlder
just should drop anything it doesn't support. We have no mipmap support -
ok, we just save first mipmap. We have no volume texture support - ok, just
save first slice.
There should be an API that will allow to access those "default" images.

Thinking about this, I think I'd make the conversion explicit. If you
loaded a multipage TIFF and want to save as a normal PNG, you could either
have a void convert(QMimeType type) that converts the current document to
the new value (dropping unsupported features in the process) and/or have a
ImageDocument converted(QMimeType type) function that creates a new
ImageDocument in the requested format based on the current document. Then,
save _that_ document.

Perhaps you/the file format plugin could even offer different options of
how to deal with the degradation. Layers might be flattened to a single
image, meta data from a specific image stored in the main meta data or vise
versa, pages glued together to form a single image... Even if the current
structure doesn't offer it, it would be nice if the API were such that such
fine-tuning would be possible.

>  I am wondering if this is really the right slicing of the possible
> contents. Pages were already mentioned before. Do you really need to be
> able to have the document represent a 2D array of vectors of images (in
> case you are using frames, mipmaps with volumne textures)? Are there image
> formats like that that we need to support in Qt? It also results in an
> overly complicated setup for the simple use cases I think.

 That's the best way i found.
For the simple usecase, there can be Document::image() method that simply
returns a "default" image (of mipmap 0, frame/page 0, slice 0).

> Might it not be better to have ImageDocument contain a collection of
> QImages directly, that can have different kinds of relationships with each
> other and that you can somehow query for if you need to?

 I was thinking about that. DDS can have up to mipmapCount*frameCount*6.
How do you suppose to get all sides for frame 10, mipmap 5?

With something like document.images().frame(10).mipmap(5)? That would
result in a list of 6 images for the requested frame and mipmap.

If images() returns a QVector<QImage>, you could use the same trick as used
in QByteArrayList to add some special filtering methods on it without
actually subclassing QVector<QImage>.

frame() and mipmap() (and side() and page() and layer() and whatever else
one might come up with) could act as filtering functions that again return
a list of images that has these methods.

  There was an idea to store mipmap/frame/side in ImageMeta::options and to
use something like document->filterResources(options). But there are
problems - i already have Document::meta. I can write something like
doc->meta.setOption(Side, PositiveX), but this makes little sense, API is

Well, I don't know how your Meta things work of course, so I cannot comment
on that. To me it makes little sense to set a meta property that belongs to
a specific image on a document directly, but that may be my
misunderstanding of your design.

> For an application I am working on at work, I actually wrote a document
> class a bit like that. The document contains a series of images: images
> made of the left or right eye, from different angles, in different wave
> lengths (IR, green laser, color - and these are actually really different
> types of images!) in any combination. The set can contain any of these, but
> need not contain all. We keep them all in a single ImageCollection that you
> can simply query for things like "which eyes occur in the set" but also
> filter back using a method filtered() with overloads for all the different
> dimentions we have, returning just another image collection. Perhaps
> ImageDocument could work in a similar way to collapse pages, frames, layers
> and mipmaps into?

 Too complex indexation.

I think it is actually simpler than forcing a 2D array onto image document
formats that don't benefit from it.

  How do i supposed to control that EACH mipmap have the same number of
frames as document->frameCount(). I didn't find suitable solution.

Why would you need to control that? If an image format requires it, then
that image format should impose that limit (or even auto-create the missing
ones?) but I don't see why it should be a general limitation. Perhaps there
are formats where it is possible that one page has a mipmap, while others
don't? Just the first page for instance to provide a quick preview?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20150520/b5566329/attachment.html>

More information about the Development mailing list