1 /*
2  *  Copyright (c) 2018 Dmitry Kazakov <dimula73@gmail.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 #ifndef KISFRAMEDATASERIALIZER_H
19 #define KISFRAMEDATASERIALIZER_H
20 
21 #include "kritaui_export.h"
22 #include <QScopedPointer>
23 #include "opengl/kis_texture_tile_info_pool.h"
24 
25 // TODO: extract DataBuffer into a separate file
26 #include "opengl/kis_texture_tile_update_info.h"
27 
28 #include <vector>
29 #include <boost/optional.hpp>
30 
31 class QString;
32 
33 
34 /**
35  * KisFrameDataSerializer is the lowest level class for storing frame
36  * data on disk. Its responsibilities are simple:
37  *
38  * 1) Accept low-level frame data object (KisFrameDataSerializer::Frame),
39  *    which contains raw data in it (the data may be not a pixel data,
40  *    but a preprocessed pixel differences)
41  *
42  * 2) Compress this data and save it on disk
43  */
44 
45 class KRITAUI_EXPORT KisFrameDataSerializer
46 {
47 public:
48     struct FrameTile
49     {
FrameTileFrameTile50         FrameTile(KisTextureTileInfoPoolSP pool) : data(pool) {}
51 
52         FrameTile(FrameTile &&rhs) = default;
53         FrameTile& operator=(FrameTile &&rhs) = default;
54 
55         FrameTile(const FrameTile &rhs) = delete;
56         FrameTile& operator=(FrameTile &rhs) = delete;
57 
isValidFrameTile58         bool isValid() const {
59             return data.data();
60         }
61 
cloneFrameTile62         FrameTile clone() const{
63             FrameTile tile(data.pool());
64             tile.col = col;
65             tile.row = row;
66             tile.rect = rect;
67             tile.data.allocate(data.pixelSize());
68 
69             const int bufferSize = data.pixelSize() * rect.width() * rect.height();
70             memcpy(tile.data.data(), data.data(), bufferSize);
71 
72             return tile;
73         }
74 
75         int col = -1;
76         int row = -1;
77         bool isCompressed = false;
78         QRect rect;
79         DataBuffer data;
80     };
81 
82     struct Frame
83     {
84         Frame() = default;
85 
86         Frame(Frame&&rhs) = default;
87         Frame& operator=(Frame &&rhs) = default;
88 
89         Frame(const Frame &rhs) = delete;
90         Frame& operator=(Frame &rhs) = delete;
91 
cloneFrame92         Frame clone() const {
93             Frame frame;
94             frame.pixelSize = pixelSize;
95             for (auto it = frameTiles.begin(); it != frameTiles.end(); ++it) {
96                 frame.frameTiles.push_back(it->clone());
97             }
98             return frame;
99         }
100 
101         int pixelSize = 0;
102         std::vector<FrameTile> frameTiles;
103 
isValidFrame104         bool isValid() const {
105             return pixelSize > 0;
106         }
107     };
108 
109 public:
110     KisFrameDataSerializer();
111     KisFrameDataSerializer(const QString &frameCachePath);
112     ~KisFrameDataSerializer();
113 
114     int saveFrame(const Frame &frame);
115     Frame loadFrame(int frameId, KisTextureTileInfoPoolSP pool);
116 
117     void moveFrame(int srcFrameId, int dstFrameId);
118 
119     bool hasFrame(int frameId) const;
120     void forgetFrame(int frameId);
121 
122     static boost::optional<qreal> estimateFrameUniqueness(const Frame &lhs, const Frame &rhs, qreal portion);
123     static bool subtractFrames(Frame &dst, const Frame &src);
124     static void addFrames(Frame &dst, const Frame &src);
125 
126 private:
127     template<template <typename U> class OpPolicy>
128     static bool processFrames(KisFrameDataSerializer::Frame &dst, const KisFrameDataSerializer::Frame &src);
129 
130 private:
131     Q_DISABLE_COPY(KisFrameDataSerializer)
132 
133     struct Private;
134     const QScopedPointer<Private> m_d;
135 };
136 
137 #endif // KISFRAMEDATASERIALIZER_H
138