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