The following is a common workflow for editing raster data.
- Initialize the stream handle.
Create a stream on the connection using the
SE_stream_create function.
Set up the stream insert or update operation.
Insert operations are performed with the SE_stream_insert_table function.
There are several functions for performing an
update operation, including SE_stream_update_table, SE_stream_set_row, and
SE_stream_update_row.
Which function you choose to use depends how you want to filter the rows of the
business table to be updated. There are three types of raster update operations:
- total replacement
- mosaic merge
- mosaic delete
Prepare the raster attribute.
The raster attribute, or more specifically, the
SE_RASTERATTR structure, maintains properties innate to the raster data. After
initializing the raster attribute structure with a call to the SE_rasterattr_create
function, the raster data properties can be set with calls to the suite of
SE_rasterattr_set functions. The following properties can be configured:
- Raster callback function and client
data structure
The name of the raster callback function must
be provided along with the address to the client data structure. The raster
callback function is called by the SE_stream_execute function. Its purpose is to
provide scanlines of pixel data.
The client data structure is defined by the application developer
and passes information from the SE_stream_execute execution environment to the raster callback function.
The SE_rasterattr_set_callback function sets the raster callback function name
and the address to the client data structure on the SE_RASTERATTR structure.
The raster callback function is integral to the modification of ArcSDE pixel data.
The name of the raster callback function is passed to the SE_stream_execute function as part of the raster attribute.
It is called internally to process and read the pixel data from a source and feed it to ArcSDE as part of an insert or update operation.
- Color map
If the raster has a color map, use the SE_rasterattr_set_colormap function to set the color map properties on the
SE_RASTERATTR structure. The default to no colormap or SE_COLORMAP_NONE.
- Compression
The SE_rasterattr_set_compression function sets the compression properties on the SE_RASTERATTR structure. The default
compression property is no compression or SE_COMPRESSION_NONE. The possible
compression types are the lossless compression LZ77, and the lossy compressions
JPEG and JPEG2000. The type of compression is set with the
SE_rasterattr_set_compression_type function. Use
the SE_rasterattr_set_compression_property function to set the compression quality
of the JPEG and JPEG200 lossy compression types.
Note that the JPEG compression type can only
be used on 8-bit raster data that does not have a color map. The JPEG2000
compress type can be used on 8-bit and 16-bit raster data that does not have a
color map.
- Extent
The SE_rasterattr_set_extent function sets
the extent of the raster. For ArcSDE, the pixel cell alignment occurs at the
center of the pixel. This property must be defined, as there cannot be a default
extent.
- Pyramid origin
The pyramid origin is defined only for insert
and update replacement operations. It cannot be set for mosaic merge or mosaic
delete operations. It defaults to the minimum x- and maximum y-coordinate of the
extent. The pyramid origin must be aligned with the pixel cells defined by the
raster extent to the 14th degree of precision.
Setting the pyramid origin avoids costly
pyramid rebuilds that occur during a future mosaic operation that expands the
extent to the west or north of the existing extent. Shifting the extent in
either of these directions requires also shifts the pyramid origin if it was
defined by default on the minimum X and maximum Y coordinate. To shift the
pyramid origin, ArcSDE must rebuild the pyramid.
You can avoid the need to set the pyramid
origin, if do not build the pyramid before mosaicking all of your source
imagery. Therefore the pyramid origin is only necessary, if you intend to mosaic
pixel data to the west or to the north of a raster’s existing pyramid origin on
a raster with a pyramid.
The pyramid origin is set on the SE_RASTERATTR structure with the SE_rasterattr_set_origin function.
- Raster dimensions
The pixel width and its height as well as the
number of bands define the raster dimensions. The raster dimensions are set on
the SE_RASTERATTR structure with the SE_rasterattr_set_image_size function.
There is no default for this properties; it must be set.
- Interleave type
The interleave property determines how the raster bands will be stored. The two possible types of interleave are band
sequential and interleave by pixel. For the band sequential format, each band is
stored in its own tile. With interleave by pixel format, the pixels of the
bands are interleaved and stored in a single tile. The interleave by pixel
format is only supported for 8-bit three band data. The interleave type defaults
to band sequential.
Use the SE_rasterattr_set_interleave function
to set the interleave type on the SE_RASTERATTR structure.
- Nodata bitmask mode
The nodata bitmask mode is a Boolean. When set to TRUE, a nodata bitmask buffer must accompany the buffer scan lines of
pixel data that the raster callback function provides when it is called by
SE_stream_execute function. When set to FALSE, the nodata bitmask does not need
to be provided and is ignored if it is. The SE_rasterattr_set_mask_mode function
is called to set the nodata bitmask mode on the SE_RASTERATTR structure. If the
function is not called, the default mode is FALSE.
- Pixel type
Currently, ten types of pixel data are
supported and are listed as follows:
- 1 bit
- 4 bit
- 8-bit unsigned
- 8-bit signed
- 16-bit unsigned
- 16-bit signed
- 32-bit unsigned
- 32-bit signed
- 32-bit real
- 64-bit real
The pixel type is set on the SE_RASTERATTR
structure with the SE_rasterattr_set_pixel_type function. There is no default
value; this property must be defined.
- Pyramid
The pyramid properties are set on the
SE_RASTERATTR structure with the SE_rasterattr_set_pyramid_property function. Defaults to no pyramid or
SE_INTERPOLATION_NONE and maximum level 0.
- Tile dimensions
There is no default value for this; this attribute must be
defined.
- Bind the raster attribute to the stream.
Call the SE_stream_bind_input_column to bind the raster attribute to the stream.
- Prepare the client data.
During the preparation of the raster attribute in step 3,
the SE_rasterattr_set_callback function was called to set the name
of the raster callback function and address of the client data structure.
The client data structure holds information that must be passed
to the raster callback function.
The definition of the raster callback function must adhere to the following definition:
- It must return a long integer.
- It can have any legal name.
- It must have five arguments. These are the arguments:
LONG <callback function name>
(void * <client data argument name>,
void ** <buffer argument name>,
LONG * <buffer length argument name>,
void ** <bitmask buffer argument name>,
LONG * <bitmask buffer length argument name>);
The names of the arguments are defined by the developer, but they follow
these rules:
- The first argument, a void pointer to the client data, is a developer-defined structure used to pass information
into the callback function. Any buffers within this structure must be allocated prior to calling the SE_stream_execute function,
which in turn will call the raster callback function.
- The second argument is the data buffer, a void pointer to point to an array of pixels that is returned to the SE_stream_executed function.
The callback function will allocate the buffer and populate the pixel array, or point to a preallocated buffer of pixels.
Upon returning execution to the SE_stream_execute function, the buffer must contain either a scanline of pixels, multiple complete scanlines,
or a null pointer.
- The length argument is the allocated length of the pixel array. The SE_stream_execute function is
expecting it to be the allocated length of a scanline of pixels, multiple scanlines, or 0. Returning a 0
as the length indicates there is no more data to be processed, and the SE_stream_execute function
should terminate calls to the raster callback function.
- The bitmask buffer is the fourth argument. It is defined as a void pointer to point to the bitmask array.
If the nodata bitmask has been enabled, the SE_stream_execute function will process the bitmask; otherwise,
it will ignore it. The bitmask maps to the pixels returned in the second argument and its allocated size must be correct
to avoid memory overwrites within the SE_stream_execute function.
- The final argument is the length of the bitmask buffer that is set
in the raster callback function and returned to SE_stream_execute.
The following is a C API example of the previous steps:
/* Add the callback function to
the SE_RASTERATTR structure. */
/* The callback function determines how SE_stream_execute will */
/* enter the image pixel data into the raster column. */
rc = SE_rasterattr_set_callback (
raster_attrib,
(SE_RASTER_PROC) raster_attribute_callback,
(void
*) client_data);
check_error (rc,
NULL, NULL, "SE_rasterattr_set_callback");
prepare_client_data
void prepare_client_data (CLIENT_DATA *client_data,
LONG pixel_type,
LONG pixelwidth,
CHAR *filename)e)e)
{
LONG bits_per_pixel, bufferbytes, bitmaskbytes;
CHAR *bsqfilename;
/* Set the number of bits each pixel will contain. In this case 8. */
bits_per_pixel = SE_PIXEL_TYPE_GET_DEPTH (pixel_type);
/* Number of bytes per scanline. In this case 256 bytes. */
bufferbytes = (pixelwidth * bits_per_pixel + 7) / 8;
/* Number of bytes in the bitmask */
bitmaskbytes = (pixelwidth + 7) / 8;
/* Populate the CLIENT_DATA structure. This structure is passed between */
/* the SE_stream_execute function and the
raster attribute callback function.*/
/* Allocate the data buffer */
client_data->buffer = (CHAR *) calloc (bufferbytes, sizeof(CHAR));
/* Set the data buffer length. In this case the data buffer length is */
/* set to a single scanline, but since the raster being loaded is */
/* 8-bit, the length could have been set to a multiple of the scanline, */
/* even the entire image provided the memory resources are available. */
client_data->length = bufferbytes;
/* Allocate the nodata bitmap buffer */
client_data->bitmaskbuffer = (CHAR *) calloc (bitmaskbytes, sizeof(CHAR));
/* Set the bitmaskbuffer length */
client_data->bitmasklength = bitmaskbytes;
/* Set the file descriptor on the BSQ image file opened for read-only */
/* access, from which the pixel values will be read in band sequential */
/* order. The file will be read by the callback function, which will be */
/* called iteratively by SE_stream_execute, until the image file is */
/* exhausted. SE_stream_execute will insert the pixels of the image */
/* into the SDE_BLK_<N> table. */
/* create the BSQ filename */
bsqfilename = (CHAR *) malloc (sizeof(CHAR) * (strlen(filename) + 5));
sprintf(bsqfilename,"%s.bsq",filename);
client_data->fd = fopen (bsqfilename, "rb");
/* Release the bsqfilename */
free(bsqfilename);
return;
}
Read a scanline, multiple scanlines, or the entire image file into the buffer. The scanline is the atomic
graduation of pixel data the SE_stream_execute function will accept. For 1-bit
and 4-bit pixel depths, the SE_stream_execute function can accept a single
scanline. For pixel depths greater than 4-bit, the call back function can submit
multiple scanlines to SE_stream_execute.
/* prepare_client_data */
LONG raster_attribute_callback (void *client_data,
void
**buffer,
LONG *length,h,h,
void **
bitmask,
LONG * * * bitmask_length)
{
LONG
size;
CLIENT_DATA *ptr;
/*
Initialize the callback buffer and length */
*buffer =
NULL;
*length =
0;
ptr = (CLIENT_DATA
*) client_data;
/*
Initialize the client data buffer with zeros */
memset (ptr->buffer,
0, ptr->length);
/*
Initialize the client data bitmask to all ones */
memset (ptr->bitmaskbuffer,
255, ptr->bitmasklength);
/* read
data from the source to the callback buffer. */
size =
fread (ptr->buffer, sizeof(CHAR), ptr->length,
ptr->fd);
/* Test
for file read error */
if (ferror(ptr->fd)) {
printf("An error has occurred reading the bsq
file.\n");
printf("The file i/o error was %d.\n",ferror(ptr->fd));
}
/* Set the data buffer
and the length before returning to */
/* SE_stream_execute
*/
*buffer =
ptr->buffer;
*length =
size;
*bitmask
= ptr->bitmaskbuffer;
*bitmask_length
= ptr->bitmasklength;
return (SE_SUCCESS);
}
/* raster_attribute_callback */
|