File indexing completed on 2024-05-12 16:01:48

0001 /*
0002  *  SPDX-FileCopyrightText: 2018 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #ifndef KISFRAMEDATASERIALIZER_H
0007 #define KISFRAMEDATASERIALIZER_H
0008 
0009 #include "kritaui_export.h"
0010 #include <QScopedPointer>
0011 #include "opengl/kis_texture_tile_info_pool.h"
0012 
0013 // TODO: extract DataBuffer into a separate file
0014 #include "opengl/kis_texture_tile_update_info.h"
0015 
0016 #include <vector>
0017 #include <boost/optional.hpp>
0018 
0019 class QString;
0020 
0021 
0022 /**
0023  * KisFrameDataSerializer is the lowest level class for storing frame
0024  * data on disk. Its responsibilities are simple:
0025  *
0026  * 1) Accept low-level frame data object (KisFrameDataSerializer::Frame),
0027  *    which contains raw data in it (the data may be not a pixel data,
0028  *    but a preprocessed pixel differences)
0029  *
0030  * 2) Compress this data and save it on disk
0031  */
0032 
0033 class KRITAUI_EXPORT KisFrameDataSerializer
0034 {
0035 public:
0036     struct FrameTile
0037     {
0038         FrameTile(KisTextureTileInfoPoolSP pool) : data(pool) {}
0039 
0040         FrameTile(FrameTile &&rhs) = default;
0041         FrameTile& operator=(FrameTile &&rhs) = default;
0042 
0043         FrameTile(const FrameTile &rhs) = delete;
0044         FrameTile& operator=(FrameTile &rhs) = delete;
0045 
0046         bool isValid() const {
0047             return data.data();
0048         }
0049 
0050         FrameTile clone() const{
0051             FrameTile tile(data.pool());
0052             tile.col = col;
0053             tile.row = row;
0054             tile.rect = rect;
0055             tile.data.allocate(data.pixelSize());
0056 
0057             const int bufferSize = data.pixelSize() * rect.width() * rect.height();
0058             memcpy(tile.data.data(), data.data(), bufferSize);
0059 
0060             return tile;
0061         }
0062 
0063         int col = -1;
0064         int row = -1;
0065         bool isCompressed = false;
0066         QRect rect;
0067         DataBuffer data;
0068     };
0069 
0070     struct Frame
0071     {
0072         Frame() = default;
0073 
0074         Frame(Frame&&rhs) = default;
0075         Frame& operator=(Frame &&rhs) = default;
0076 
0077         Frame(const Frame &rhs) = delete;
0078         Frame& operator=(Frame &rhs) = delete;
0079 
0080         Frame clone() const {
0081             Frame frame;
0082             frame.pixelSize = pixelSize;
0083             for (auto it = frameTiles.begin(); it != frameTiles.end(); ++it) {
0084                 frame.frameTiles.push_back(it->clone());
0085             }
0086             return frame;
0087         }
0088 
0089         int pixelSize = 0;
0090         std::vector<FrameTile> frameTiles;
0091 
0092         bool isValid() const {
0093             return pixelSize > 0;
0094         }
0095     };
0096 
0097 public:
0098     KisFrameDataSerializer();
0099     KisFrameDataSerializer(const QString &frameCachePath);
0100     ~KisFrameDataSerializer();
0101 
0102     int saveFrame(const Frame &frame);
0103     Frame loadFrame(int frameId, KisTextureTileInfoPoolSP pool);
0104 
0105     void moveFrame(int srcFrameId, int dstFrameId);
0106 
0107     bool hasFrame(int frameId) const;
0108     void forgetFrame(int frameId);
0109 
0110     static boost::optional<qreal> estimateFrameUniqueness(const Frame &lhs, const Frame &rhs, qreal portion);
0111     static bool subtractFrames(Frame &dst, const Frame &src);
0112     static void addFrames(Frame &dst, const Frame &src);
0113 
0114 private:
0115     template<template <typename U> class OpPolicy>
0116     static bool processFrames(KisFrameDataSerializer::Frame &dst, const KisFrameDataSerializer::Frame &src);
0117 
0118 private:
0119     Q_DISABLE_COPY(KisFrameDataSerializer)
0120 
0121     struct Private;
0122     const QScopedPointer<Private> m_d;
0123 };
0124 
0125 #endif // KISFRAMEDATASERIALIZER_H