Giter Club home page Giter Club logo

Comments (6)

guzba avatar guzba commented on June 9, 2024

Yes that does cause some trouble sadly. I tries this out myself and here is what I ran into:

The image[x, y] accessor is a safe way to access image data that returns rgbx(0, 0, 0, 0) if you attempt to read outside the bounds of the image.

We must check if image.inside(x, y) first, not just assert as shown in your example. Further, asserts are not run in release so we'd need doAssert. But the point is to not crash and just get transparent black, so asserts are not an option.

Since we need to branch and cannot guarantee we have an addressable heap memory thing to return a pointer to (var type), we cannot return a var ColorRGBX.

If you want to swap I suggest using swap image.data[image.dataIndex(x, y)], image.data[image.dataIndex(x, y)] and accept your program will crash if you attempt to swap out of bounds.

from pixie.

demotomohiro avatar demotomohiro commented on June 9, 2024

Thank you for your reply.

So image[x, y] works differently from seq[T] when it got out of bound coordinate.
myseq[idx] always raise exception when idx is out of bound unless -d:danger is set.
But image[x, y] returns transparent black, and image[x, y] = v does nothing instead of raising an exception.
And there is no way to image[x, y] returns var ColorRGBX safely in that case.

Adding new procedure that raises exception in the same way as myseq[idx] allows returning var ColorRGBX safely.
And I can add it to my code.

import std/strformat
import pixie

proc `{}`(image: var Image, x, y: int): var ColorRGBX {.inline.} =
  ## Accessing any pixels outside the bounds of the image is error
  when not defined(danger):
    if not image.inside(x, y):
      raise newException(IndexDefect, &"({x}, {y}) not in range ({image.width - 1}, {image.height - 1})")

  image.unsafe[x, y]

var image = newImage(10, 10)
image[0, 0] = rgba(0, 255, 255, 255)
image[0, 1] = rgba(255, 255, 0, 255)
swap(image{0, 0}, image{0, 1})
doAssert image[0, 0] == rgba(255, 255, 0, 255)
doAssert image[0, 1] == rgba(0, 255, 255, 255)
doAssertRaises(IndexDefect):
  echo image{11, 0}

from pixie.

guzba avatar guzba commented on June 9, 2024

This is sort of true. You should be careful about the exception from seq[] though / IndexDefect. They are not considered catchable.

IndexDefect is a Defect and Defects are "Abstract base class for all exceptions that Nim's runtime raises but that are strictly uncatchable as they can also be mapped to a quit / trap / exit operation."

So counting on seq[] access exceptions to manage your control flow (using try catch) could be troublesome.

from pixie.

guzba avatar guzba commented on June 9, 2024

I have another suggestion and change we can make here:

It should work to use:

swap image.unsafe[x, y], image.unsafe[x + 1,y]

To enable this we can make image.unsafe[x, y] return a var ColorRGBX since it will segfault if you ask for something out of bounds.

from pixie.

guzba avatar guzba commented on June 9, 2024

I guess as templates they already work / the var or not part of the return doesnt matter.

from pixie.

demotomohiro avatar demotomohiro commented on June 9, 2024

When we use seq[T], we avoid accessing it with out of bounds index.
But when we accidentally access it with out of bound index, it is a bug need to be fixed.
If seq[T] returns default(T) instead of raising IndexDefect, it is hard to find the bug.

There are cases you want image[x, y] returns transparent black when x and/or y are outside the bounds of the image.
But when you write code so that x and y are always inside the bound of the image, bound check helps to find the bug.

swap(image.unsafe[0, 0], image.unsafe[0, 1]) works.
But there is only bound check in Image.data.
It doesn't check for x >= image.width.

import std/strformat
import pixie

var image = newImage(10, 10)
image[0, 0] = rgba(0, 255, 255, 255)
image[0, 1] = rgba(255, 255, 0, 255)
swap(image.unsafe[0, 0], image.unsafe[0, 1])
doAssert image[0, 0] == rgba(255, 255, 0, 255)
doAssert image[0, 1] == rgba(0, 255, 255, 255)
doAssertRaises(IndexDefect):
  echo image.unsafe[10, 10]
# This assert fails because IndexDefect is not raised.
# doAssertRaises(IndexDefect):
#   echo image.unsafe[11, 0]

from pixie.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.