23#include <klocalizedstring.h>
67#define DEFAULT_SPACING 0.25
77 const QByteArray& data,
84 d->
data = QByteArray::fromRawData(data.data() + dataPos, data.size() - dataPos);
112 d->
data = QByteArray();
127 Q_UNUSED(resourcesInterface);
128 d->
data = dev->readAll();
137 qWarning() <<
filename() <<
"GBR could not be loaded: expected header size larger than bytearray size. Header Size:" <<
sizeof(
GimpBrushHeader) <<
"Byte array size" <<
d->
data.size();
165 qWarning() <<
filename() <<
"GBR could not be loaded, spacing above 1000. Spacing:" << bh.
spacing;
173 qWarning() <<
"GBR could not be loaded: header size larger than bytearray size. Header Size:" << bh.
header_size <<
"Byte array size" <<
d->
data.size();
195 qWarning() <<
filename() <<
"GBR loading failed: width or height is 0" << bh.
width << bh.
height;
199 QImage::Format imageFormat;
202 imageFormat = QImage::Format_Indexed8;
204 imageFormat = QImage::Format_ARGB32;
209 if (
image.isNull()) {
210 qWarning() <<
filename() <<
"GBR loading failed; image could not be created from following dimensions" << bh.
width << bh.
height
211 <<
"QImage::Format" << imageFormat;
219 for (
int i = 0; i < 256; ++i) table.append(qRgb(i, i, i));
220 image.setColorTable(table);
224 qWarning() <<
filename() <<
"GBR file dimensions bigger than bytearray size. Header:"<< k <<
"Width:" << bh.
width <<
"height" << bh.
height
225 <<
"expected byte array size:" << (k + (bh.
width * bh.
height)) <<
"actual byte array size" <<
d->
data.size();
233 for (quint32 y = 0; y < bh.
height; y++) {
234 uchar *pixel =
reinterpret_cast<uchar *
>(
image.scanLine(y));
235 for (quint32 x = 0; x < bh.
width; x++, k++) {
236 qint32 val = 255 -
static_cast<uchar
>(
d->
data.at(k));
241 }
else if (bh.
bytes == 4) {
245 qWarning() <<
filename() <<
"GBR file dimensions bigger than bytearray size. Header:"<< k <<
"Width:" << bh.
width <<
"height" << bh.
height
246 <<
"expected byte array size:" << (k + (bh.
width * bh.
height * 4)) <<
"actual byte array size" <<
d->
data.size();
253 for (quint32 y = 0; y < bh.
height; y++) {
255 for (quint32 x = 0; x < bh.
width; x++, k += 4) {
264 warnKrita <<
filename() <<
"WARNING: loading of GBR brushes with" << bh.
bytes <<
"bytes per pixel is not supported";
270 if (!
d->
data.isEmpty()) {
294 qWarning() <<
"this brush is not valid, set a brush tip image" <<
filename();
298 QByteArray utf8Name =
name().toUtf8();
299 char const*
name = utf8Name.data();
300 int nameLength = qstrlen(
name);
304 bh.
version = qToBigEndian((quint32)2);
309 bh.
bytes = qToBigEndian((quint32)1);
312 bh.
bytes = qToBigEndian((quint32)4);
315 bh.
spacing = qToBigEndian(
static_cast<quint32
>(
spacing() * 100.0));
318 QByteArray bytes = QByteArray::fromRawData(
reinterpret_cast<char*
>(&bh),
sizeof(
GimpBrushHeader));
319 wrote = dev->write(bytes);
326 wrote = dev->write(
name, nameLength + 1);
338 for (qint32 y = 0; y <
height(); y++) {
339 for (qint32 x = 0; x <
width(); x++) {
341 bytes[k++] =
static_cast<char>(255 - qRed(c));
346 for (qint32 y = 0; y <
height(); y++) {
347 for (qint32 x = 0; x <
width(); x++) {
350 bytes[k++] =
static_cast<char>(qRed(pixel));
351 bytes[k++] =
static_cast<char>(qGreen(pixel));
352 bytes[k++] =
static_cast<char>(qBlue(pixel));
353 bytes[k++] =
static_cast<char>(qAlpha(pixel));
358 wrote = dev->write(bytes);
379 if (!preserveAlpha) {
380 const int imageWidth = brushTip.width();
381 const int imageHeight = brushTip.height();
382 QImage
image(imageWidth, imageHeight, QImage::Format_Indexed8);
384 for (
int i = 0; i < 256; ++i) {
385 table.append(qRgb(i, i, i));
387 image.setColorTable(table);
389 for (
int y = 0; y < imageHeight; y++) {
390 QRgb *pixel =
reinterpret_cast<QRgb *
>(brushTip.scanLine(y));
391 uchar * dstPixel =
image.scanLine(y);
392 for (
int x = 0; x < imageWidth; x++) {
394 float alpha = qAlpha(c) / 255.0f;
398 int a = 255 + int(alpha * (qGray(c) - 255));
399 dstPixel[x] = (uchar)a;
423 return QString(
".gbr");
virtual void setSpacing(double spacing)
virtual void setBrushType(enumBrushType type)
void predefinedBrushToXML(const QString &type, QDomElement &e) const
virtual void setBrushTipImage(const QImage &image)
void setWidth(qint32 width)
void setHeight(qint32 height)
virtual void setBrushApplication(enumBrushApplication brushApplication)
virtual bool isImageType() const
QImage brushTipImage() const override
brushImage the image the brush tip can paint with. Not all brush types have a single image.
void setHasColorAndTransparency(bool value)
void toXML(QDomDocument &d, QDomElement &e) const override
void setBrushTipImage(const QImage &image) override
bool initFromPaintDev(KisPaintDeviceSP image, int x, int y, int w, int h)
bool saveToDevice(QIODevice *dev) const override
bool loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP resourcesInterface) override
QString defaultFileExtension() const override
KoResourceSP clone() const override
void toXML(QDomDocument &d, QDomElement &e) const override
virtual void makeMaskImage(bool preserveAlpha)
KisGbrBrush(const QString &filename)
Construct brush to load filename later as brush.
quint32 const GimpV2BrushMagic
QSharedPointer< KoResource > KoResourceSP
void setValid(bool valid)
void setName(const QString &name)