DUDS
Distributed Update of Data from Something
BppImage.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the DUDS project. It is subject to the BSD-style
3  * license terms in the LICENSE file found in the top-level directory of this
4  * distribution and at https://github.com/jjackowski/duds/blob/master/LICENSE.
5  * No part of DUDS, including this file, may be copied, modified, propagated,
6  * or distributed except according to the terms contained in the LICENSE file.
7  *
8  * Copyright (C) 2018 Jeff Jackowski
9  */
10 
13 #include <duds/general/Errors.hpp>
14 
15 namespace duds { namespace ui { namespace graphics {
16 
17 std::ostream &operator << (std::ostream &os, const ImageLocation &il) {
18  os << '(' << il.x << ',' << il.y << ')';
19  return os;
20 }
21 
22 std::ostream &operator << (std::ostream &os, const ImageDimensions &id) {
23  os << '[' << id.w << ',' << id.h << ']';
24  return os;
25 }
26 
27 
29 img(bufferBlockSize(id.w, id.h)), dim(id),
30 blkPerLine(bufferBlocksPerLine(id.w))
31 { }
32 
34 img(std::move(mv.img)), dim(mv.dim), blkPerLine(mv.blkPerLine) {
35  mv.dim.w = mv.dim.h = 0;
36  mv.blkPerLine = 0;
37 }
38 
40 img(src.img), dim(src.dim), blkPerLine(src.blkPerLine) { }
41 
43  const char *data
44 ) {
45  // data starts with width, then height, both as little endian shorts
46  dim.w = data[0] | (data[1] << 8);
47  dim.h = data[2] | (data[3] << 8);
48  data += 4;
49  // allocate space for image
50  img.resize(bufferBlockSize(dim.w, dim.h));
52  // move over image data one char at a time
53  for (int y = 0; y < dim.h; ++y) {
54  // find start of line in destination; may be more padded than source
55  char *dest = (char*)bufferLine(y);
56  for (int x = 0; x < dim.w; ++data, ++dest, x += 8) {
57  // may copy past end of width, but space is allocated, so no problem
58  *dest = *data;
59  }
60  }
61 }
62 
64  const std::vector<char> &data
65 ) {
66  // assure a size large enough to hold the smallest image
67  if (data.size() < 5) {
69  }
70  // data starts with width, then height, both as little endian shorts
71  dim.w = data[0] | (data[1] << 8);
72  dim.h = data[2] | (data[3] << 8);
73  // check input for adequate length
74  if (data.size() < ((dim.w / 8 + ((dim.w % 8) ? 1 : 0)) * dim.h + 4)) {
75  // too short
78  );
79  }
80  // allocate space for image
81  img.resize(bufferBlockSize(dim.w, dim.h));
83  std::vector<char>::const_iterator citer = data.cbegin() + 4;
84  // move over image data one char at a time
85  for (int y = 0; y < dim.h; ++y) {
86  // find start of line in destination; may be more padded than source
87  char *dest = (char*)bufferLine(y);
88  for (int x = 0; x < dim.w; ++citer, ++dest, x += 8) {
89  // may copy past end of width, but space is allocated, so no problem
90  *dest = *citer;
91  }
92  }
93 }
94 
96  img = std::move(mv.img);
97  dim = mv.dim;
98  blkPerLine = mv.blkPerLine;
99  mv.blkPerLine = 0;
100  mv.dim.w = mv.dim.h = 0;
101  return *this;
102 }
103 
105  img = src.img;
106  dim = src.dim;
107  blkPerLine = src.blkPerLine;
108  return *this;
109 }
110 
111 void BppImage::swap(BppImage &other) {
112  img.swap(other.img);
113  std::swap(dim, other.dim);
115 }
116 
118  img.clear();
119  dim.w = dim.h = 0;
120  blkPerLine = 0;
121 }
122 
124  if ((newdim.w < 0) || (newdim.h < 0)) {
126  ImageErrorDimensions(newdim)
127  );
128  }
129  if (newdim.empty()) {
130  clear();
131  } else if (newdim != dim) {
132  dim = newdim;
133  img.resize(bufferBlockSize(dim.w, dim.h));
135  }
136 }
137 
139  if (img.empty()) {
141  }
142  return &(img[0]);
143 }
144 
145 bool BppImage::operator == (const BppImage &other) const {
146  // both empty?
147  if (dim.empty() && other.dim.empty()) {
148  return true;
149  }
150  // dimension mismatch?
151  if (dim != other.dim) {
152  return false;
153  }
154  // produce mask for right side of image; might cover whole image
155  PixelBlock mask = PixelBlock(-1) >>
156  (sizeof(PixelBlock) * 8) - (dim.w % (sizeof(PixelBlock) * 8));
157  // traverse image data
158  const PixelBlock *spot = &(img[0]), *otherspot = &(other.img[0]);
159  for (int y = 0; y < dim.h; ++y, ++spot, ++otherspot) {
160  // visit all but rightmost block; may visit nothing
161  for (int x = 0; x < (blocksPerLine() - 1); ++x, ++spot, ++otherspot) {
162  if (*spot != *otherspot) {
163  return false;
164  }
165  }
166  // compare rightmost block
167  if ((*spot & mask) != (*otherspot & mask)) {
168  return false;
169  }
170  }
171  // everything matches
172  return true;
173 }
174 
176  if ((py > dim.h) || (py < 0)) {
180  );
181  }
182  return &(img[blkPerLine * py]);
183 }
184 
186  PixelBlock *(&addr),
187  PixelBlock &mask,
188  const ImageLocation &il
189 ) {
190  // bounds check
191  if (!dim.withinBounds(il)) {
195  );
196  }
197  mask = (PixelBlock)1 << (il.x % (sizeof(PixelBlock) * 8));
198  addr = &(img[blkPerLine * il.y + (il.x / (sizeof(PixelBlock) * 8))]);
199 }
200 
202  return startPosition(ImageLocation(0, 0), dim, dir);
203 }
204 
206  const ImageLocation &origin,
207  const ImageDimensions &size,
208  Direction dir
209 ) {
210  switch (dir) {
211  case HorizInc:
212  return ImageLocation(origin.x, origin.y);
213  case VertInc:
214  return ImageLocation(origin.x + size.w - 1, origin.y);
215  case HorizDec:
216  return ImageLocation(origin.x + size.w - 1, origin.y + size.h - 1);
217  case VertDec:
218  return ImageLocation(origin.x, origin.y + size.h - 1);
219  default:
221  }
222 }
223 
225  if (dim.withinBounds(il)) {
226  return Pixel(this, il, dir);
227  } else {
231  );
232  }
233 }
234 
236  const ImageLocation &il,
237  Direction dir
238 ) const {
239  if (dim.withinBounds(il)) {
240  return ConstPixel(this, il, dir);
241  } else {
245  );
246  }
247 }
248 
250  if (img.empty()) {
252  }
253  return Pixel(this);
254 }
255 
257  if (img.empty()) {
259  }
260  return Pixel(this, startPosition(dir), dir);
261 }
262 
264  const ImageLocation &origin,
265  const ImageDimensions &size,
266  Direction dir
267 ) {
268  if (img.empty()) {
270  }
271  return Pixel(this, origin, size, startPosition(dir), dir);
272 }
273 
275  if (img.empty()) {
277  }
278  return ConstPixel(this);
279 }
280 
282  if (img.empty()) {
284  }
285  return ConstPixel(this, startPosition(dir), dir);
286 }
287 
289  const ImageLocation &origin,
290  const ImageDimensions &size,
291  Direction dir
292 ) const {
293  if (img.empty()) {
295  }
296  return ConstPixel(this, origin, size, startPosition(ImageLocation(0,0), size, dir), dir);
297 }
298 
299 bool BppImage::state(const ImageLocation &il) const {
300  const PixelBlock *a;
301  PixelBlock m;
302  bufferSpot(a, m, il);
303  return (*a & m) != 0;
304 }
305 
306 void BppImage::state(const ImageLocation &il, bool s) {
307  PixelBlock *a;
308  PixelBlock m;
309  bufferSpot(a, m, il);
310  *a = (*a & ~m) | (s ? m : 0);
311 }
312 
314  PixelBlock *a;
315  PixelBlock m;
316  bufferSpot(a, m, il);
317  return ((*a = (*a & ~m) ^ m) & m) != 0;
318 }
319 
321  for (PixelBlock &b : img) {
322  b = ~b;
323  }
324 }
325 
326 void BppImage::invertLines(int start, int height) {
327  PixelBlock *end = bufferLine(start + height);
328  for (PixelBlock *b = bufferLine(start); b < end; ++b) {
329  *b = ~(*b);
330  }
331 }
332 
333 void BppImage::patternLines(int start, int height, PixelBlock val) {
334  PixelBlock *end = bufferLine(start + height);
335  for (PixelBlock *b = bufferLine(start); b < end; ++b) {
336  *b = val;
337  }
338 }
339 
340 void BppImage::blankImage(bool s) {
341  PixelBlock v;
342  if (s) {
343  v = -1;
344  } else {
345  v = 0;
346  }
347  for (PixelBlock &b : img) {
348  b = v;
349  }
350 }
351 
352 
353 static bool opsetbit(bool dest, bool src) {
354  return src;
355 }
356 
357 static bool opnotbit(bool dest, bool src) {
358  return !src;
359 }
360 
361 static bool opandbit(bool dest, bool src) {
362  return dest && src;
363 }
364 
365 static bool oporbit(bool dest, bool src) {
366  return dest || src;
367 }
368 
369 static bool opxorbit(bool dest, bool src) {
370  return dest ^ src;
371 }
372 
374  opsetbit,
375  opnotbit,
376  opandbit,
377  oporbit,
378  opxorbit
379 };
380 
381 static void opset(
382  BppImage::PixelBlock *dest,
383  const BppImage::PixelBlock &src,
384  const BppImage::PixelBlock &mask
385 ) {
386  *dest = (*dest & ~mask) | (src & mask);
387 }
388 
389 static void opnot(
390  BppImage::PixelBlock *dest,
391  const BppImage::PixelBlock &src,
392  const BppImage::PixelBlock &mask
393 ) {
394  *dest = (*dest & ~mask) | (~src & mask);
395 }
396 
397 static void opand(
398  BppImage::PixelBlock *dest,
399  const BppImage::PixelBlock &src,
400  const BppImage::PixelBlock &mask
401 ) {
402  *dest = (*dest & ~mask) | ((src & *dest) & mask);
403 }
404 
405 static void opor(
406  BppImage::PixelBlock *dest,
407  const BppImage::PixelBlock &src,
408  const BppImage::PixelBlock &mask
409 ) {
410  *dest |= src & mask;
411 }
412 
413 static void opxor(
414  BppImage::PixelBlock *dest,
415  const BppImage::PixelBlock &src,
416  const BppImage::PixelBlock &mask
417 ) {
418  *dest = (*dest & ~mask) | ((src ^ *dest) & mask);
419 }
420 
422  opset,
423  opnot,
424  opand,
425  opor,
426  opxor
427 };
428 
429 
431  const BppImage * const src,
432  const ImageLocation &destLoc,
433  const ImageLocation &srcLoc,
434  const ImageDimensions &srcSize,
435  Direction srcDir,
436  Operation op
437 ) {
438  if ((op < OpSet) || (op > OpXor)) {
439  // bad data
441  }
442  // source iterator
443  ConstPixel siter = src->cbegin(srcLoc, srcSize, srcDir);
444  ImageDimensions destSize;
445  if ((srcDir == VertInc) || (srcDir == HorizDec)) {
446  // the iteration direction rotates the image 90 degrees; the dimensions
447  // are swapped for writing to the destination image
448  destSize = srcSize.swappedAxes();
449  } else {
450  destSize = srcSize;
451  }
452  // destination iterator
453  Pixel diter = begin(destLoc, destSize);
454  // iteratate over the image's pixels
457  for (; siter != EndPixel(); ++diter, ++siter) {
458  *diter = OpBitFunctions[op](*diter, *siter);
459  }
460 }
461 
463  const BppImage * const src,
464  const ImageLocation &dest,
465  Direction srcDir,
466  Operation op
467 ) {
468  ImageDimensions s(src->dimensions());
469  bool swapped = false;
470  if ((srcDir == VertInc) || (srcDir == HorizDec)) {
471  // the iteration direction rotates the image 90 degrees; the dimensions
472  // are swapped for comaprisons to the destination image
473  s.swapAxes();
474  swapped = true;
475  }
476  // source dimensions clipped to available destination size
477  ImageDimensions d = dim.clip(s, dest);
478  if (swapped) {
479  d.swapAxes();
480  }
481  // do the writing
482  write(src, dest, ImageLocation(0, 0), d, srcDir, op);
483 }
484 
486  ImageLocation ul,
487  ImageDimensions id,
488  Operation op
489 ) {
490  // check for nothing to draw
491  if (id.empty()) {
492  return;
493  }
494  // bounds check
495  if (!dim.withinBounds(ul)) {
499  );
500  }
501  if (!dim.withinBounds(ul - ImageLocation(1,1) + id)) {
504  ImageErrorLocation(ul - ImageLocation(1,1) + id)
505  );
506  }
507  // compute start and end addresses ingoring line height
508  PixelBlock *next = &(img[blkPerLine * ul.y + (ul.x / (sizeof(PixelBlock) * 8))]);
509  static const PixelBlock ones = -1;
510  PixelBlock mask, modmask, offset = 0;
511  std::int16_t stop = ul.x + id.w;
512  // compute start mask
513  if (!(ul.x % (sizeof(PixelBlock) * 8)) && ((stop - ul.x) >= (sizeof(PixelBlock) * 8))) {
514  // a whole block will be used
515  ul.x += sizeof(PixelBlock) * 8;
516  mask = ones;
517  } else {
518  // first bit
519  mask = PixelBlock(1) << (ul.x % (sizeof(PixelBlock) * 8));
520  modmask = mask << 1;
521  // is there a way to optimize out the loop? yes
522  for (++ul.x; modmask && (ul.x < stop); ++ul.x) {
523  mask |= modmask;
524  modmask <<= 1;
525  }
526  }
527  // write first block changes
528  for (int loop = 0; loop < id.h; offset += blocksPerLine(), ++loop
529  ) {
530  OpFunctions[op](next + offset, ones, mask);
531  }
532  // loop until the end
533  while (ul.x < stop) {
534  assert(!(ul.x % (sizeof(PixelBlock) * 8)));
535  // advance the address
536  ++next;
537  // compute the next mask
538  if ((stop - ul.x) >= (sizeof(PixelBlock) * 8)) {
539  // a whole block will be used
540  mask = ones;
541  } else {
542  mask = ones >>
543  (sizeof(PixelBlock) * 8) - (ul.x % (sizeof(PixelBlock) * 8));
544  }
545  ul.x += sizeof(PixelBlock) * 8;
546  // write next block changes
547  offset = 0;
548  for (int loop = 0; loop < id.h; offset += blocksPerLine(), ++loop) {
549  OpFunctions[op](next + offset, ones, mask);
550  }
551  }
552 }
553 
554 // -------------------------------------------------------------------
555 
557  const BppImage *img,
558  const End
559 ) : pos(-1, -1), blk(nullptr),
560 // ConstPixel stores a pointer to a non-const BppImage, even though it will
561 // not modify the image, because it is the base class for Pixel
562 src(const_cast<BppImage*>(img))
563 { }
564 
566  const BppImage *img,
567  const ImageLocation &il,
568  Direction d
569 ) : dir(d), orig(0, 0), dim(img->dimensions()),
570 // ConstPixel stores a pointer to a non-const BppImage, even though it will
571 // not modify the image, because it is the base class for Pixel
572 src(const_cast<BppImage*>(img)) {
573  // set the location; throw if out of bounds
574  location(il);
575  // do not request a buffer spot when making an end iterator
576  if ((il.x != -1) && (il.y != -1)) {
577  src->bufferSpot(blk, mask, pos);
578  }
579 }
580 
582  const BppImage *img,
583  const ImageLocation &o,
584  const ImageDimensions &s,
585  const ImageLocation &p,
586  Direction d
587 ) : dir(d),
588 // ConstPixel stores a pointer to a non-const BppImage, even though it will
589 // not modify the image, because it is the base class for Pixel
590 src(const_cast<BppImage*>(img)) {
591  // set the location, origin, and dimensions; throw if out of bounds
592  origdimloc(o, s, p);
593  /* broken, but should it be fixed?
594  // do not request a buffer spot when making an end iterator
595  if ((il.x != -1) && (il.y != -1)) {
596  src->bufferSpot(blk, mask, orig + pos);
597  }
598  */
599 }
600 
602  const BppImage::Pixel &p
603 ) {
604  return *this = (ConstPixel)p;
605 }
606 
615  switch (dir) {
616  case HorizInc:
617  if (++pos.x >= dim.w) {
618  if (++pos.y >= dim.h) {
619  pos.x = pos.y = -1;
620  blk = nullptr;
621  break;
622  }
623  pos.x = 0;
624  // was fine when origin was (0,0) and dim matched the image
625  //mask = 1;
626  //++blk;
627  src->bufferSpot(blk, mask, orig + pos);
628  } else {
629  mask <<= 1;
630  // advance to next block of pixels?
631  if (!mask) {
632  mask = 1;
633  ++blk;
634  }
635  }
636  break;
637  case VertInc:
638  if (++pos.y >= dim.h) {
639  if (--pos.x < 0) {
640  pos.x = pos.y = -1;
641  blk = nullptr;
642  break;
643  }
644  pos.y = 0;
645  }
646  src->bufferSpot(blk, mask, orig + pos);
647  break;
648  case HorizDec:
649  if (--pos.x < 0) {
650  if (--pos.y < 0) {
651  pos.x = pos.y = -1;
652  blk = nullptr;
653  break;
654  }
655  pos.x = dim.w - 1;
656  // was fine when origin was (0,0) and dim matched the image
657  //mask = 1 << (pos.x % (sizeof(PixelBlock) * 8));
658  //--blk;
659  src->bufferSpot(blk, mask, orig + pos);
660  } else {
661  mask >>= 1;
662  // advance to next block of pixels?
663  if (!mask) {
664  mask = 1 << (pos.x % (sizeof(PixelBlock) * 8));
665  --blk;
666  }
667  }
668  break;
669  case VertDec:
670  if (--pos.y < 0) {
671  if (++pos.x >= dim.w ) {
672  pos.x = pos.y = -1;
673  blk = nullptr;
674  break;
675  }
676  pos.y = dim.h - 1;
677  }
678  src->bufferSpot(blk, mask, orig + pos);
679  break;
680  default:
681  // PANIC!!!
683  }
684  return *this;
685 }
686 
688  if (dim.withinBounds(il)) {
689  // store the location
690  pos = il;
691  // set internal data to use new location
692  src->bufferSpot(blk, mask, orig + pos);
693  } else {
697  );
698  }
699 }
700 
702  if (src->dimensions().withinBounds(il + dim)) {
703  // store the new origin
704  orig = il;
705  // update internal data to use new location
706  src->bufferSpot(blk, mask, orig + pos);
707  } else {
711  );
712  }
713 }
714 
716  if (d.withinBounds(pos) &&
718  ) {
719  // store the new dimensions
720  dim = d;
721  // spot in image buffer unchanged
722  } else {
726  );
727  }
728 }
729 
731  const ImageLocation &o,
732  const ImageDimensions &d,
733  const ImageLocation &p
734 ) {
735  if (d.withinBounds(p) &&
736  src->dimensions().withinBounds(o - ImageLocation(1,1) + d)
737  ) {
738  // store the new data
739  orig = o;
740  dim = d;
741  pos = p;
742  // set internal data to use new location
743  src->bufferSpot(blk, mask, orig + pos);
744  } else {
745  if (d.withinBounds(p)) {
748  ImageErrorLocation(o + d)
749  );
750  } else {
754  );
755  }
756  }
757 }
758 
760  // check for a possible end iterator
761  if (!src || !cp.src) {
762  // check positions only; dimensions and origin do not matter
763  return (
764  (pos.x == -1) && (pos.y == -1) &&
765  (cp.pos.x == -1) && (cp.pos.y == -1)
766  );
767  }
768  // all data must match
769  return (src == cp.src) && (pos == cp.pos) &&
770  (orig == cp.orig) && (dim == cp.dim);
771 }
772 
774  if (blk) {
775  return (*blk & mask) != 0;
776  } else {
778  }
779 }
780 
782  if (blk) {
783  *blk = (*blk & ~mask) | (s ? mask : 0);
784  } else {
786  }
787 }
788 
790  if (blk) {
791  return ((*blk = (*blk & ~mask) ^ mask) & mask) != 0;
792  } else {
794  }
795 }
796 
798  ImageDimensions dim(0, 0);
799  if (i0) {
800  if (i1) {
801  dim = i0->dimensions().maxExtent(i1->dimensions());
802  } else {
803  dim = i0->dimensions();
804  }
805  } else if (i1) {
806  dim = i1->dimensions();
807  }
808  return dim;
809 }
810 
811 } } }
std::uintptr_t PixelBlock
The type used to hold pixel values, one bit per pixel.
Definition: BppImage.hpp:326
constexpr ImageDimensions clip(const ImageDimensions &dim, const ImageLocation &loc=ImageLocation(0, 0)) const
Returns a region clipped to fit within this object&#39;s dimensions.
Definition: BppImage.hpp:234
const ImageDimensions & dimensions() const
Returns the dimensions of the image.
Definition: BppImage.hpp:1112
The total number of supported operations.
Definition: BppImage.hpp:1550
boost::error_info< struct Info_ImageDimensions, ImageDimensions > ImageErrorDimensions
Image dimensions relevant to the error.
Definition: BppImage.hpp:293
ImageDimensions dim
The dimensions of the image to iterate over; can be used to limit the portion visited by the iterator...
Definition: BppImage.hpp:489
bool empty() const
Returns true if there is no image data.
Definition: BppImage.hpp:1080
The base class for errors related to the use of images.
Stores a location within an image.
Definition: BppImage.hpp:33
void invertLines(int start, int height)
Toggles the state of all pixels of the given contiguous horizontal lines.
Definition: BppImage.cpp:326
std::int16_t y
Vertical coordinate.
Definition: BppImage.hpp:41
PixelBlock mask
The mask used to isolate the referenced pixel.
Definition: BppImage.hpp:475
Pixel pixel(const ImageLocation &il, Direction dir=HorizInc)
Returns a Pixel (iterator) to iterate across the image starting from the given location.
Definition: BppImage.cpp:224
std::int16_t x
Horizontal coordinate.
Definition: BppImage.hpp:37
ImageLocation startPosition(Direction dir=HorizInc) const
Returns the starting location needed to iterate over the entire image in the given direction...
Definition: BppImage.cpp:201
const PixelBlock * bufferLine(int py) const
Returns a pointer to the start of the given line.
Definition: BppImage.cpp:175
constexpr bool empty() const
True if the dimensions indicate zero area.
Definition: BppImage.hpp:169
void(* OpFunction)(PixelBlock *dest, const PixelBlock &src, const PixelBlock &mask)
Definition: BppImage.hpp:1560
static bool oporbit(bool dest, bool src)
Definition: BppImage.cpp:365
ImageLocation pos
The location of the referenced pixel on the source image.
Definition: BppImage.hpp:479
void swap(NddArray< T > &one, NddArray< T > &two)
Makes NddAray meet the requirements of Swappable to assist in using std::swap().
Definition: NddArray.hpp:1211
const std::vector< PixelBlock > & data() const
Provides access to the internal vector storing the image data.
Definition: BppImage.hpp:1133
bool state() const
Returns the state of the referenced pixel.
Definition: BppImage.cpp:773
A forward and output iterator that visits each location of the image.
Definition: BppImage.hpp:823
static constexpr int bufferBlocksPerLine(int width)
Returns the number of PixelBlock objects that will be used for each horizontal line of an image of th...
Definition: BppImage.hpp:363
STL namespace.
constexpr ImageDimensions maxExtent(const ImageDimensions &dim) const
Returns new dimensions that are minimally large enough to fit this dimension and the given dimension...
Definition: BppImage.hpp:222
BppImage & operator=(BppImage &&mv)
Move assignment.
Definition: BppImage.cpp:95
constexpr ConstPixel()
Construct a ConstPixel to nowhere.
Definition: BppImage.hpp:498
move_impl move(unsigned int c, unsigned int r)
Display stream manipulator that moves the display cursor to the given location.
void invert()
Toggles the state of all pixels.
Definition: BppImage.cpp:320
std::ostream & operator<<(std::ostream &os, const ImageLocation &il)
Writes an ImageLocation object to a stream in human readable form.
Definition: BppImage.cpp:17
Direction dir
The direction to move when incremented.
Definition: BppImage.hpp:493
const ImageLocation & location() const
Returns the coordinates of the referenced pixel relative to this object&#39;s origin. ...
Definition: BppImage.hpp:668
static const OpFunction OpFunctions[OpTotal]
Functions implementing the operations listed in Operation one PixelBlock at a time.
Definition: BppImage.hpp:1566
Data with an image to parse was too short to hold the image.
PixelBlock * blk
The PixelBlock containing the referenced pixel.
Definition: BppImage.hpp:471
static void opxor(BppImage::PixelBlock *dest, const BppImage::PixelBlock &src, const BppImage::PixelBlock &mask)
Definition: BppImage.cpp:413
bool invertPixel(const ImageLocation &il)
Toggles the state of a pixel.
Definition: BppImage.cpp:313
Stores the dimensions of an image.
Definition: BppImage.hpp:125
Pixel begin()
Returns a Pixel (iterator) to the upper left of the image.
Definition: BppImage.cpp:249
The Y coordinate will be incremented.
Definition: BppImage.hpp:399
void patternLines(int start, int height, PixelBlock val)
Writes a pattern of pixles to a set of contiguous horizontal lines.
Definition: BppImage.cpp:333
ConstPixel cbegin() const
Returns a ConstPixel (iterator) to the upper left of the image.
Definition: BppImage.cpp:274
void blankImage(bool state)
Changes the state of every pixel in the image to the given state.
Definition: BppImage.cpp:340
std::vector< PixelBlock > img
The image data.
Definition: BppImage.hpp:331
Performs a bitwise exclusive-or operation with the destination and source data, and places the result...
Definition: BppImage.hpp:1546
static bool opsetbit(bool dest, bool src)
Definition: BppImage.cpp:353
void write(const BppImage *const src, const ImageLocation &destLoc, const ImageLocation &srcLoc, const ImageDimensions &srcSize, Direction srcDir=HorizInc, Operation op=OpSet)
Writes the specified portion of the source into this image.
Definition: BppImage.cpp:430
The Y coordinate will be decremented.
Definition: BppImage.hpp:412
void origdimloc(const ImageLocation &o, const ImageDimensions &d, const ImageLocation &p)
Changes the origin, dimensions, and relative position of this object.
Definition: BppImage.cpp:730
static bool opxorbit(bool dest, bool src)
Definition: BppImage.cpp:369
The Pixel or ConstPixel iterator object was dereferenced when in at the end.
A problem with image bounds, such as the use of a location beyond the image&#39;s dimensions.
ImageDimensions dim
The dimensions of the image.
Definition: BppImage.hpp:335
bool operator==(const BppImage &other) const
Returns true if the contents of the two images are identical.
Definition: BppImage.cpp:145
static constexpr std::size_t bufferBlockSize(int w, int h)
Returns the size of an image buffer as the number of PixelBlock PixelBlocks needed to store an image ...
Definition: BppImage.hpp:347
ConstPixel & operator++()
Pre-increment operator.
Definition: BppImage.cpp:607
static void opset(BppImage::PixelBlock *dest, const BppImage::PixelBlock &src, const BppImage::PixelBlock &mask)
Definition: BppImage.cpp:381
Can be used as an end iterator to avoid making a whole iterator.
Definition: BppImage.hpp:445
void drawBox(ImageLocation ul, ImageDimensions id, Operation op=OpSet)
Draws a box into this image.
Definition: BppImage.cpp:485
int size() const
Returns the number of pixels that make up the image.
Definition: BppImage.hpp:1094
The X coordinate will be decremented until reaching zero.
Definition: BppImage.hpp:406
Pixel end()
Returns a Pixel end iterator.
int blkPerLine
Number of PixelBlocks used for each horizontal line.
Definition: BppImage.hpp:340
void swapAxes()
Swaps the dimensions&#39;s axes.
Definition: BppImage.hpp:202
The X coordinate will be incremented until reaching the width limit.
Definition: BppImage.hpp:393
ImageLocation orig
Upper left corner of the image to limit the iteration to a portion of the whole image.
Definition: BppImage.hpp:484
const ImageLocation & origin() const
Returns this object&#39;s origin used to limit the area of the source image that will be visited...
Definition: BppImage.hpp:721
bool state(const ImageLocation &il) const
Returns the state of the image pixel of the requested location.
Definition: BppImage.cpp:299
ConstPixel & operator=(const ConstPixel &)=default
Obvious assignment operator.
Direction
Controls the direction ConstPixel and Pixel objects will move across the image when the object is inc...
Definition: BppImage.hpp:386
void resize(const duds::ui::graphics::ImageDimensions &newdim)
Changes the size of the image.
Definition: BppImage.cpp:123
ImageDimensions MaxExtent(const BppImage *i0, const BppImage *i1)
Returns the maximum extent of the dimensions of two bit-per-pixel images.
Definition: BppImage.cpp:797
bool toggle()
Toggles the state of the pixel.
Definition: BppImage.cpp:789
static bool opandbit(bool dest, bool src)
Definition: BppImage.cpp:361
void clear()
Removes all image data.
Definition: BppImage.cpp:117
Operation
Tells how to modify the destination pixel with the source pixel data.
Definition: BppImage.hpp:1521
Indicates the image has zero size when an operation requires some image data.
BppImage()
Make an empty image with zero size.
Definition: BppImage.hpp:965
static bool opnotbit(bool dest, bool src)
Definition: BppImage.cpp:357
bool(* OpBitFunction)(bool dest, bool src)
Definition: BppImage.hpp:1553
static void opand(BppImage::PixelBlock *dest, const BppImage::PixelBlock &src, const BppImage::PixelBlock &mask)
Definition: BppImage.cpp:397
A forward iterator like class that visits each location of the image or a subset of the image...
Definition: BppImage.hpp:456
void swap(BppImage &other)
Swap two images.
Definition: BppImage.cpp:111
void bufferSpot(PixelBlock *(&addr), PixelBlock &mask, const ImageLocation &il)
Provides the location of the specified pixel inside the image data.
Definition: BppImage.cpp:185
constexpr ImageDimensions swappedAxes() const
Returns new dimensions with swapped axes.
Definition: BppImage.hpp:208
bool state() const
Returns the state of the referenced pixel.
Definition: BppImage.hpp:897
General graphics related code.
Definition: HD44780.hpp:15
constexpr bool withinBounds(const ImageLocation &loc) const
Returns true if the given location is within the bounds specified by this object. ...
Definition: BppImage.hpp:182
ConstPixel cpixel(const ImageLocation &il, Direction dir=HorizInc) const
Returns a ConstPixel (iterator) to iterate across the image starting from the given location...
Definition: BppImage.cpp:235
boost::error_info< struct Info_ImageLocation, ImageLocation > ImageErrorLocation
An image location relevant to the error.
Definition: BppImage.hpp:288
static void opor(BppImage::PixelBlock *dest, const BppImage::PixelBlock &src, const BppImage::PixelBlock &mask)
Definition: BppImage.cpp:405
const PixelBlock * buffer() const
Retuns a pointer to the start of image data.
Definition: BppImage.cpp:138
BppImage * src
The image to operate upon.
Definition: BppImage.hpp:465
General errors.
Assigns the pixels in the destination the same value as the pixels in the source. ...
Definition: BppImage.hpp:1526
#define DUDS_THROW_EXCEPTION(x)
Works like BOOST_THROW_EXCEPTION, but includes a stack trace if DUDS_ERRORS_VERBOSE is defined...
Definition: Errors.hpp:48
An image that uses a single bit to represent the state of each pixel; a black or white picture...
Definition: BppImage.hpp:321
const ImageDimensions & dimensions() const
Returns this object&#39;s dimensions used to limit the area of the source image that will be visited...
Definition: BppImage.hpp:749
int blocksPerLine() const
Returns the number of PixelBlock objects per row in the image data.
Definition: BppImage.hpp:1167
std::int16_t height() const
Returns the height of the image.
Definition: BppImage.hpp:1106
static const OpBitFunction OpBitFunctions[OpTotal]
Functions implementing the operations listed in Operation one bit at a time.
Definition: BppImage.hpp:1559
bool operator==(const ConstPixel &cp) const
Less than obvious equality operator.
Definition: BppImage.cpp:759
static void opnot(BppImage::PixelBlock *dest, const BppImage::PixelBlock &src, const BppImage::PixelBlock &mask)
Definition: BppImage.cpp:389