Krita Source Code Documentation
Loading...
Searching...
No Matches
KisAbrBrushCollection Class Reference

#include <kis_abr_brush_collection.h>

Public Member Functions

KisAbrBrushSP brushByName (QString name) const
 
QList< KisAbrBrushSPbrushes () const
 
QSharedPointer< QMap< QString, KisAbrBrushSP > > brushesMap () const
 
QString defaultFileExtension () const
 
QString filename () const
 
QImage image () const
 
bool isLoaded () const
 
 KisAbrBrushCollection (const QString &filename)
 Construct brush to load filename later as brush.
 
QDateTime lastModified () const
 
bool load ()
 
bool loadFromDevice (QIODevice *dev)
 
bool save ()
 
bool saveToDevice (QIODevice *dev) const
 
 ~KisAbrBrushCollection ()
 

Protected Member Functions

 KisAbrBrushCollection (const KisAbrBrushCollection &rhs)
 
void toXML (QDomDocument &d, QDomElement &e) const
 

Private Member Functions

qint32 abr_brush_load (QDataStream &abr, AbrInfo *abr_hdr, const QString filename, qint32 image_ID, qint32 id)
 
qint32 abr_brush_load_v12 (QDataStream &abr, AbrInfo *abr_hdr, const QString filename, qint32 image_ID, qint32 id)
 
quint32 abr_brush_load_v6 (QDataStream &abr, AbrInfo *abr_hdr, const QString filename, qint32 image_ID, qint32 id)
 

Private Attributes

QSharedPointer< QMap< QString, KisAbrBrushSP > > m_abrBrushes
 
QString m_filename
 
bool m_isLoaded
 
QDateTime m_lastModified
 

Detailed Description

load a collection of brushes from an abr file

Definition at line 32 of file kis_abr_brush_collection.h.

Constructor & Destructor Documentation

◆ KisAbrBrushCollection() [1/2]

KisAbrBrushCollection::KisAbrBrushCollection ( const QString & filename)

Construct brush to load filename later as brush.

Definition at line 522 of file kis_abr_brush_collection.cpp.

523 : m_isLoaded(false)
526 , m_abrBrushes(new QMap<QString, KisAbrBrushSP>())
527{
528}
QSharedPointer< QMap< QString, KisAbrBrushSP > > m_abrBrushes

◆ ~KisAbrBrushCollection()

KisAbrBrushCollection::~KisAbrBrushCollection ( )
inline

Definition at line 42 of file kis_abr_brush_collection.h.

42{}

◆ KisAbrBrushCollection() [2/2]

KisAbrBrushCollection::KisAbrBrushCollection ( const KisAbrBrushCollection & rhs)
protected

Definition at line 530 of file kis_abr_brush_collection.cpp.

533{
534 m_abrBrushes.reset(new QMap<QString, KisAbrBrushSP>());
535 for (auto it = rhs.m_abrBrushes->begin();
536 it != rhs.m_abrBrushes->end();
537 ++it) {
538
539 m_abrBrushes->insert(it.key(), KisAbrBrushSP(new KisAbrBrush(*it.value(), this)));
540 }
541}
QSharedPointer< KisAbrBrush > KisAbrBrushSP

References m_abrBrushes.

Member Function Documentation

◆ abr_brush_load()

qint32 KisAbrBrushCollection::abr_brush_load ( QDataStream & abr,
AbrInfo * abr_hdr,
const QString filename,
qint32 image_ID,
qint32 id )
private

Definition at line 503 of file kis_abr_brush_collection.cpp.

504{
505 qint32 layer_ID = -1;
506 switch (abr_hdr->version) {
507 case 1:
508 Q_FALLTHROUGH();
509 // fall through, version 1 and 2 are compatible
510 case 2:
511 layer_ID = abr_brush_load_v12(abr, abr_hdr, filename, image_ID, id);
512 break;
513 case 6:
514 layer_ID = abr_brush_load_v6(abr, abr_hdr, filename, image_ID, id);
515 break;
516 }
517
518 return layer_ID;
519}
quint32 abr_brush_load_v6(QDataStream &abr, AbrInfo *abr_hdr, const QString filename, qint32 image_ID, qint32 id)
qint32 abr_brush_load_v12(QDataStream &abr, AbrInfo *abr_hdr, const QString filename, qint32 image_ID, qint32 id)

References abr_brush_load_v12(), abr_brush_load_v6(), filename(), and AbrInfo::version.

◆ abr_brush_load_v12()

qint32 KisAbrBrushCollection::abr_brush_load_v12 ( QDataStream & abr,
AbrInfo * abr_hdr,
const QString filename,
qint32 image_ID,
qint32 id )
private

Definition at line 399 of file kis_abr_brush_collection.cpp.

400{
401 Q_UNUSED(image_ID);
402 short brush_type;
403 qint32 brush_size;
404 qint32 next_brush;
405
406 qint32 top, left, bottom, right;
407 qint16 depth;
408 char compression;
409 QString name;
410
411 qint32 width, height;
412 qint32 size;
413
414 qint32 layer_ID = -1;
415 char *buffer;
416
417 // short
418 abr >> brush_type;
419 // long
420 abr >> brush_size;
421 next_brush = abr.device()->pos() + brush_size;
422
423 if (brush_type == 1) {
424 // computed brush
425 // FIXME: support it!
426 warnKrita << "WARNING: computed brush unsupported, skipping.";
427 abr.device()->seek(abr.device()->pos() + next_brush);
428 // TODO: test also this one abr.skipRawData(next_brush);
429 }
430 else if (brush_type == 2) {
431 // sampled brush
432 // discard 4 misc bytes and 2 spacing bytes
433 abr.device()->seek(abr.device()->pos() + 6);
434
435 if (abr_hdr->version == 2)
437 if (name.isNull()) {
439 }
440
441 // discard 1 byte for antialiasing and 4 x short for short bounds
442 abr.device()->seek(abr.device()->pos() + 9);
443
444 // long
445 abr >> top;
446 abr >> left;
447 abr >> bottom;
448 abr >> right;
449 // short
450 abr >> depth;
451 // char
452 abr.device()->getChar(&compression);
453
454 width = right - left;
455 height = bottom - top;
456 size = width * (depth >> 3) * height;
457
458 /* FIXME: support wide brushes */
459 if (height > 16384) {
460 warnKrita << "WARNING: wide brushes not supported";
461 abr.device()->seek(next_brush);
462 }
463 else {
464 buffer = (char*)malloc(size);
465
466 if (!compression) {
467 // not compressed - read raw bytes as brush data
468 abr.readRawData(buffer, size);
469 } else {
470 rle_decode(abr, buffer, height);
471 }
472
473 KisAbrBrushSP abrBrush;
474 QImage brushTipImage = convertToQImage(buffer, width, height);
475 if (m_abrBrushes->contains(name)) {
476 abrBrush = m_abrBrushes.data()->operator[](name);
477 }
478 else {
479 abrBrush = KisAbrBrushSP(new KisAbrBrush(name, this));
480 QBuffer buf;
481 buf.open(QFile::ReadWrite);
482 brushTipImage.save(&buf, "PNG");
483 abrBrush->setMD5Sum(KoMD5Generator::generateHash(buf.data()));
484 }
485
486 abrBrush->setBrushTipImage(brushTipImage);
487 // XXX: call extra setters on abrBrush for other options of ABR brushes free (buffer);
488 abrBrush->setValid(true);
489 abrBrush->setName(name);
490 m_abrBrushes.data()->operator[](name) = abrBrush;
491 layer_ID = 1;
492 }
493 }
494 else {
495 warnKrita << "Unknown ABR brush type, skipping.";
496 abr.device()->seek(next_brush);
497 }
498
499 return layer_ID;
500}
static QString generateHash(const QString &filename)
generateHash reads the given file and generates a hex-encoded md5sum for the file.
static QString abr_v1_brush_name(const QString filename, qint32 id)
static QString abr_read_ucs2_text(QDataStream &abr)
static QImage convertToQImage(char *buffer, qint32 width, qint32 height)
save the QImages as png files to directory image_tests
static qint32 rle_decode(QDataStream &abr, char *buffer, qint32 height)
#define warnKrita
Definition kis_debug.h:87
const char * name(StandardAction id)
int size(const Forest< T > &forest)
Definition KisForest.h:1232
int depth(typename Forest< T >::const_child_iterator beginIt, typename Forest< T >::const_child_iterator endIt)
Definition KisForest.h:1213

References abr_read_ucs2_text(), abr_v1_brush_name(), convertToQImage(), filename(), KoMD5Generator::generateHash(), m_abrBrushes, rle_decode(), AbrInfo::version, and warnKrita.

◆ abr_brush_load_v6()

quint32 KisAbrBrushCollection::abr_brush_load_v6 ( QDataStream & abr,
AbrInfo * abr_hdr,
const QString filename,
qint32 image_ID,
qint32 id )
private

Definition at line 301 of file kis_abr_brush_collection.cpp.

302{
303 Q_UNUSED(image_ID);
304 qint32 brush_size = 0;
305 qint32 brush_end = 0;
306 qint32 next_brush = 0;
307
308 qint32 top, left, bottom, right;
309 top = left = bottom = right = 0;
310 short depth;
311 char compression;
312
313 qint32 width = 0;
314 qint32 height = 0;
315 qint32 size = 0;
316
317 qint32 layer_ID = -1;
318
319 char *buffer;
320
321 abr >> brush_size;
322 brush_end = brush_size;
323 // complement to 4
324 while (brush_end % 4 != 0) {
325 brush_end++;
326 }
327
328 next_brush = abr.device()->pos() + brush_end;
329
330 // discard key
331 abr.device()->seek(abr.device()->pos() + 37);
332 if (abr_hdr->subversion == 1)
333 // discard short coordinates and unknown short
334 abr.device()->seek(abr.device()->pos() + 10);
335 else
336 // discard unknown bytes
337 abr.device()->seek(abr.device()->pos() + 264);
338
339 // long
340 abr >> top;
341 abr >> left;
342 abr >> bottom;
343 abr >> right;
344 // short
345 abr >> depth;
346 // char
347 abr.device()->getChar(&compression);
348
349 width = right - left;
350 height = bottom - top;
351 size = width * (depth >> 3) * height;
352
353 // remove .abr and add some id, so something like test.abr -> test_12345
354 QString name = abr_v1_brush_name(filename, id);
355
356 buffer = (char*)malloc(size);
357
358 // data decoding
359 if (!compression) {
360 // not compressed - read raw bytes as brush data
361 //fread (buffer, size, 1, abr);
362 abr.readRawData(buffer, size);
363 } else {
364 rle_decode(abr, buffer, height);
365 }
366
367 if (width < quint16_MAX && height < quint16_MAX) {
368 // filename - filename of the file , e.g. test.abr
369 // name - test_number_of_the_brush, e.g test_1, test_2
370 KisAbrBrushSP abrBrush;
371 QImage brushTipImage = convertToQImage(buffer, width, height);
372 if (m_abrBrushes->contains(name)) {
373 abrBrush = m_abrBrushes.data()->operator[](name);
374 }
375 else {
376 abrBrush = KisAbrBrushSP(new KisAbrBrush(name, this));
377 QBuffer buf;
378 buf.open(QFile::ReadWrite);
379 brushTipImage.save(&buf, "PNG");
380 abrBrush->setMD5Sum(KoMD5Generator::generateHash(buf.data()));
381 }
382
383 abrBrush->setBrushTipImage(brushTipImage);
384 // XXX: call extra setters on abrBrush for other options of ABR brushes
385 abrBrush->setValid(true);
386 abrBrush->setName(name);
387 m_abrBrushes.data()->operator[](name) = abrBrush;
388
389 }
390
391 free(buffer);
392 abr.device()->seek(next_brush);
393
394 layer_ID = id;
395 return layer_ID;
396}
const quint16 quint16_MAX
Definition kis_global.h:25

References abr_v1_brush_name(), convertToQImage(), filename(), KoMD5Generator::generateHash(), m_abrBrushes, quint16_MAX, rle_decode(), and AbrInfo::subversion.

◆ brushByName()

KisAbrBrushSP KisAbrBrushCollection::brushByName ( QString name) const
inline

Definition at line 72 of file kis_abr_brush_collection.h.

72 {
73 if (m_abrBrushes->contains(name)) {
74 return m_abrBrushes.data()->operator[](name);
75 }
76 return KisAbrBrushSP();
77 }

◆ brushes()

QList< KisAbrBrushSP > KisAbrBrushCollection::brushes ( ) const
inline

Definition at line 64 of file kis_abr_brush_collection.h.

64 {
65 return m_abrBrushes->values();
66 }

◆ brushesMap()

QSharedPointer< QMap< QString, KisAbrBrushSP > > KisAbrBrushCollection::brushesMap ( ) const
inline

Definition at line 68 of file kis_abr_brush_collection.h.

68 {
69 return m_abrBrushes;
70 }

◆ defaultFileExtension()

QString KisAbrBrushCollection::defaultFileExtension ( ) const
Returns
default file extension for saving the brush

Definition at line 633 of file kis_abr_brush_collection.cpp.

634{
635 return QString(".abr");
636}

◆ filename()

QString KisAbrBrushCollection::filename ( ) const
inline

Definition at line 83 of file kis_abr_brush_collection.h.

83 {
84 return m_filename;
85 }

◆ image()

QImage KisAbrBrushCollection::image ( ) const
Returns
a preview of the brush

Definition at line 618 of file kis_abr_brush_collection.cpp.

619{
620 if (m_abrBrushes->size() > 0) {
621 return m_abrBrushes->values().first()->image();
622 }
623 return QImage();
624}

References m_abrBrushes.

◆ isLoaded()

bool KisAbrBrushCollection::isLoaded ( ) const

Definition at line 613 of file kis_abr_brush_collection.cpp.

614{
615 return m_isLoaded;
616}

References m_isLoaded.

◆ lastModified()

QDateTime KisAbrBrushCollection::lastModified ( ) const
inline

Definition at line 79 of file kis_abr_brush_collection.h.

79 {
80 return m_lastModified;
81 }

◆ load()

bool KisAbrBrushCollection::load ( )

Definition at line 543 of file kis_abr_brush_collection.cpp.

544{
545 m_isLoaded = true;
546 QFile file(filename());
547 QFileInfo info(file);
548 m_lastModified = info.lastModified();
549 // check if the file is open correctly
550 if (!file.open(QIODevice::ReadOnly)) {
551 warnKrita << "Can't open file " << filename();
552 return false;
553 }
554
555 bool res = loadFromDevice(&file);
556 file.close();
557
558 return res;
559
560}
bool loadFromDevice(QIODevice *dev)

References filename(), loadFromDevice(), m_isLoaded, m_lastModified, and warnKrita.

◆ loadFromDevice()

bool KisAbrBrushCollection::loadFromDevice ( QIODevice * dev)

Definition at line 562 of file kis_abr_brush_collection.cpp.

563{
564 AbrInfo abr_hdr;
565 qint32 image_ID;
566 int i;
567 qint32 layer_ID;
568
569 QByteArray ba = dev->readAll();
570 QBuffer buf(&ba);
571 buf.open(QIODevice::ReadOnly);
572 QDataStream abr(&buf);
573
574
575 if (!abr_read_content(abr, &abr_hdr)) {
576 warnKrita << "Error: cannot parse ABR file: " << filename();
577 return false;
578 }
579
580 if (!abr_supported_content(&abr_hdr)) {
581 warnKrita << "ERROR: unable to decode abr format version " << abr_hdr.version << "(subver " << abr_hdr.subversion << ")";
582 return false;
583 }
584
585 if (abr_hdr.count == 0) {
586 errKrita << "ERROR: no sample brush found in " << filename();
587 return false;
588 }
589
590 image_ID = 123456;
591
592 for (i = 0; i < abr_hdr.count; i++) {
593 layer_ID = abr_brush_load(abr, &abr_hdr, QFileInfo(filename()).fileName(), image_ID, i + 1);
594 if (layer_ID == -1) {
595 warnKrita << "Warning: problem loading brush #" << i << " in " << filename();
596 }
597 }
598
599 return true;
600
601}
qint32 abr_brush_load(QDataStream &abr, AbrInfo *abr_hdr, const QString filename, qint32 image_ID, qint32 id)
static bool abr_read_content(QDataStream &abr, AbrInfo *abr_hdr)
static bool abr_supported_content(AbrInfo *abr_hdr)
#define errKrita
Definition kis_debug.h:107

References abr_brush_load(), abr_read_content(), abr_supported_content(), AbrInfo::count, errKrita, filename(), AbrInfo::subversion, AbrInfo::version, and warnKrita.

◆ save()

bool KisAbrBrushCollection::save ( )

Definition at line 603 of file kis_abr_brush_collection.cpp.

604{
605 return false;
606}

◆ saveToDevice()

bool KisAbrBrushCollection::saveToDevice ( QIODevice * dev) const

Definition at line 608 of file kis_abr_brush_collection.cpp.

609{
610 return false;
611}

◆ toXML()

void KisAbrBrushCollection::toXML ( QDomDocument & d,
QDomElement & e ) const
protected

Definition at line 626 of file kis_abr_brush_collection.cpp.

627{
628 Q_UNUSED(d);
629 Q_UNUSED(e);
630 // Do nothing...
631}

Member Data Documentation

◆ m_abrBrushes

QSharedPointer<QMap<QString, KisAbrBrushSP> > KisAbrBrushCollection::m_abrBrushes
private

Definition at line 101 of file kis_abr_brush_collection.h.

◆ m_filename

QString KisAbrBrushCollection::m_filename
private

Definition at line 100 of file kis_abr_brush_collection.h.

◆ m_isLoaded

bool KisAbrBrushCollection::m_isLoaded
private

Definition at line 98 of file kis_abr_brush_collection.h.

◆ m_lastModified

QDateTime KisAbrBrushCollection::m_lastModified
private

Definition at line 99 of file kis_abr_brush_collection.h.


The documentation for this class was generated from the following files: