Skip to content

Commit

Permalink
"REBOOL Valid_Tuples()" => return TRUE or FALSE
Browse files Browse the repository at this point in the history
The Valid_Tuples routine in the image code said it returned a
REBOOL but actually was returning an integer.  Its confusing name
had it actually returning an index > 0 if there were invalid tuples... and
further it's not that the tuple is invalid, but that something that isn't
a tuple is in the list.

Further adding to the problems, the routine was enumerating from
the index of the block value it was holding up to the length *adjusted
with the index subtracted out*.  This is made more apparent by the
name VAL_LEN_AT (now distinct from VAL_LEN_HEAD).  As a
result it would not be checking the values fully from the index
forward, but fewer if the index was nonzero.

Adding further confusion to the mix, the passed back index was
used to add to the value of the block passed in, in one case...
as opposed to indexing within the block.  Hence an index of its
children was being used to index into its siblings.

The good news is that the new macro stylings make this much
clearer and easier to grasp.  The replacement function returns a
TRUE or FALSE, and is named "Array_Has_Non_Tuple".  The
index is an out parameter and is a zero-based child index.
  • Loading branch information
hostilefork committed Dec 15, 2015
1 parent 4e22d29 commit 25d8bda
Showing 1 changed file with 32 additions and 17 deletions.
49 changes: 32 additions & 17 deletions src/core/t-image.c
Expand Up @@ -260,19 +260,27 @@ void Bin_To_Alpha(REBYTE *rgba, REBCNT size, REBYTE *bin, REBINT len)


//
// Valid_Tuples: C
// Array_Has_Non_Tuple: C
//
REBFLG Valid_Tuples(REBVAL *blk)
// Checks the given ANY-ARRAY! REBVAL from its current index position to
// the end to see if any of its contents are not TUPLE!. If so, returns
// TRUE and `index_out` will contain the index position from the head of
// the array of the non-tuple. Otherwise returns FALSE.
//
REBOOL Array_Has_Non_Tuple(REBCNT *index_out, REBVAL *blk)
{
REBCNT n = VAL_INDEX(blk);
REBCNT len = VAL_LEN_AT(blk);
REBCNT len;

blk = VAL_ARRAY_AT(blk);
assert(ANY_ARRAY(blk));

for (; n < len; n++)
if (!IS_TUPLE(blk+n)) return n+1;
len = VAL_LEN_HEAD(blk);
*index_out = VAL_INDEX(blk);

return 0;
for (; *index_out < len; (*index_out)++)
if (!IS_TUPLE(VAL_ARRAY_AT_HEAD(blk, *index_out)))
return TRUE;

return FALSE;
}


Expand Down Expand Up @@ -479,7 +487,10 @@ REBVAL *Create_Image(REBVAL *block, REBVAL *val, REBCNT modes)
}
}
else if (IS_BLOCK(block)) {
if ((w = Valid_Tuples(block))) fail (Error_Invalid_Arg(block + w - 1));
REBCNT bad_index;
if (Array_Has_Non_Tuple(&bad_index, block))
fail (Error_Invalid_Arg(VAL_ARRAY_AT_HEAD(block, bad_index)));

Tuples_To_RGBA(ip, size, VAL_ARRAY_AT(block), VAL_LEN_AT(block));
}
else
Expand Down Expand Up @@ -510,7 +521,7 @@ REBVAL *Modify_Image(struct Reb_Call *call_, REBCNT action)
REBOOL only = 0; // /only
REBCNT index = VAL_INDEX(value);
REBCNT tail = VAL_LEN_HEAD(value);
REBINT n;
REBCNT n;
REBINT x;
REBINT w;
REBINT y;
Expand All @@ -529,8 +540,8 @@ REBVAL *Modify_Image(struct Reb_Call *call_, REBCNT action)
if (D_REF(5)) only = 1;

// Validate that block arg is all tuple values:
if (IS_BLOCK(arg) && (n = Valid_Tuples(arg)))
fail (Error_Invalid_Arg(VAL_ARRAY_AT_HEAD(arg, n-1)));
if (IS_BLOCK(arg) && Array_Has_Non_Tuple(&n, arg))
fail (Error_Invalid_Arg(VAL_ARRAY_AT_HEAD(arg, n)));

// Get the /dup refinement. It specifies fill size.
if (D_REF(6)) {
Expand Down Expand Up @@ -628,13 +639,17 @@ REBVAL *Modify_Image(struct Reb_Call *call_, REBCNT action)
if (index + dup > tail) dup = tail - index; // clip it
ip += index * 4;
if (IS_INTEGER(arg)) { // Alpha channel
n = VAL_INT32(arg);
if ((n < 0) || (n > 255)) fail (Error_Out_Of_Range(arg));
REBINT arg_int = VAL_INT32(arg);
if ((arg_int < 0) || (arg_int > 255))
fail (Error_Out_Of_Range(arg));
if (IS_PAIR(count)) // rectangular fill
Fill_Alpha_Rect((REBCNT *)ip, (REBYTE)n, w, dupx, dupy);
Fill_Alpha_Rect(
cast(REBCNT*, ip), cast(REBYTE, arg_int), w, dupx, dupy
);
else
Fill_Alpha_Line(ip, (REBYTE)n, dup);
} else if (IS_TUPLE(arg)) { // RGB
Fill_Alpha_Line(ip, cast(REBYTE, arg_int), dup);
}
else if (IS_TUPLE(arg)) { // RGB
if (IS_PAIR(count)) // rectangular fill
Fill_Rect((REBCNT *)ip, TO_PIXEL_TUPLE(arg), w, dupx, dupy, only);
else
Expand Down

0 comments on commit 25d8bda

Please sign in to comment.