File indexing completed on 2025-01-05 03:55:18

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2005-06-14
0007  * Description : digiKam 8/16 bits image management API.
0008  *               Data management.
0009  *
0010  * SPDX-FileCopyrightText: 2005-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0011  * SPDX-FileCopyrightText: 2006-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #include "dimg_p.h"
0018 
0019 namespace Digikam
0020 {
0021 
0022 DImg& DImg::operator=(const DImg& image)
0023 {
0024     m_priv = image.m_priv;
0025 
0026     return *this;
0027 }
0028 
0029 bool DImg::operator==(const DImg& image) const
0030 {
0031     return (m_priv == image.m_priv);
0032 }
0033 
0034 void DImg::reset()
0035 {
0036     m_priv = new Private;
0037 }
0038 
0039 void DImg::detach()
0040 {
0041     // are we being shared?
0042 
0043     if (m_priv->ref == 1)
0044     {
0045         return;
0046     }
0047 
0048     QExplicitlySharedDataPointer<Private> old(m_priv);
0049 
0050     m_priv = new Private;
0051     copyImageData(old);
0052     copyMetaData(old);
0053 
0054     if (old->data)
0055     {
0056         size_t size = allocateData();
0057         memcpy(m_priv->data, old->data, size);
0058     }
0059 }
0060 
0061 void DImg::putImageData(uint width, uint height, bool sixteenBit, bool alpha, uchar* const data, bool copyData)
0062 {
0063     // set image data, metadata is untouched
0064 
0065     bool null = (width == 0) || (height == 0);
0066 
0067     // allocateData, or code below will set null to false
0068 
0069     setImageData(true, width, height, sixteenBit, alpha);
0070 
0071     // replace data
0072 
0073     delete [] m_priv->data;
0074     m_priv->data = nullptr;
0075 
0076     if (null)
0077     {
0078         // image is null - no data
0079 
0080         return;
0081     }
0082     else if (copyData)
0083     {
0084         size_t size = allocateData();
0085 
0086         if (m_priv->data && data)
0087         {
0088             memcpy(m_priv->data, data, size);
0089         }
0090     }
0091     else
0092     {
0093         if (data)
0094         {
0095             m_priv->data = data;
0096             m_priv->null = false;
0097         }
0098         else
0099         {
0100             allocateData();
0101         }
0102     }
0103 }
0104 
0105 void DImg::putImageData(uchar* const data, bool copyData)
0106 {
0107     if (!data)
0108     {
0109         delete [] m_priv->data;
0110         m_priv->data = nullptr;
0111         m_priv->null = true;
0112     }
0113     else if (copyData)
0114     {
0115         memcpy(m_priv->data, data, numBytes());
0116     }
0117     else
0118     {
0119         m_priv->data = data;
0120     }
0121 }
0122 
0123 void DImg::resetMetaData()
0124 {
0125     m_priv->attributes.clear();
0126     m_priv->embeddedText.clear();
0127     m_priv->metaData = MetaEngineData();
0128 }
0129 
0130 uchar* DImg::stripImageData()
0131 {
0132     uchar* const data  = m_priv->data;
0133     m_priv->data       = nullptr;
0134     m_priv->null       = true;
0135 
0136     return data;
0137 }
0138 
0139 void DImg::copyMetaData(const QExplicitlySharedDataPointer<Private>& src)
0140 {
0141     m_priv->metaData     = src->metaData;
0142     m_priv->attributes   = src->attributes;
0143     m_priv->embeddedText = src->embeddedText;
0144     m_priv->iccProfile   = src->iccProfile;
0145     m_priv->imageHistory = src->imageHistory;
0146 
0147     // FIXME: what about sharing and deleting lanczos_func?
0148 }
0149 
0150 void DImg::copyImageData(const QExplicitlySharedDataPointer<Private>& src)
0151 {
0152     setImageData(src->null, src->width, src->height, src->sixteenBit, src->alpha);
0153 }
0154 
0155 size_t DImg::allocateData() const
0156 {
0157     quint64 size = (quint64)m_priv->width  *
0158                     (quint64)m_priv->height *
0159                     (quint64)(m_priv->sixteenBit ? 8 : 4);
0160 
0161     if (size >= std::numeric_limits<size_t>::max())
0162     {
0163         m_priv->null = true;
0164 
0165         return 0;
0166     }
0167 
0168     m_priv->data = DImgLoader::new_failureTolerant(size);
0169 
0170     if (!m_priv->data)
0171     {
0172         m_priv->null = true;
0173 
0174         return 0;
0175     }
0176 
0177     m_priv->null = false;
0178 
0179     return size;
0180 }
0181 
0182 void DImg::setImageDimension(uint width, uint height)
0183 {
0184     m_priv->width  = width;
0185     m_priv->height = height;
0186 }
0187 
0188 void DImg::setImageData(bool null, uint width, uint height, bool sixteenBit, bool alpha)
0189 {
0190     m_priv->null       = null;
0191     m_priv->width      = width;
0192     m_priv->height     = height;
0193     m_priv->alpha      = alpha;
0194     m_priv->sixteenBit = sixteenBit;
0195 }
0196 
0197 } // namespace Digikam