98 { rgb_[0] =
r; rgb_[1] =
g; rgb_[2] =
b; }
120 bool operator==(
const RGBColor & oth)
const noexcept
121 {
return((rgb_[0] == oth.rgb_[0]) &&
122 (rgb_[1] == oth.rgb_[1]) &&
123 (rgb_[2] == oth.rgb_[2])); }
125 bool operator!=(
const RGBColor & oth)
const noexcept
126 {
return(!
operator==(oth)); }
191 std::vector<RGBColor> pal_;
225template <ImageCoordDim CELLW = 1, ImageCoordDim CELLH = 1>
236 {
if ((wimage == 0) || (himage == 0))
261 { regionleft_ = xmin; regionright_ = xmin + xlength - 1;
262 regiontop_ = ymin; regionbottom_ = ymin + ylength - 1;
263 if (regionright_ >= wimg_)
264 { regionright_ = wimg_ - 1;
265 xlength = regionright_ - xmin + 1; }
266 if (regionbottom_ >= himg_)
267 { regionbottom_ = himg_ - 1;
268 ylength = regionbottom_ - ymin + 1; }
269 if ((xlength == 0) || (ylength == 0) ||
270 (regionright_ < xmin) || (regionbottom_ < ymin))
272 std::to_string(xmin) +
",w" +
273 std::to_string(xlength) +
",t" +
274 std::to_string(ymin) +
",h" +
275 std::to_string(ylength) +
276 " within image of " +
277 std::to_string(wimg_) +
"x" +
278 std::to_string(himg_) +
281 lastcellx_ = xmin + lastAllowedCoord(xlength,CELLW);
282 regionwidthm1cell_ = lastcellx_ - xmin;
283 sizeonecellrow_ =
static_cast<size_t>(CELLH) *
284 static_cast<size_t>(wimg_); }
291 {
return((x_ >= regionleft_) && (x_ <= regionright_) &&
292 (y_ >= regiontop_) && (y_ <= regionbottom_)); }
300 resc.setRegion(x_,CELLW,y_,CELLH);
309 { setPixel(regionleft_ + xc * CELLW, regiontop_ + yc * CELLH); }
312 void reset(
void)
noexcept { setPixel(regionleft_,regiontop_); }
317 {
return((x_ - regionleft_) / CELLW); }
322 {
return((y_ - regiontop_) / CELLH);}
341 {
if ((!
inside()) || (x_ >= lastcellx_))
return(
false);
342 x_ += CELLW; offset_ += CELLW;
return(
true); }
348 {
if (!
inside())
return(
false);
350 { x_ = regionleft_; y_ += CELLH;
352 static_cast<size_t>(regionwidthm1cell_) +
354 lastrowchange_ =
true; }
355 else lastrowchange_ =
false;
365 { std::string res{
"RasterCursor<"};
366 res += std::to_string(CELLW) +
"," + std::to_string(CELLH) +
367 ">[@(" + std::to_string(x_) +
"," + std::to_string(y_) +
368 "), offs " + std::to_string(offset_) +
", region (l" +
369 std::to_string(regionleft_) +
",r" +
370 std::to_string(regionright_) +
",t" +
371 std::to_string(regiontop_) +
",b" +
372 std::to_string(regionbottom_);
374 res +=
"; lastcellx " +
375 std::to_string(lastcellx_) +
", regionwidth-1cell " +
376 std::to_string(regionwidthm1cell_) +
")," +
377 (
inside() ?
"in" :
"out") +
"," +
387 {
return(celldim <= avdim ?
388 (avdim % celldim == 0 ? avdim - celldim :
389 avdim - (avdim % celldim)) :
397 ImageCoordDim regionleft_,regionright_,regiontop_,regionbottom_;
399 size_t sizeonecellrow_;
403 void checkInside(
void)
const
405 RUNTIMEEXCEP(
"Tried to access out of range RasterImage cursor: "
409 {
return(
static_cast<size_t>(x_) +
static_cast<size_t>(y_) *
410 static_cast<size_t>(wimg_)); }
413 { x_ =
x; y_ =
y; offset_ = offsetOfPixel(x_,y_);
414 lastrowchange_ =
false; }
417 static_assert((CELLW > 0) && (CELLH > 0),
418 "RasterCursor tessellation must have non-empty cells");
432template <
typename PixelType>
443 {
if ((w != 0) && (h != 0))
444 { numofpxs_ =
static_cast<size_t>(w_) *
static_cast<size_t>(h_);
445 pimg_ = SafeImgPtr(
new PixelType [numofpxs_]); } }
452 {
if (
this != &oth) moveFrom(std::move(oth));
return(*
this); }
457 bool empty(
void)
const noexcept {
return(!pimg_); }
458 ImageCoordDim width(
void)
const noexcept { checkEmptied();
return(w_); }
459 ImageCoordDim height(
void)
const noexcept { checkEmptied();
return(h_); }
460 size_t numPixels(
void)
const noexcept { checkEmptied();
return(numofpxs_); }
462 template <ImageCoordDim CELLW = 1, ImageCoordDim CELLH = 1>
466 template <ImageCoordDim CELLW = 1, ImageCoordDim CELLH = 1>
468 { checkEmptied();
return(pimg_.get()[cursor.
globalOffset()]); }
470 template <ImageCoordDim CELLW = 1, ImageCoordDim CELLH = 1>
472 { checkEmptied();
return(pimg_.get()[cursor.
globalOffset()]); }
474 PixelType * contigContent(
void)
noexcept
475 { checkEmptied();
return(pimg_.get()); }
476 const PixelType * contigContent(
void)
const noexcept
477 { checkEmptied();
return(pimg_.get()); }
481 using SafeImgPtr = std::unique_ptr< PixelType [] >;
487 void checkEmptied(
void)
const
491 { w_ = oth.w_; h_ = oth.h_; numofpxs_ = oth.numofpxs_;
492 pimg_ = std::move(oth.pimg_); }
528template <
typename ColorIndex>
542 unsigned w,
unsigned h):
Base{w,h},
546 RUNTIMEEXCEP(
"Incompatible palette for given PalettizedImage"); }
554 auto rgbcur = img.makeCursor();
555 auto thiscur = this->makeCursor();
557 RGBColor{
reinterpret_cast<const uint8_t *
>(
558 img.pixel(rgbcur))});
559 while (rgbcur.forward() && thiscur.forward());
567 {
if (
this != &oth) moveFrom(std::move(oth));
return(*
this); }
572 const RGBPalette & palette(
void)
const noexcept
573 { checkEmptied();
return(*pal_); }
578 RGBImage res{Base::width(),Base::height()};
579 auto pixcur = Base::makeCursor();
580 auto rgbcur = res.makeCursor();
583 auto pixcolind = Base::pixel(pixcur);
584 const RGBColor & rgbc = (*pal_)[pixcolind];
585 auto & p = res.pixel(rgbcur);
589 }
while (pixcur.forward() && rgbcur.forward());
597 void checkEmptied(
void)
const
598 {
if (Base::empty())
RUNTIMEEXCEP(
"Emptied palettized image"); }
601 { Base::operator=(std::move(oth)); pal_ = oth.pal_; }
603 static_assert(std::is_arithmetic<ColorIndex>::value &&
604 std::is_unsigned<ColorIndex>::value,
605 "ColorIndex template argument must be an unsigned type");
uint32_t Size
Size of a palette.
constexpr ImageCoordDim cellW(void) const noexcept
To get the tesselation in X from any RasterCursor object.
RGBColor(const CompLevel *rgb)
Constructor from an array of 3 components in R-G-B order.
void set(const CompLevel *rgb) noexcept
Change all components in R-G-B order.
void resetRegion(void)
Change area of the image reachable by the cursor to the whole image.
RGBColor(const RGBColor &)=default
Moves are just copies.
RasterImage(ImageCoordDim w, ImageCoordDim h)
Constructor: image of certain size; content not set, just stored.
CompLevel g(void) const noexcept
Return the green component.
const RGBColor & operator[](Index ind) const
Read one of the colors. Throw if out of range index.
double rgbDistance2(const RGBColor &oth) const
Return the squared Euclidean distance between THIS and OTH.
void setB(CompLevel b) noexcept
Change the red component.
RGBPalette(Size s)
Constructor: S colors, all (0,0,0). If S is 0, throws.
RasterImage(const RasterImage &)=delete
Copies forbidden; moves leave the original without content.
RGBImage toRGBImg(void) const
Create and return a new RGBImage with the content of this image.
CompLevel b(void) const noexcept
Return the blue component.
bool forward(void) noexcept
Move the cursor one cell forward.
ImageCoordDim y(void) const noexcept
Return the Y-cell coordinate within current region.
CompLevel r(void) const noexcept
Return the red component.
void setRegion(ImageCoordDim xmin, ImageCoordDim xlength, ImageCoordDim ymin, ImageCoordDim ylength)
Change the region of the image reachable by the cursor.
Size numColors(void) const noexcept
Return the number of colors in the palette.
RGBPalette(const RGBColor::CompLevel *rgbs, Size s)
Constructor: from an array of R-G-B bytes for S colors.
std::string to_string(bool summary=true) const
Return a text describing the cursor.
PalettizedImage(const PalettizedImage &)=delete
Copies forbidden; moves leave the original without content.
RGBColor & operator[](Index ind)
Read/write one of the colors. Throw if out of range index.
Size Index
Index of a color in a palette.
void setG(CompLevel g) noexcept
Change the green component.
bool lastChangedRow(void) const noexcept
Return TRUE if the last movement caused a change of row.
RasterCursor< 1, 1 > subCursor(void) const
Return a cursor limited to the cell where this cursor is.
void rgbRead(CompLevel *rgb) const noexcept
Fill the three components into RGB.
uint8_t CompLevel
A component level, from 0 to 255.
RGBColor(CompLevel r=0, CompLevel g=0, CompLevel b=0)
Default constructor.
std::string getHTMLString(void) const
In '#......' HTML format.
std::string to_string(void) const
Return a text describing the color.
static constexpr double kMaxRGBDist2
Maximum squared Euclidean distance between 2 rgb colors.
void setFromHTMLString(const std::string &c)
C must be in '#......' HTML format. Otherwise, throw.
RGBPalette(const RGBPalette &)=delete
No copies; only moves.
PalettizedImage(const RGBPalette &pal, const RGBImage &img)
Build a palettized version of RGBIMG.
PalettizedImage(const RGBPalette &pal, unsigned w, unsigned h)
Create storage for an image with the given palette and dimensions.
void set(ImageCoordDim xc, ImageCoordDim yc) noexcept
Set the cursor to the given cell coords. Do not throw if outside.
const CompLevel * rgb(void) const noexcept
Return the three components in R-G-B order.
constexpr ImageCoordDim cellH(void) const noexcept
To get the tesselation in Y from any RasterCursor object.
std::string to_string(void) const
Return a multi-line description of the palette.
bool right(void) noexcept
Move the cursor one cell to the right (no row change).
ImageCoordDim xPixel(void) const noexcept
Return the X-pixel coordinate within current region.
void set(CompLevel r, CompLevel g, CompLevel b) noexcept
Change all components.
ImageCoordDim x(void) const noexcept
Return the X-cell coordinate within current region.
PalettizedImage(void)=default
Default constructor: emptied palettized image.
RasterCursor(ImageCoordDim wimage, ImageCoordDim himage)
Default constructor / position constructor for a given sized image.
bool inside(void) const noexcept
Return TRUE if the cursor is inside the current region of the image.
void setR(CompLevel r) noexcept
Change the red component.
Index closestColor(const RGBColor &col) const noexcept
Find the closest color in the palette to COL.
void reset(void) noexcept
Set the cursor to the top-left cell coords of the current region.
RasterImage(void)=default
Default constructor: undefined content.
ImageCoordDim yPixel(void) const noexcept
Return the Y-pixel coordinate within current region.
size_t globalOffset(void) const
Return the linear offset within the image corresponding to cursor.
void vector(const RGBColor &oth, double *rgbv) const noexcept
Fill RGBV with the three components of a vector going from THIS to OTH.
An image that stores pixel colors contiguously as palette indexes.
A RGB color with 8 bits per component.
A palette defining a number of RGB colors.
A cursor to access RasterImage pixels bi-linearly with certain tesselation.
A 2D matrix of certain type that has contiguous storage.
unsigned ImageCoordDim
Type for coordinates and dimensions of images.
uint8_t[3] ThreeBytes
Auxiliary type needed for RGBImage.
Collect diverse traits for the fixed integer type T.
#define RUNTIMEEXCEP(txt)
Raise a runtime exception with the given std::string TXT + additional info.
unsigned char bits_of_value(T v)
The same as bits_of_constexprvalue(v) but for any variable value.