/* Copyright 2000, Atlantic Aerospace Electronics Corp */ /* * Name: initializeImage * Input: dimension dimension of image * maxImageValue max legal image value * numberLines number line segments for image * minThickness min thickness for line segment * maxThickness max thickness for line segment * Output: image image initialized * Comment: This routine allocates memory to store an image and fills * in the image structure except for the image data. The * pixels of the image are of type ShortInt. If there * is an error allocating memory, than a NULL pointer is * returned. Assumptions: the image dimensions given are * positive. * Calls: errorMessage() * (system) malloc() * free() * Return: image structure pointer (partially filled in - no data - * and allocated) * NULL (error allocating memory for image/image structure) * * Revision History: * Date Name Revision * --------- ----------- ----------------------------- * 25May2000 May Leung Created * 05Jun2000 May Leung Add maxImageValue as input to initializeImage() * XXMay2020 Joshua Bakita Commented out significant portions to allow this to * be #include(d) elsewhere. */ typedef int Int; typedef short int ShortInt; typedef float Float; void drawRowPoint (Int value, Int pointThickness, Int row, Int column, Image *image); void drawColumnPoint (Int value, Int pointThickness, Int row, Int column, Image *image); #define MIN_RANDOM_VALUE 0 #if 0 #ifndef NDEBUG #include #endif /* NDEBUG */ #include /* define assert() */ #include /* define NULL, malloc(), free() */ #include "stressmark.h" /* system include file */ #include "neighborhood.h" /* define types, structures, etc */ #include "errorMessage.h" /* define errorMessage() */ #include "random.h" /* define randomUInt() */ #include "initializeImage.h" /* define initializeImage() */ Image *initializeImage (Int dimension, /* dimension of image */ Int maxImageValue, /* max legal image value */ Int numberLines, /* number line segments for image */ Int minThickness, /* min thickness for line segment */ Int maxThickness) /* max thickness for line segment */ { /* beginning of initializeImage() */ Image *image; /* pointer to image structure to allocate */ ShortInt *data; /* pointer to the data for the image structure*/ Int lineIndex; /* loop index variable for line segments */ Int pixelIndex; /* loop index variable for pixels */ Int limit; /* limit for loop using pixelIndex */ Coord startPoint; /* starting point for a line segment */ Coord endPoint; /* ending point for a line segment */ Int lineThickness; /* thickness for a line segment */ Int startValue; /* starting value for a line segment */ Int endValue; /* ending value for a line segment */ /* * Assert the assumptions that the number of columns and number of rows * are positive values. No test on the maximum possible value is done since * numColumns and numRows are of type Int and the maximum value of an Int * type is possible. */ assert(dimension > 0); assert(numberLines > 0); assert((minThickness > 0) && (minThickness < dimension)); assert((maxThickness > 0) && (maxThickness < dimension)); assert(minThickness <= maxThickness); /* create image */ image = createImage(dimension,dimension,maxImageValue); if (image == NULL) { return(NULL); } /* end error check from createImage */ /* zero out the image */ limit = dimension * dimension; data = image->data; for (pixelIndex = 0; pixelIndex < limit; pixelIndex++) { *data++ = 0; } /* end for loop */ /* * Populate the image with line segments where the endpoints, values, and * thickness of each line segment are randomly generated. */ for (lineIndex = 0; lineIndex < numberLines; lineIndex++) { randomImageLocation(image, &startPoint); randomImageLocation(image, &endPoint); lineThickness = randomUInt(minThickness,maxThickness); startValue = randomUInt(MIN_RANDOM_VALUE, maxImageValue); endValue = randomUInt(MIN_RANDOM_VALUE, maxImageValue); /* add line segment to the image */ drawLineSegment(&startPoint, &endPoint, startValue, endValue, lineThickness, image); } /* end for loop */ return(image); } /* end initializeImage() */ #endif /* * drawLineSegment() This routine draws a line segment into the given image * starting at the coordinate startPoint and ending at the * coordinate endPoint. The values along this line segment * vary linearly from the given starting value startValue to * the end value endValue and have a lineThickness associated * to it. * * This routine is modeled after the routine draw_line() from * "Practical Computer Vision using C", by J.R. Parker, Wiley, 1994, pp 114-116. * It has been enhanced to have values on the line segment vary and to have * a thickness to the line segment. */ void drawLineSegment (Coord *startPoint, /* starting point for line segment */ Coord *endPoint, /* ending point for line segment */ Int startValue, /* starting value for line segment */ Int endValue, /* ending value for line segment */ Int lineThickness, /* thickness for line segment */ Image *image) /* image to add line segment to */ { /* beginning of drawLineSegment() */ /* * Modeled after draw_line() from "Practical Computer Vision using C", * by J.R. Parker, Wiley, 1994, pp 114-116. Enhanced to have values * on the line segment vary and to have a thickness to the line segment. * The value along the line segment is kept in a float variable so that * fractional increments along the line segment can accumulate to integer * values. */ Int changeColumn, changeRow; /* change along line segment in col/row */ Int absColumn, absRow; /* absolute value of change in col/row */ Int signColumn, signRow; /* sign of change along line segment col/row */ Int delta; /* increment alone line segment */ Int column, row; /* column & row of coordinate along line seg */ Float value, valueDelta; /* value & value change along line segment */ // assert(validImage(image)); assert(startPoint != NULL); assert(endPoint != NULL); #ifdef DEBUG0 fprintf(stderr, "drawLineSegment: start row %6ld col %6ld\tend row %6ld col %6ld\n", startPoint->row,startPoint->column,endPoint->row,endPoint->column); fprintf(stderr," startVal %6ld endVal %6ld thickness %6ld\n", startValue, endValue, lineThickness); #endif /* DEBUG0 */ changeColumn = endPoint->column - startPoint->column; if (changeColumn < 0) { absColumn = - changeColumn; signColumn = - 1; } /* end changeColumn < 0 */ else { /* changeColumn >= 0 */ absColumn = changeColumn; signColumn = 1; } /* end changeColumn >= 0 */ absColumn *= 2; changeRow = endPoint->row - startPoint->row; if (changeRow < 0) { absRow = - changeRow; signRow = - 1; } /* end changeRow < 0 */ else { /* changeRow >= 0 */ absRow = changeRow; signRow = 1; } /* end changeRow >= 0 */ absRow *= 2; column = startPoint->column; row = startPoint->row; value = startValue; /* add changing value to algorithm */ if (signColumn * changeColumn > signRow * changeRow) { /* column dominant */ /* determine the change in value for each step (added to algorithm) */ valueDelta = ((Float) endValue - startValue) / ((Float) changeColumn * signColumn); delta = absRow - (absColumn / 2); while (TRUE) { /* inifinite loop */ /* * Line is column dominant, so line thickness will be along rows. Make * sure the ending value doesn't go beyond endValue. (Added to algorithm) */ drawRowPoint((Int) value, lineThickness, row, column, image); if (valueDelta >=0) { value = MIN(endValue, value+valueDelta); } /* values are incrementing */ else { /* valueDelta < 0 */ value = MAX(endValue, value+valueDelta); } /* values are decreasing */ if (column == endPoint->column) { return; /* done with line segment exit routine */ } /* end exit criteria */ if (delta >= 0) { row += signRow; delta -= absColumn; } /* end if delta >= 0 */ column += signColumn; delta += absRow; } /* end while infinite loop */ } /* end row dominant case */ else { /* row dominant case */ /* determine the change in value for each step (added to algorithm) */ if (changeRow == 0) { valueDelta = 0; assert(changeColumn == 0); } /* end if changeRow == 0 */ else { valueDelta = ((Float) endValue - startValue) / ((Float) changeRow * signRow); } /* end else */ delta = absColumn - (absRow / 2); while (TRUE) { /* inifinite loop */ /* * Line is row dominant, so line thickness will be along columns. Make * sure the ending value doesn't go beyond endValue. (Added to algorithm) */ drawColumnPoint((Int) value, lineThickness, row, column, image); if (valueDelta >=0) { value = MIN(endValue, value+valueDelta); } /* values are incrementing */ else { /* valueDelta < 0 */ value = MAX(endValue, value+valueDelta); } /* values are decreasing */ if (row == endPoint->row) { return; /* done with line segment exit routine */ } /* end exit criteria */ if (delta >= 0) { column += signColumn; delta -= absRow; } /* end if delta >= 0 */ row += signRow; delta += absColumn; } /* end while infinite loop */ } /* end column dominant case */ return; } /* end of drawLineSegment() */ /* * drawRowPoint() This routine draws a point with a row thickness onto the * given image for the coordinate and value provided. */ void drawRowPoint (Int value, /* value for point */ Int pointThickness, /* thickness for point */ Int row, /* row coordinate of point */ Int column, /* column coordinate of point */ Image *image) /* image to draw point onto */ { /* beginning of drawRowPoint() */ Int halfThickness; /* half the point thickness */ Int lowerRow, upperRow, rowIndex; /* loop boundaries and index for row */ ShortInt *data; /* image data pointer */ // assert(validImage(image)); assert(value >= MIN_RANDOM_VALUE); assert(value <= image->maxImageValue); assert(pointThickness > 0); #ifdef DEBUG0 fprintf(stderr, "drawRowPoint: value %5ld, thickness %6ld, row %6ld, column %6ld\n", value,pointThickness,row,column); #endif /* DEBUG0 */ halfThickness = (Int) pointThickness / 2; /* use integer division */ lowerRow = MAX(0, row - halfThickness); upperRow = MIN(image->numRows, row + pointThickness - halfThickness); data = image->data + (lowerRow * image->numColumns) + column; for (rowIndex = lowerRow; rowIndex < upperRow; rowIndex++) { *data = (ShortInt) value; data += image->numColumns; /* increment pointer to next row */ } /* end for loop */ return; } /* end of drawRowPoint() */ /* * drawColumnPoint() This routine draws a point with a column thickness onto the * given image for the coordinate and value provided. */ void drawColumnPoint (Int value, /* value for point */ Int pointThickness, /* thickness for point */ Int row, /* row coordinate of point */ Int column, /* column coordinate of point */ Image *image) /* image to draw point onto */ { /* beginning of drawColumnPoint() */ Int halfThickness; /* half the point thickness */ Int leftColumn, rightColumn, columnIndex; /* col loop boundaries&index*/ ShortInt *data; /* image data pointer */ // assert(validImage(image)); assert(value >= MIN_RANDOM_VALUE); assert(value <= image->maxImageValue); assert(pointThickness > 0); #ifdef DEBUG0 fprintf(stderr, "drawColumnPoint: value %5ld, thickness %6ld, row %6ld, column %6ld\n", value,pointThickness,row,column); #endif /* DEBUG0 */ halfThickness = (Int) pointThickness / 2; /* use integer division */ leftColumn = MAX(0, column - halfThickness); rightColumn = MIN(image->numColumns, column + pointThickness - halfThickness); data = image->data + (row * image->numColumns) + leftColumn; for (columnIndex = leftColumn; columnIndex < rightColumn; columnIndex++) { *data = (ShortInt) value; data++; /* increment pointer to next column */ } /* end for loop */ return; } /* end of drawColumnPoint() */ /* * randomImageLocation() This routine generates a random coordinate yielding a * coordinate in the given image using randomUInt(). */ #if 0 #include "random.h" void randomImageLocation (Image *image, /* image in question */ Coord *location) /* random location generated */ { /* beginning of randomImageLocation() */ Int index; /* random location in image */ Int maxIndex; /* maximum index in image */ assert(validImage(image)); assert(location != NULL); maxIndex = image->numColumns * image->numRows - 1; index = randomUInt(0, maxIndex); /* use integer division to clip to closest integer value */ location->row = (Int) index / image->numColumns; location->column = index - (location->row * image->numColumns); assert((location->row >= 0) && (location->row < image->numRows)); assert((location->column >= 0) && (location->column < image->numColumns)); assert(index = location->column + (location->row * image->numColumns)); return; } /* end of randomImageLocation() */ #endif