Home    |    Concepts   |   API   |   Samples
Concepts > Rasters > Basic Principles
Raster Editing Workflow

The following is a common workflow for editing raster data.

  1. Initialize the stream handle.
    Create a stream on the connection using the SE_stream_create function.
  2.  

  3. 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
  4.  

  5. 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.

     

  6. Bind the raster attribute to the stream.
    Call the SE_stream_bind_input_column to bind the raster attribute to the stream.
  7.  

  8. 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 */

feedback | privacy | legal