<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.2900.2963" name=GENERATOR></HEAD>
<BODY>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>Over the past 
several months, I've seen a number of postings regarding support in PostGIS for 
raster data.&nbsp; The email threads tend to look like this:</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006>---</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>Poster: 
</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>I'd like to have 
support for raster data in PostGIS.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006>Responder:&nbsp;&nbsp;&nbsp;</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>If you are just 
going to put the whole image in the database, then take the complete image back 
out, what's the point.&nbsp; Why do you think storing in the RDB would be better 
than managing raster data in files?</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006>Poster:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>I would not have to 
manage the interactions between the RDB and a file-based database, the images 
would follow transactional semantics, and the raster data would be network 
accessible.&nbsp; Additionally, I could use PostGIS spatial queries&nbsp;to 
relate&nbsp;vector data to&nbsp;raster data, and maybe even write some 
additional raster manipulation functions, all of which would be built into the 
database.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006>Responder:</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>That stuff sounds 
neat, but the performance issues are unworkable.&nbsp; Performance with large 
images will be terrible if we use anything other than flat 
files.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006>---</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>Generally, the 
debate ends here.&nbsp; This time I'd like to see if the conversation could go 
in another direction.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>I think the "what's 
the point" response is basically valid for a naive implementation of images 
within a RDB.&nbsp; If you are going to treat an image as a blob that can be 
extracted only in the same form that it was inserted, there is really not much 
point in using relational storage.&nbsp; The raster data will need to be read 
into program memory buffers in one big chunk.&nbsp; For large images, the 
data&nbsp;will likely need to be&nbsp;written into a temporary file so it can be 
incrementally processed using file seeks.&nbsp; In this case, you'd be better 
off having the data in a file in the first place.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>However, if you 
support multiple modes of extraction, then the relational model really starts to 
become compelling.&nbsp; For example, I could see extracting an image that is a 
subsector of&nbsp;the complete image (i.e. a smaller image that&nbsp;covers 
a&nbsp;smaller geographic region).&nbsp; One could also imagine extracting a 
low-resolution version of the image for "zoomed-out" display.&nbsp; Low-res 
images would cover the same geographic area, but with fewer pixels, so less 
processing for applications.&nbsp; By extracting image subsets, large image 
processing could be done straight from the database, without bloating 
application memory or using an&nbsp;intermediate temporary 
file.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>The ability to do 
both resolution and sector types of subsetting&nbsp;are well-supported by the 
JPEG2000 image format.&nbsp; In fact, these types of operations were some of the 
drivers behind the JPEG2000 design.&nbsp; Given that JPEG2000 compresses well 
and is an open standard, it seems like a good format for storing&nbsp;raster 
data.&nbsp; So is there some way to store JPEG2000 data in an intelligent way 
within a relational database?</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>Essentially, I think 
you could store JPEG2000 in a database by defining a new data type (e.g. 
pgraster) that could hold the image data in JPEG2000 format.&nbsp; The data type 
might also populate some derived data when the object is written by 
interpreting&nbsp;the JPEG2000, such as a PostGIS GEOMETRY object to represent 
the bounding box of the raster.&nbsp; This derived data would allow more optimal 
responses to spatial queries, but overall would not be mandatory to the 
implementation.&nbsp; However, it&nbsp;would&nbsp;be mandatory&nbsp;to define a 
set of SQL functions that take a pgraster argument&nbsp;to allow one to extract 
different subsets of&nbsp;the JPEG2000&nbsp;data.&nbsp; </SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>In terms of 
implementation, I think&nbsp;the pgraster implementation&nbsp;would require the 
following:</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>1. The underlying 
database storage would allow random access&nbsp;into the image 
data.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>2. A fairly 
sophisticated JPEG2000 codec would need to be linked into the database server, 
so that different subsets of the data could be accessed.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>3. The JPEG2000 
codec would need to be integrated with the RDB storage so that one could use 
standard codec functions with a RDB storage model.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>I think #1 could be 
achieved by making the pgraster type "toastable", and using a PostgreSQL TOAST 
table for the underlying storage.&nbsp; The data would not use TOAST 
compression, since the image should already be well-compressed.&nbsp; We could 
use the internal PostgreSQL function heap_tuple_untoast_attr_slice() to extract 
subsets of the toasted data, so we do not need to detoast the entire image 
during processing.&nbsp; Toast does not provide an API for a similar kind of 
seeking during writes, but I think it's the seeking on reads that will be the 
most significant to performance.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>I think #2 is 
potentially more problematic.&nbsp; The publicly available JPEG2000 codecs do 
not seem to have the interfaces needed for extraction of parts of a JPEG2000 
image.&nbsp; The JasPer library only provides the encode and decode functions 
that produce or accept a jas_image_t type; it doesn't have any of partial 
extraction capabilities.&nbsp; The Open JPEG codec is a bit tougher to get a 
handle on, but it also appears to only allow translation between an image type 
and&nbsp;a codestream.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>The code that really 
seems well-adapted to this problem is the Kakadu package written by David 
Taubman, one of the originators of JPEG 2000.&nbsp; Unfortunately, this library 
is not open source.&nbsp; Kakadu has been included as an optional component of 
other open source projects, like GDAL.&nbsp; However, I think&nbsp;Kakadu's 
license would come into conflict with the GPL used by PostGIS.&nbsp;&nbsp; I'm 
not a lawyer, but I&nbsp;think this conflict&nbsp;could be overcome if PostGIS 
could be release under dual licenses, such as GPL or LGPL.&nbsp; Whether or not 
its desirable to include of Kakadu in a PostGIS extension is another 
question.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>If anyone has 
knowledge of other JPEG 2000 codecs that have these low-level access 
capabilities, I'd be very happy to hear about them.&nbsp;&nbsp; Also, if I've 
mischaracterized any of the codecs, I'd love to be 
corrected.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>In any event, I'm 
curious to see if there is significant interest in an implementation of JPEG2000 
raster data type&nbsp;within PostGIS.&nbsp; If so, I think I could dedicate a 
significant amount of my time over the next several months, as well as perhaps 
some funding from my employer, depending upon whether some of the issues I 
raised above can be resolved.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2><SPAN class=807092918-24102006>Steve 
Marshall</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=807092918-24102006></SPAN></FONT>&nbsp;</DIV></BODY></HTML>