Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickimageprovider.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
9#include <QtQuick/private/qsgcontext_p.h>
10#include <private/qqmlglobal_p.h>
11#include <QtGui/qcolorspace.h>
12
14
15/*!
16 \class QQuickTextureFactory
17 \since 5.0
18 \brief The QQuickTextureFactory class provides an interface for loading custom textures from QML.
19 \inmodule QtQuick
20
21 The purpose of the texture factory is to provide a placeholder for a image
22 data that can be converted into an OpenGL texture.
23
24 Creating a texture directly is not possible as there is rarely an OpenGL context
25 available in the thread that is responsible for loading the image data.
26*/
27
28/*!
29 Constructs a texture factory. Since QQuickTextureFactory is abstract, it
30 cannot be instantiated directly.
31*/
32
33QQuickTextureFactory::QQuickTextureFactory()
34{
35}
36
37/*!
38 Destroys the texture factory.
39*/
40
41QQuickTextureFactory::~QQuickTextureFactory()
42{
43}
44
45/*!
46 \fn int QQuickTextureFactory::textureByteCount() const
47
48 Returns the number of bytes of memory the texture consumes.
49*/
50
51/*!
52 \fn QImage QQuickTextureFactory::image() const
53
54 Returns an image version of this texture.
55
56 The lifespan of the returned image is unknown, so the implementation should
57 return a self contained QImage, not make use of the QImage(uchar *, ...)
58 constructor.
59
60 This function is not commonly used and is expected to be slow.
61 */
62
63QImage QQuickTextureFactory::image() const
64{
65 return QImage();
66}
67
68/*!
69 Returns a QQuickTextureFactory holding the given \a image.
70
71 This is typically used as a helper in QQuickImageResponse::textureFactory.
72
73 \since 5.6
74 */
75
76QQuickTextureFactory *QQuickTextureFactory::textureFactoryForImage(const QImage &image)
77{
78 if (image.isNull())
79 return nullptr;
80 QQuickTextureFactory *texture = QSGContext::createTextureFactoryFromImage(image);
81 if (texture)
82 return texture;
83 return new QQuickDefaultTextureFactory(image);
84}
85
86
87
88/*!
89 \fn QSGTexture *QQuickTextureFactory::createTexture(QQuickWindow *window) const
90
91 This function is called on the scene graph rendering thread to create a QSGTexture
92 instance from the factory. \a window provides the context which this texture is
93 created in.
94
95 QML will internally cache the returned texture as needed. Each call to this
96 function should return a unique instance.
97
98 The OpenGL context used for rendering is bound when this function is called.
99 */
100
101/*!
102 \fn QSize QQuickTextureFactory::textureSize() const
103
104 Returns the size of the texture. This function will be called from arbitrary threads
105 and should not rely on an OpenGL context bound.
106 */
107
108
109/*!
110 \class QQuickImageResponse
111 \since 5.6
112 \brief The QQuickImageResponse class provides an interface for asynchronous image loading in QQuickAsyncImageProvider.
113 \inmodule QtQuick
114
115 The purpose of an image response is to provide a way for image provider jobs to be executed
116 in an asynchronous way.
117
118 Responses are deleted via \l deleteLater once the finished() signal has been emitted.
119 If you are using QRunnable as base for your QQuickImageResponse
120 ensure automatic deletion is disabled.
121
122 See the \l {imageresponseprovider}{Image Response Provider Example} for a complete implementation.
123
124 \sa QQuickImageProvider
125*/
126
127/*!
128 Constructs the image response
129*/
130QQuickImageResponse::QQuickImageResponse()
131 : QObject(*(new QQuickImageResponsePrivate))
132{
133 qmlobject_connect(this, QQuickImageResponse, SIGNAL(finished()),
134 this, QQuickImageResponse, SLOT(_q_finished()));
135}
136
137/*!
138 Destructs the image response
139*/
140QQuickImageResponse::~QQuickImageResponse()
141{
142}
143
144/*!
145 Returns the error string for the job execution. An empty string means no error.
146*/
147QString QQuickImageResponse::errorString() const
148{
149 return QString();
150}
151
152/*!
153 This method is used to communicate that the response is no longer required by the engine.
154
155 It may be reimplemented to cancel a request in the provider side, however, it is not mandatory.
156
157 A cancelled QQuickImageResponse still needs to emit finished() so that the
158 engine may clean up the QQuickImageResponse.
159
160 \note finished() should not be emitted until the response is complete,
161 regardless of whether or not cancel() was called. If it is called prematurely,
162 the engine may destroy the response while it is still active, leading to a crash.
163*/
164void QQuickImageResponse::cancel()
165{
166}
167
168/*!
169 \fn void QQuickImageResponse::finished()
170
171 Signals that the job execution has finished (be it successfully, because an
172 error happened or because it was cancelled).
173
174 \note Emission of this signal must be the final action the response performs:
175 once the signal is received, the response will subsequently be destroyed by
176 the engine.
177 */
178
179/*!
180 \fn QQuickTextureFactory *QQuickImageResponse::textureFactory() const
181
182 Returns the texture factory for the job. You can use QQuickTextureFactory::textureFactoryForImage
183 if your provider works with QImage. The engine takes ownership of the returned QQuickTextureFactory.
184
185 \note This method will be called only when needed. For example, it may not be called if there is an
186 error or the job is cancelled. Therefore, allocate the QQuickTextureFactory instance only in this
187 method or otherwise ensure its deletion.
188 */
189
190
191/*!
192 \class QQuickImageProvider
193 \since 5.0
194 \inmodule QtQuick
195 \brief The QQuickImageProvider class provides an interface for supporting pixmaps and threaded image requests in QML.
196
197 QQuickImageProvider is used to provide advanced image loading features
198 in QML applications. It allows images in QML to be:
199
200 \list
201 \li Loaded using QPixmaps rather than actual image files
202 \li Loaded asynchronously in a separate thread
203 \endlist
204
205 To specify that an image should be loaded by an image provider, use the
206 \b {"image:"} scheme for the URL source of the image, followed by the
207 identifiers of the image provider and the requested image. For example:
208
209 \qml
210 Image { source: "image://myimageprovider/image.png" }
211 \endqml
212
213 This specifies that the image should be loaded by the image provider named
214 "myimageprovider", and the image to be loaded is named "image.png". The QML engine
215 invokes the appropriate image provider according to the providers that have
216 been registered through QQmlEngine::addImageProvider().
217
218 Note that the identifiers are case-insensitive, but the rest of the URL will be passed on with
219 preserved case. For example, the below snippet would still specify that the image is loaded by the
220 image provider named "myimageprovider", but it would request a different image than the above snippet
221 ("Image.png" instead of "image.png").
222 \qml
223 Image { source: "image://MyImageProvider/Image.png" }
224 \endqml
225
226 If you want the rest of the URL to be case insensitive, you will have to take care
227 of that yourself inside your image provider.
228
229 \section2 An Example
230
231 Here are two images. Their \c source values indicate they should be loaded by
232 an image provider named "colors", and the images to be loaded are "yellow"
233 and "red", respectively:
234
235 \snippet imgprovider/imageprovider-example.qml 0
236
237 When these images are loaded by QML, it looks for a matching image provider
238 and calls its requestImage() or requestPixmap() method (depending on its
239 imageType()) to load the image. The method is called with the \c id
240 parameter set to "yellow" for the first image, and "red" for the second.
241
242 Here is an image provider implementation that can load the images
243 requested by the above QML. This implementation dynamically
244 generates QPixmap images that are filled with the requested color:
245
246 \snippet imgprovider/imageprovider.cpp 0
247
248 To make this provider accessible to QML, it is registered with the QML engine
249 with a "colors" identifier:
250
251 \snippet imgprovider/imageprovider.cpp 1
252 \codeline
253 \snippet imgprovider/imageprovider.cpp 2
254
255 Now the images can be successfully loaded in QML:
256
257 \image imageprovider.png
258
259 See the \l {imageprovider}{Image Provider Example} for the complete implementation.
260 Note that the example registers the provider via a \l{QQmlEngineExtensionPlugin}{plugin}
261 instead of registering it in the application \c main() function as shown above.
262
263 It is possible to provide \l {High Resolution Versions of Images}{"@nx" high DPI syntax}.
264
265
266 \section2 Asynchronous Image Loading
267
268 Image providers that support QImage or Texture loading automatically include support
269 for asychronous loading of images. To enable asynchronous loading for an
270 image source, set the \c asynchronous property to \c true for the relevant
271 \l Image or \l BorderImage object. When this is enabled,
272 the image request to the provider is run in a low priority thread,
273 allowing image loading to be executed in the background, and reducing the
274 performance impact on the user interface.
275
276 To force asynchronous image loading, even for image sources that do not
277 have the \c asynchronous property set to \c true, you may pass the
278 \c QQmlImageProviderBase::ForceAsynchronousImageLoading flag to the image
279 provider constructor. This ensures that all image requests for the
280 provider are handled in a separate thread.
281
282 Asynchronous loading for image providers that provide QPixmap is only supported
283 in platforms that have the ThreadedPixmaps feature, in platforms where
284 pixmaps can only be created in the main thread (i.e. ThreadedPixmaps is not supported)
285 if \l {Image::}{asynchronous} is set to \c true, the value is ignored
286 and the image is loaded synchronously.
287
288 Asynchronous image loading for providers of type other than ImageResponse are
289 executed on a single thread per engine basis. That means that a slow image provider
290 will block the loading of any other request. To avoid that we suggest using QQuickAsyncImageProvider
291 and implement threading on the provider side via a \c QThreadPool or similar.
292 See the \l {imageresponseprovider}{Image Response Provider Example} for a complete implementation.
293
294
295 \section2 Image Caching
296
297 Images returned by a QQuickImageProvider are automatically cached,
298 similar to any image loaded by the QML engine. When an image with a
299 "image://" prefix is loaded from cache, requestImage() and requestPixmap()
300 will not be called for the relevant image provider. If an image should
301 always be fetched from the image provider, and should not be cached at
302 all, set the \c cache property to \c false for the relevant \l Image
303 or \l BorderImage object.
304
305 \sa QQmlEngine::addImageProvider()
306*/
307
308/*!
309 Creates an image provider that will provide images of the given \a type and
310 behave according to the given \a flags.
311*/
312QQuickImageProvider::QQuickImageProvider(ImageType type, Flags flags)
313 : d(new QQuickImageProviderPrivate)
314{
315 d->type = type;
316 d->flags = flags;
317 d->isProviderWithOptions = false;
318}
319
320/*!
321 Destroys the QQuickImageProvider
322
323 \note The destructor of your derived class need to be thread safe.
324*/
325QQuickImageProvider::~QQuickImageProvider()
326{
327 delete d;
328}
329
330/*!
331 Returns the image type supported by this provider.
332*/
333QQuickImageProvider::ImageType QQuickImageProvider::imageType() const
334{
335 return d->type;
336}
337
338/*!
339 Returns the flags set for this provider.
340*/
341QQuickImageProvider::Flags QQuickImageProvider::flags() const
342{
343 return d->flags;
344}
345
346/*!
347 Implement this method to return the image with \a id. The default
348 implementation returns an empty image.
349
350 The \a id is the requested image source, with the "image:" scheme and
351 provider identifier removed. For example, if the image \l{Image::}{source}
352 was "image://myprovider/icons/home", the given \a id would be "icons/home".
353
354 The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
355 an Image item. If \a requestedSize is a valid size, the image
356 returned should be of that size.
357
358 In all cases, \a size must be set to the original size of the image. This
359 is used to set the \l {Item::}{width} and \l {Item::}{height} of the
360 relevant \l Image if these values have not been set explicitly.
361
362 \note this method may be called by multiple threads, so ensure the
363 implementation of this method is reentrant.
364*/
365QImage QQuickImageProvider::requestImage(const QString &id, QSize *size, const QSize& requestedSize)
366{
367 Q_UNUSED(id);
368 Q_UNUSED(size);
369 Q_UNUSED(requestedSize);
370 if (d->type == Image)
371 qWarning("ImageProvider supports Image type but has not implemented requestImage()");
372 return QImage();
373}
374
375/*!
376 Implement this method to return the pixmap with \a id. The default
377 implementation returns an empty pixmap.
378
379 The \a id is the requested image source, with the "image:" scheme and
380 provider identifier removed. For example, if the image \l{Image::}{source}
381 was "image://myprovider/icons/home", the given \a id would be "icons/home".
382
383 The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
384 an Image item. If \a requestedSize is a valid size, the image
385 returned should be of that size.
386
387 In all cases, \a size must be set to the original size of the image. This
388 is used to set the \l {Item::}{width} and \l {Item::}{height} of the
389 relevant \l Image if these values have not been set explicitly.
390
391 \note this method may be called by multiple threads, so ensure the
392 implementation of this method is reentrant.
393*/
394QPixmap QQuickImageProvider::requestPixmap(const QString &id, QSize *size, const QSize& requestedSize)
395{
396 Q_UNUSED(id);
397 Q_UNUSED(size);
398 Q_UNUSED(requestedSize);
399 if (d->type == Pixmap)
400 qWarning("ImageProvider supports Pixmap type but has not implemented requestPixmap()");
401 return QPixmap();
402}
403
404
405/*!
406 Implement this method to return the texture with \a id. The default
407 implementation returns \nullptr.
408
409 The \a id is the requested image source, with the "image:" scheme and
410 provider identifier removed. For example, if the image \l{Image::}{source}
411 was "image://myprovider/icons/home", the given \a id would be "icons/home".
412
413 The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
414 an Image item. If \a requestedSize is a valid size, the image
415 returned should be of that size.
416
417 In all cases, \a size must be set to the original size of the image. This
418 is used to set the \l {Item::}{width} and \l {Item::}{height} of the
419 relevant \l Image if these values have not been set explicitly.
420
421 \note this method may be called by multiple threads, so ensure the
422 implementation of this method is reentrant.
423*/
424
425QQuickTextureFactory *QQuickImageProvider::requestTexture(const QString &id, QSize *size, const QSize &requestedSize)
426{
427 Q_UNUSED(id);
428 Q_UNUSED(size);
429 Q_UNUSED(requestedSize);
430 if (d->type == Texture)
431 qWarning("ImageProvider supports Texture type but has not implemented requestTexture()");
432 return nullptr;
433}
434
435/*!
436 \class QQuickAsyncImageProvider
437 \since 5.6
438 \inmodule QtQuick
439 \brief The QQuickAsyncImageProvider class provides an interface for asynchronous control of QML image requests.
440
441 See the \l {imageresponseprovider}{Image Response Provider Example} for a complete implementation.
442
443 \sa QQuickImageProvider
444*/
445QQuickAsyncImageProvider::QQuickAsyncImageProvider()
446 : QQuickImageProvider(ImageResponse, ForceAsynchronousImageLoading)
447 , d(nullptr) // just as a placeholder in case we need it for the future
448{
449 Q_UNUSED(d);
450}
451
452QQuickAsyncImageProvider::~QQuickAsyncImageProvider()
453{
454}
455
456/*!
457 \fn QQuickImageResponse *QQuickAsyncImageProvider::requestImageResponse(const QString &id, const QSize &requestedSize)
458
459 Implement this method to return the job that will provide the texture with \a id.
460
461 The \a id is the requested image source, with the "image:" scheme and
462 provider identifier removed. For example, if the image \l{Image::}{source}
463 was "image://myprovider/icons/home", the given \a id would be "icons/home".
464
465 The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
466 an Image item. If \a requestedSize is a valid size, the image
467 returned should be of that size.
468
469 \note this method may be called by multiple threads, so ensure the
470 implementation of this method is reentrant.
471*/
472
473
487
488/*!
489 \class QQuickImageProviderOptions
490 \brief The QQuickImageProviderOptions class provides options for QQuickImageProviderWithOptions image requests.
491 \inmodule QtQuick
492 \internal
493
494 \sa QQuickImageProviderWithOptions
495*/
496
497/*!
498 \enum QQuickImageProviderOptions::AutoTransform
499
500 Whether the image provider should apply transformation metadata on read().
501
502 \value UsePluginDefaultTransform Image provider should do its default behavior on whether applying transformation metadata on read or not
503 \value ApplyTransform Image provider should apply transformation metadata on read
504 \value DoNotApplyTransform Image provider should not apply transformation metadata on read
505*/
506
507QQuickImageProviderOptions::QQuickImageProviderOptions()
508 : d(new QQuickImageProviderOptionsPrivate())
509{
510}
511
512QQuickImageProviderOptions::~QQuickImageProviderOptions()
513{
514}
515
516QQuickImageProviderOptions::QQuickImageProviderOptions(const QQuickImageProviderOptions &other)
517 : d(other.d)
518{
519}
520
521QQuickImageProviderOptions& QQuickImageProviderOptions::operator=(const QQuickImageProviderOptions &other)
522{
523 d = other.d;
524 return *this;
525}
526
527bool QQuickImageProviderOptions::operator==(const QQuickImageProviderOptions &other) const
528{
529 return d->autoTransform == other.d->autoTransform &&
530 d->preserveAspectRatioCrop == other.d->preserveAspectRatioCrop &&
531 d->preserveAspectRatioFit == other.d->preserveAspectRatioFit &&
532 d->targetColorSpace == other.d->targetColorSpace;
533}
534
535/*!
536 Returns whether the image provider should apply transformation metadata on read().
537*/
538QQuickImageProviderOptions::AutoTransform QQuickImageProviderOptions::autoTransform() const
539{
540 return d->autoTransform;
541}
542
543void QQuickImageProviderOptions::setAutoTransform(QQuickImageProviderOptions::AutoTransform autoTransform)
544{
545 d->autoTransform = autoTransform;
546}
547
548/*!
549 Returns whether the image request is for a PreserveAspectCrop Image.
550 This allows the provider to better optimize the size of the returned image.
551*/
552bool QQuickImageProviderOptions::preserveAspectRatioCrop() const
553{
554 return d->preserveAspectRatioCrop;
555}
556
557void QQuickImageProviderOptions::setPreserveAspectRatioCrop(bool preserveAspectRatioCrop)
558{
559 d->preserveAspectRatioCrop = preserveAspectRatioCrop;
560}
561
562/*!
563 Returns whether the image request is for a PreserveAspectFit Image.
564 This allows the provider to better optimize the size of the returned image.
565*/
566bool QQuickImageProviderOptions::preserveAspectRatioFit() const
567{
568 return d->preserveAspectRatioFit;
569}
570
571void QQuickImageProviderOptions::setPreserveAspectRatioFit(bool preserveAspectRatioFit)
572{
573 d->preserveAspectRatioFit = preserveAspectRatioFit;
574}
575
576/*!
577 Returns the color space the image provider should return the image in.
578*/
579QColorSpace QQuickImageProviderOptions::targetColorSpace() const
580{
581 return d->targetColorSpace;
582}
583
584void QQuickImageProviderOptions::setTargetColorSpace(const QColorSpace &colorSpace)
585{
586 d->targetColorSpace = colorSpace;
587}
588
589/*!
590 Returns the requested source clip rect.
591*/
592QRectF QQuickImageProviderOptions::sourceClipRect() const
593{
594 return d->sourceClipRect;
595}
596
597void QQuickImageProviderOptions::setSourceClipRect(const QRectF &rect)
598{
599 d->sourceClipRect = rect;
600}
601
602QQuickImageProviderWithOptions::QQuickImageProviderWithOptions(ImageType type, Flags flags)
603 : QQuickAsyncImageProvider()
604{
605 QQuickImageProvider::d->type = type;
606 QQuickImageProvider::d->flags = flags;
607 QQuickImageProvider::d->isProviderWithOptions = true;
608}
609
610QImage QQuickImageProviderWithOptions::requestImage(const QString &id, QSize *size, const QSize& requestedSize)
611{
612 return requestImage(id, size, requestedSize, QQuickImageProviderOptions());
613}
614
615QPixmap QQuickImageProviderWithOptions::requestPixmap(const QString &id, QSize *size, const QSize& requestedSize)
616{
617 return requestPixmap(id, size, requestedSize, QQuickImageProviderOptions());
618}
619
620QQuickTextureFactory *QQuickImageProviderWithOptions::requestTexture(const QString &id, QSize *size, const QSize &requestedSize)
621{
622 return requestTexture(id, size, requestedSize, QQuickImageProviderOptions());
623}
624
625QImage QQuickImageProviderWithOptions::requestImage(const QString &id, QSize *size, const QSize& requestedSize, const QQuickImageProviderOptions &options)
626{
627 Q_UNUSED(options);
628 return QQuickAsyncImageProvider::requestImage(id, size, requestedSize);
629}
630
631QPixmap QQuickImageProviderWithOptions::requestPixmap(const QString &id, QSize *size, const QSize& requestedSize, const QQuickImageProviderOptions &options)
632{
633 Q_UNUSED(options);
634 return QQuickAsyncImageProvider::requestPixmap(id, size, requestedSize);
635}
636
637QQuickTextureFactory *QQuickImageProviderWithOptions::requestTexture(const QString &id, QSize *size, const QSize &requestedSize, const QQuickImageProviderOptions &options)
638{
639 Q_UNUSED(options);
640 return QQuickAsyncImageProvider::requestTexture(id, size, requestedSize);
641}
642
643QQuickImageResponse *QQuickImageProviderWithOptions::requestImageResponse(const QString &id, const QSize &requestedSize)
644{
645 Q_UNUSED(id);
646 Q_UNUSED(requestedSize);
647 if (imageType() == ImageResponse)
648 qWarning("ImageProvider is of ImageResponse type but has not implemented requestImageResponse()");
649 return nullptr;
650}
651
652QQuickImageResponse *QQuickImageProviderWithOptions::requestImageResponse(const QString &id, const QSize &requestedSize, const QQuickImageProviderOptions &options)
653{
654 Q_UNUSED(options);
655 return requestImageResponse(id, requestedSize);
656}
657
658/*!
659 Returns the recommended scaled image size for loading and storage. This is
660 calculated according to the native pixel size of the image \a originalSize,
661 the requested sourceSize \a requestedSize, the image file format \a format,
662 and \a options. If the calculation otherwise concludes that scaled loading
663 is not recommended, an invalid size is returned.
664*/
665QSize QQuickImageProviderWithOptions::loadSize(const QSize &originalSize, const QSize &requestedSize, const QByteArray &format, const QQuickImageProviderOptions &options,
666 qreal devicePixelRatio)
667{
668 QSize res;
669 const bool formatIsScalable = (format == "svg" || format == "svgz" || format == "pdf");
670 const bool noRequestedSize = requestedSize.width() <= 0 && requestedSize.height() <= 0;
671 if ((noRequestedSize && !formatIsScalable) || originalSize.isEmpty())
672 return res;
673
674 // If no sourceSize was set and we're loading an SVG, ensure that we provide
675 // a default size that accounts for DPR so that the image isn't blurry.
676 if (noRequestedSize && formatIsScalable)
677 return originalSize * devicePixelRatio;
678
679 const bool preserveAspectCropOrFit = options.preserveAspectRatioCrop() || options.preserveAspectRatioFit();
680
681 if (!preserveAspectCropOrFit && formatIsScalable && !requestedSize.isEmpty())
682 return requestedSize;
683
684 qreal ratio = 0.0;
685 if (requestedSize.width() && (preserveAspectCropOrFit || formatIsScalable ||
686 requestedSize.width() < originalSize.width())) {
687 ratio = qreal(requestedSize.width()) / originalSize.width();
688 }
689 if (requestedSize.height() && (preserveAspectCropOrFit || formatIsScalable ||
690 requestedSize.height() < originalSize.height())) {
691 qreal hr = qreal(requestedSize.height()) / originalSize.height();
692 if (ratio == 0.0)
693 ratio = hr;
694 else if (!preserveAspectCropOrFit && (hr < ratio))
695 ratio = hr;
696 else if (preserveAspectCropOrFit && (hr > ratio))
697 ratio = hr;
698 }
699 if (ratio > 0.0) {
700 res.setHeight(qRound(originalSize.height() * ratio));
701 res.setWidth(qRound(originalSize.width() * ratio));
702 }
703 return res;
704}
705
706QQuickImageProviderWithOptions *QQuickImageProviderWithOptions::checkedCast(QQuickImageProvider *provider)
707{
708 if (provider && provider->d && provider->d->isProviderWithOptions)
709 return static_cast<QQuickImageProviderWithOptions *>(provider);
710
711 return nullptr;
712}
713
714QT_END_NAMESPACE
715
716#include "moc_qquickimageprovider.cpp"
QQuickImageProviderOptions::AutoTransform autoTransform