ExtendScript's UnitValue - adobe

So I can't find, for the life of me, a clear breakdown of the components of ExtendScript's UnitValue object. Every source I found had something to do with Adobe, and didn't explain it. I'd really like to have a full reference on it, but if no one can find one, I need at least a few questions answered concerning it.
First, what are its constructors? I've seen UnitValue(10,'px') which makes sense, but I've also seen UnitValue(20,20)
Second, how can you convert from one unit to another?
Third, how can you find its value and its unit?
I think I've seen uv.value but nothing getting the unitsLastly, as my tags indicate, this is for Adobe, of course, since I've never seen or heard of any other program that uses ExtendScript.

UnitValue is documented in the Adobe JavaScript Tools Guide.
In particular, you create an object with v = new UnitValue(number, unit), where unit is a string value like in (inch), mm (millimeter), pt (point), px (pixel), etc.
To convert a UnitValue to an actual number, use the as method, e.g. v.as("cm") to convert v into centimeters.

Well, no one else seemed to know, and I finally figured some of it out, so I guess I'll answer it myself:
<This site> was a little helpful as a documentation, but I think Adobe functions slightly different from it.
UnitValue's main constructor is:
UnitValue(numericalvalue,unit)
I've also seen an alternative that accepts one string:
UnitValue("42 in")
For conversion, UnitValue comes with a handy as method which accepts the unit to convert to (as a string), and then returns its measurement in that unit, i.e.:
UnitValue(5,'ft').as('in') === 60
(Note, according to the reference I found, I believe the as method should return the UnitValue instance after being converted to the unit indicated; Adobe's implementation, however, seems to instead merely return the value - therefore I'm use the type-equality operator above to show Adobe's method)
For getting the numerical value and measurement unit, the following two properties exist:
UnitValue.value // number: the numerical value
UnitValue.type // string: the unit of measurement
This is all I could find by my research. If someone has a better answer, post it, and I may accept it.

What's really interesting to me is the baseValue property which allows us to change the frame of reference for the conversion. For instance:
var startUnit = UnitValue(500, "px");
startUnit.baseValue = UnitValue(1 / 72, "in"); // from what I can tell this is the default baseUnit value
$.writeln(v.as("in")); // returns 6.94444444444444 which is what 500px # 72 dpi is as expressed in inches
startUnit.baseValue = UnitValue(1 / 300, "in"); // set to 300dpi
$.writeln(v.as("in")); // returns 1.66666666666667 which is what 500px # 300 dpi is as expressed in inches
I think the default baseValue is always UnitValue(1/72, "in") even if the app.preferences.rulerUnits is set to any other type of measurement but I haven't really looked into it much

Related

How do I trim a slice and get the indices (indexes) of the result?

This seems like a simple problem:
let slice = " some wacky text. ";
let trimmed = slice.trim();
// how do I get the index of the start and end within the original slice?
Attempt 1
Look for an alternative API. trim wraps trim_matches which deals with indices internally anyway: so lets copy this code! But this uses std::str::pattern::Pattern which is unstable, thus can't be used outside std in stable Rust.
Attempt 2
Just use trim and calculate the slice indices from the pointers. There's a nice as_ptr_range method, but its also unstable; luckily as the PR says there's an easy work-around.
let slice_ptr = slice.as_ptr();
let trimmed_ptr = trimmed.as_ptr();
// don't bother about the end (we can use trimmed.len())
Now that we've got some pointers, we need their difference. sub is not the right method for this. offset_from is, but it's unstable (as noted in the design, it's only valid use is to compare two pointers into the same slice, which is exactly what we want to do, unfortunately it's yet another thing delayed by the details).
Now, there are hackier ways of solving this problem. We could transmute the pointers to usize (we know the element size is 1 byte, so no need to multiply). But this is most likely the Undefined Behaviour type of unsafe, so lets not go there.
Attempt 3
Edit: the source problem is easy to solve directly, so probably the answer in this case is roll-my-own. Possibly I should just close this.

Converting a Gray-Scale Array to a FloatingPoint-Array

I am trying to read a .tif-file in julia as a Floating Point Array. With the FileIO & ImageMagick-Package I am able to do this, but the Array that I get is of the Type Array{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2}.
I can convert this FixedPoint-Array to Float32-Array by multiplying it with 255 (because UInt8), but I am looking for a function to do this for any type of FixedPointNumber (i.e. reinterpret() or convert()).
using FileIO
# Load the tif
obj = load("test.tif");
typeof(obj)
# Convert to Float32-Array
objNew = real.(obj) .* 255
typeof(objNew)
The output is
julia> using FileIO
julia> obj = load("test.tif");
julia> typeof(obj)
Array{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2}
julia> objNew = real.(obj) .* 255;
julia> typeof(objNew)
Array{Float32,2}
I have been looking in the docs quite a while and have not found the function with which to convert a given FixedPoint-Array to a FloatingPont-Array without multiplying it with the maximum value of the Integer type.
Thanks for any help.
edit:
I made a small gist to see if the solution by Michael works, and it does. Thanks!
Note:I don't know why, but the real.(obj) .* 255-code does not work (see the gist).
Why not just Float32.()?
using ColorTypes
a = Gray.(convert.(Normed{UInt8,8}, rand(5,6)));
typeof(a)
#Array{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2}
Float32.(a)
The short answer is indeed the one given by Michael, just use Float32.(a) (for grayscale). Another alternative is channelview(a), which generally performs channel separation thus also stripping the color information from the array. In the latter case you won't get a Float32 array, because your image is stored with 8 bits per pixel, instead you'll get an N0f8 (= FixedPointNumbers.Normed{UInt8,8}). You can read about those numbers here.
Your instinct to multiply by 255 is natural, given how other image-processing frameworks work, but Julia has made some effort to be consistent about "meaning" in ways that are worth taking a moment to think about. For example, in another programming language just changing the numerical precision of an array:
img = uint8(255*rand(10, 10, 3)); % an 8-bit per color channel image
figure; image(img)
imgd = double(img); % convert to double-precision, but don't change the values
figure; image(imgd)
produces the following surprising result:
That second "all white" image represents saturation. In this other language, "5" means two completely different things depending on whether it's stored in memory as a UInt8 vs a Float64. I think it's fair to say that under any normal circumstances, a user of a numerical library would call this a bug, and a very serious one at that, yet somehow many of us have grown to accept this in the context of image processing.
These new types arise because in Julia we've gone to the effort to implement new numerical types (FixedPointNumbers) that act like fractional values (e.g., between 0 and 1) but are stored internally with the same bit pattern as the "corresponding" UInt8 (the one you get by multiplying by 255). This allows us to work with 8-bit data and yet allow values to always be interpreted on a consistent scale (0.0=black, 1.0=white).

Using strconv for negative hex values in Go

I've been building an assembler for no good reason the past day or so using Go so I can get familiar with the language. It's my first real program using Go so I expected problems, but I have a consistent bug coming up time and time again. I just figured out other hacky ways to fix it in other cases, but this time I think I need an answer so I feel like I'm actually doing this right.
Basically, I have to parse tons of byte values. Some of these are signed bytes so -1 = 0xFF and so on. When calculating the address of a label I need to find the offset of it from the current address. The following code is a stripped down basic version of what I use to get the offset:
// lbladdr holds the target label address
// address holds current address in memory
// label[x] holds the offset
if address > lbladdr {
lbladdr -= address
}
label[x] = strconv.FormatInt(int64(lbladdr), 16)
This works for positive values, but when I get a negative address (address > lbladdr) then instead of getting a value like FE I get -2. I don't get why the standard library would append a negative sign to a hex number and I haven't been able to find anything in the documentation about it. I've looked a lot of other places but I can't seem to find anyone with the same problem either.
I hope it's just something on my end that is a simple fix.
It's perfectly reasonable to use a negative sign on hexadecimal numbers. I know that when working with assembly it's common to use the actual bitpattern for the register you are representing in hex to represent the signs. However Go doesn't know you are doing that. Neither is go's formatting function written to support hex values as they would be in a CPU register. Further the bitpatterns will differ depending on the register size (16 vs 32 vs 64 and big vs little endian). you would be storing them in. So the base isn't enough to print them the way you want. You will need to write your own formatting lib that supports formatting for the type of Register you want to represent.
It's by design: http://golang.org/src/pkg/strconv/itoa.go?s=628:668#L8
What you may want is to cast to uint64:
package main
import (
"fmt"
"strconv"
)
func main() {
i := -1
fmt.Printf("%x\n", uint64(i))
fmt.Println(strconv.FormatUint(uint64(i), 16))
}

'Rational' token in Javacc

How does one create a 'Rational' token in javacc that takes a rational number and calculates its value. Foe example '2/5' value =0.4. I know how to write a regex for this, but don't know, and have never been properly taught, how to/where to incorporate java methods in javacc code. I have been advised that:
Note that rational numbers with 0 denominator are undefined. Instead of generating an error,
print infinity, as shown above.
Advice: You can use the indexOf and substring methods from the Java String class in order
to extract the numerator and denominator parts of your rational number. It’s a good idea to
define a second variable (e.g. val2) in order store the value of your denominator. Also, cast
the result of the division to double i.e. (double) val / val2.
Bear in mind that I'm new to javacc, but have a basic knowledge of java. Any advice on this matter will be greatly appreciated. Many thanks.
If there aren't problems related to choice points inside your grammar you can use the following syntax:
JAVACODE
void parse_rational() {
Token num, den;
num = getToken(1); // first value
getNextToken(); // trash fract symbol
den = getToken(1); // second value
/* do whatever you want */
}
But this approach makes JavaCC think about the "token" parse_rational as a black box, that's why using it in a choice (eg: S(): { parse_rational() | SomethingElse } it's not good.
I don't know if you need to write a full compiler or just a fraction parser, if the answer is the second this thing can work quite well..

How do I detect circular logic or recursion in a custom expression evaluator?

I've written an experimental function evaluator that allows me to bind simple functions together such that when the variables change, all functions that rely on those variables (and the functions that rely on those functions, etc.) are updated simultaneously. The way I do this is instead of evaluating the function immediately as it's entered in, I store the function. Only when an output value is requested to I evaluate the function, and I evaluate it each and every time an output value is requested.
For example:
pi = 3.14159
rad = 5
area = pi * rad * rad
perim = 2 * pi * rad
I define 'pi' and 'rad' as variables (well, functions that return a constant), and 'area' and 'perim' as functions. Any time either 'pi' or 'rad' change, I expect the results of 'area' and 'perim' to change in kind. Likewise, if there were any functions depending on 'area' or 'perim', the results of those would change as well.
This is all working as expected. The problem here is when the user introduces recursion - either accidental or intentional. There is no logic in my grammar - it's simply an evaluator - so I can't provide the user with a way to 'break out' of recursion. I'd like to prevent it from happening at all, which means I need a way to detect it and declare the offending input as invalid.
For example:
a = b
b = c
c = a
Right now evaluating the last line results in a StackOverflowException (while the first two lines evaluate to '0' - an undeclared variable/function is equal to 0). What I would like to do is detect the circular logic situation and forbid the user from inputing such a statement. I want to do this regardless of how deep the circular logic is hidden, but I have no idea how to go about doing so.
Behind the scenes, by the way, input strings are converted to tokens via a simple scanner, then to an abstract syntax tree via a hand-written recursive descent parser, then the AST is evaluated. The language is C#, but I'm not looking for a code solution - logic alone will be fine.
Note: this is a personal project I'm using to learn about how parsers and compilers work, so it's not mission critical - however the knowledge I take away from this I do plan to put to work in real life at some point. Any help you guys can provide would be appreciated greatly. =)
Edit: In case anyone's curious, this post on my blog describes why I'm trying to learn this, and what I'm getting out of it.
I've had a similar problem to this in the past.
My solution was to push variable names onto a stack as I recursed through the expressions to check syntax, and pop them as I exited a recursion level.
Before I pushed each variable name onto the stack, I would check if it was already there.
If it was, then this was a circular reference.
I was even able to display the names of the variables in the circular reference chain (as they would be on the stack and could be popped off in sequence until I reached the offending name).
EDIT: Of course, this was for single formulae... For your problem, a cyclic graph of variable assignments would be the better way to go.
A solution (probably not the best) is to create a dependency graph.
Each time a function is added or changed, the dependency graph is checked for cylces.
This can be cut short. Each time a function is added, or changed, flag it. If the evaluation results in a call to the function that is flagged, you have a cycle.
Example:
a = b
flag a
eval b (not found)
unflag a
b = c
flag b
eval c (not found)
unflag b
c = a
flag c
eval a
eval b
eval c (flagged) -> Cycle, discard change to c!
unflag c
In reply to the comment on answer two:
(Sorry, just messed up my openid creation so I'll have to get the old stuff linked later...)
If you switch "flag" for "push" and "unflag" for "pop", it's pretty much the same thing :)
The only advantage of using the stack is the ease of which you can provide detailed information on the cycle, no matter what the depth. (Useful for error messages :) )
Andrew

Resources