Index: setup.py
===================================================================
RCS file: /home/thuban/jail/thubanrepository/thuban/setup.py,v
retrieving revision 1.46
diff -r1.46 setup.py
1094,1096c1094
<                                 [ext_dir + "/thuban/gdalwarp.cpp",
<                                 ext_dir + "/thuban/cpl_mfile.cpp",
<                                 ext_dir + "/thuban/bmpdataset.cpp"],
---
>                                 [ext_dir + "/thuban/gdalwarp.cpp"],
Index: Thuban/UI/baserenderer.py
===================================================================
RCS file: /home/thuban/jail/thubanrepository/thuban/Thuban/UI/baserenderer.py,v
retrieving revision 1.13
diff -r1.13 baserenderer.py
78a79,85
> def proj_params_to_str(proj):
>     "Build a string suitable for GDAL describing the given projection"
>     str = ""
>     if proj is not None:
>         for p in proj.GetAllParameters():
>             str += "+" + p + " "
>     return str
180,195d186
<         # Whether the raster layer has already been drawn. See below for
<         # the optimization this is used for
<         seenRaster = True
< 
<         #
<         # This is only a good optimization if there is only one
<         # raster layer and the image covers the entire window (as
<         # it currently does). We note if there is a raster layer
<         # and only begin drawing layers once we have drawn it.
<         # That way we avoid drawing layers that won't be seen.
<         #
<         if Thuban.Model.resource.has_gdal_support():
<             for layer in self.map.Layers():
<                 if isinstance(layer, RasterLayer) and layer.Visible():
<                     seenRaster = False
<                     break
202,204c193,194
<                     if seenRaster:
<                         for i in self.draw_shape_layer_incrementally(layer):
<                             yield True
---
>                     for i in self.draw_shape_layer_incrementally(layer):
>                         yield True
208d197
<                     seenRaster = True
372a362
> 
465,469c455,456
<         in_proj = ""
<         proj = layer.GetProjection()
<         if proj is not None:
<             for p in proj.GetAllParameters():
<                 in_proj += "+" + p + " "
---
>         in_proj  = proj_params_to_str(layer.GetProjection())
>         out_proj = proj_params_to_str(self.map.GetProjection())
471,475c458,474
<         out_proj = ""
<         proj = self.map.GetProjection()
<         if proj is not None:
<             for p in proj.GetAllParameters():
<                 out_proj += "+" + p + " "
---
>         # True  -- warp the image to the size of the whole screen
>         # False -- only use the bound box of the layer (currently inaccurate)
>         if True: 
>             pmin = [0,height]
>             pmax = [width, 0]
>         else:
>             bb = layer.LatLongBoundingBox()
>             bb = [[[bb[0], bb[1]], [bb[2], bb[3]],],]
>             pmin, pmax = self.projected_points(layer, bb)[0]
> 
>         fmin = [max(0, pmin[0]) - offx, offy - min(height, pmin[1])]
>         fmax = [min(width, pmax[0]) - offx, offy - max(0, pmax[1])]
> 
>         xmin = fmin[0]/self.scale
>         ymin = fmin[1]/self.scale
>         xmax = fmax[0]/self.scale
>         ymax = fmax[1]/self.scale
477,480c476,477
<         xmin = (0 - offx) / self.scale
<         ymin = (offy - height) / self.scale
<         xmax = (width - offx) / self.scale
<         ymax = (offy - 0) / self.scale
---
>         width  = int(min(width,  round(fmax[0] - fmin[0] + 1)))
>         height = int(min(height, round(fmax[1] - fmin[1] + 1)))
483c480,481
<             data = ProjectRasterFile(layer.GetImageFilename(),
---
>             data = [width, height,
>                     ProjectRasterFile(layer.GetImageFilename(),
486a485
>                    ]
493c492,499
<             self.draw_raster_data(data, "BMP")
---
>             mask = "#030104"
>             mask = None
>             self.draw_raster_data(fmin[0]+offx, offy-fmax[1], data, "RAW", mask)
>             data = None
> 
>     def draw_raster_data(self, x, y, data, format="BMP", mask = None):
>         """Draw the raster image in data onto the DC with the top
>         left corner at (x,y)
495,500c501,502
<     def draw_raster_data(self, data, format="BMP"):
<         """Draw the raster image in data onto the DC
< 
<         The raster image data is a string holding the data in the format
<         indicated by the format parameter. The image is assumed to be
<         exactly the size of the dc and to cover it completely.
---
>         The raster image data is a list holding the image width, height,
>         and data in the format indicated by the format parameter. 
505,508c507,518
<           'BMP' -- Windows Bitmap
<           'JPEG' -- Jpeg
< 
<         The default format is 'bmp'.
---
>           'RAW'  -- an array of RGB values (len=3*width*height)
>           'BMP'  -- Windows Bitmap
>           'JPEG' -- JPEG Image
> 
>         The default format is 'BMP'.
> 
>         The mask parameter determines how a mask (if any) is applied
>         to the image. mask can have the following values:
>         
>           o  None -- no mask is used
>           o  Any object accepted by wxBitmap.SetMaskColour()
>           o  A one-bit image the same size as the image data
Index: Thuban/UI/renderer.py
===================================================================
RCS file: /home/thuban/jail/thubanrepository/thuban/Thuban/UI/renderer.py,v
retrieving revision 1.53
diff -r1.53 renderer.py
25c25,26
<     wxBITMAP_TYPE_JPEG, wxBITMAP_TYPE_PNG, wxBITMAP_TYPE_TIF, wxBITMAP_TYPE_GIF
---
>     wxBITMAP_TYPE_JPEG, wxBITMAP_TYPE_PNG, wxBITMAP_TYPE_TIF, \
>     wxBITMAP_TYPE_GIF, wxEmptyImage
40a42,45
> from math import floor
> 
> from types import StringType
> 
102,104c107,114
<     def draw_raster_data(self, data, format = 'BMP'):
<         stream = cStringIO.StringIO(data)
<         image = wxImageFromStream(stream, raster_format_map[format])
---
>     def draw_raster_data(self, x,y, data, format = 'BMP', mask = None):
>         if format == 'RAW':
>             image = wxEmptyImage(data[0], data[1])
>             image.SetData(data[2])
>         else:
>             stream = cStringIO.StringIO(data[2])
>             image = wxImageFromStream(stream, raster_format_map[format])
> 
106c116,127
<         self.dc.DrawBitmap(bitmap, 0, 0)
---
> 
>         if mask is None:
>             self.dc.DrawBitmap(bitmap, int(round(x)), int(round(y)), False)
>         else:
>             # if we are given a mask object, try to pass it to SetMaskColour,
>             # otherwise assume it's a mask image
>             try:
>                 bitmap.SetMaskColour(mask);
>                 self.dc.DrawBitmap(bitmap, int(round(x)), int(round(y)), True)
>             except (TypeError):
>                 # implement using a mask image
>                 raise NotImplementedError
Index: libraries/thuban/gdalwarp.cpp
===================================================================
RCS file: /home/thuban/jail/thubanrepository/thuban/libraries/thuban/gdalwarp.cpp,v
retrieving revision 1.1
diff -r1.1 gdalwarp.cpp
93a94,96
> #include <Python.h>
> 
> #include "gdal.h"
94a98
> #include "gdal_priv.h"
97,111d100
< #include "cpl_mfile.h"
< 
< CPL_C_START
< void CPL_DLL GDALRegister_THUBANBMP(void);
< CPL_C_END
< 
<                                                                                 
< /* MFILENAME takes the name of a variable to declare as being the
<  * "filename", and the address of a MFILEReceiver.
<  */
< #define MFILENAME(name, ptr) \
< char name[ 8 + 2 * sizeof( void* ) + 1]; \
< {snprintf( name, sizeof(name), "\3\1\4MFILE%0*x", 2*sizeof(void*), (int)(ptr)); \
<  memset( ptr, 0, sizeof( ptr ) );}
< 
113d101
< #include <Python.h>
119a108,110
> #define NO_DATA_VAL 255
> #define NO_DATA_VAL_STR "255"
> 
190a182,362
> /************************************************************************/
> /*                             GetImageData                             */
> /*                                                                      */ 
> /* Extract the image data from the GDALDataset and pack it into a single*/
> /* array of RGB triples. Use the ColorTable to determine the RGB        */
> /* values. We extract the data from the GDALDataset rather than create  */
> /* our own driver because the data needs to be translated from          */
> /* 4 byte pixel information into 3 byte RGB information. This could be  */
> /* done as the data is written to the data set or afterwards, as it is  */
> /* done here. Any minor savings from our own driver are outweighed by   */
> /* the high development/maintenance costs.                              */
> /*                                                                      */ 
> /* TODO:                                                                */
> /*                                                                      */ 
> /*  o Handle out of memory issues more cleanly than asserting           */ 
> /*  o Handle the case where there is no color table (is there a case?)  */ 
> /*                                                                      */ 
> /************************************************************************/
> 
> static CPLErr GetImageData(GDALDataset *ds, 
>                            unsigned char **imgbuf, unsigned int *imglen)
> {
>     CPLErr ret = CE_None;
> 
>     GDALColorEntry color;
>     GDALColorTable *pal = NULL;
> 
>     int nWordSize = 0;
> 
>     ds->FlushCache();
> 
>     int rasterCount  = ds->GetRasterCount();
>     int nRasterXSize = ds->GetRasterXSize();
>     int nRasterYSize = ds->GetRasterYSize();
>     if ( ! (nRasterXSize > 0 && nRasterYSize > 0 ))
>         return CE_Failure;
> 
>     //
>     // create the new image array for RGBRGB... values
>     //
>     *imglen = 3 * nRasterXSize * nRasterYSize;
>     *imgbuf = new unsigned char[*imglen];
>     if ( *imgbuf == NULL )
>         return CE_Failure;
> 
>     memset(*imgbuf, 170, *imglen);
> 
>     //
>     // if there are three bands assume for now that they are RGB bands
>     //
>     if (rasterCount == 3)
>     {
>         for (int i=1; i <= rasterCount; i++)
>         {
>             int offs = 0;
>             GDALRasterBand *band = ds->GetRasterBand(i);
> 
>             switch (band->GetColorInterpretation())
>             {
>                 case GCI_RedBand:   offs = 1; break;
>                 case GCI_GreenBand: offs = 2; break;
>                 case GCI_BlueBand:  offs = 3; break;
>                 default:            offs = i-1; break;
>             }
> 
>             //
>             // copy the image into the buffer using the proper offset
>             // so we first copy over all Red values, then all Green
>             // values, and then all Blue values
>             //
>             ret = band->RasterIO(GF_Read, 0, 0, 
>                                  nRasterXSize, nRasterYSize,
>                                  *imgbuf+offs, nRasterXSize, nRasterYSize, 
>                                  GDT_Byte, 3, 0);
>                     
>             if (ret == CE_Failure) break;
>         }
>     }
>     else if (rasterCount == 1)
>     {
>         //
>         // one band is either a palette based image, or greyscale
>         //
> 
>         GDALRasterBand *band = ds->GetRasterBand(1);
> 
>         switch (band->GetColorInterpretation())
>         {
>             case GCI_PaletteIndex:
> 
>                 pal = band->GetColorTable();
>                 // FIXME: what happens if pal is NULL? ignore?
>                 
>                 // test this once to see if conversion is supported. 
>                 if (pal && pal->GetColorEntryAsRGB(0, &color))
>                 {
>                     //
>                     // copy over all the palette indices and then
>                     // loop through the buffer replacing the values
>                     // with the correct RGB triples. 
>                     //
>                     ret = band->RasterIO(GF_Read, 0, 0, 
>                                          nRasterXSize, nRasterYSize,
>                                          *imgbuf, nRasterXSize, nRasterYSize, 
>                                          GDT_Byte, 3, 0);
>                             
>                     if (ret == CE_Failure) break;
> 
>                     for (unsigned char *data = *imgbuf;
>                          data != (*imgbuf+*imglen);
>                          data += 3)
>                     {
>                         if (*data == NO_DATA_VAL)
>                         {
>                             *(data + 0) = 3;
>                             *(data + 1) = 1;
>                             *(data + 2) = 4;
>                         }
>                         else
>                         {
>                             pal->GetColorEntryAsRGB(*data, &color);
> 
>                             *(data + 0) = color.c1;
>                             *(data + 1) = color.c2;
>                             *(data + 2) = color.c3;
>                         }
>                     }
>                 }
>                 break;
> 
>             case GCI_Undefined: // can we try to make a greyscale image?
>             case GCI_GrayIndex:
> 
>                 //
>                 // copy over all the palette indices and then
>                 // loop through the buffer replacing the values
>                 // with the correct RGB triples. 
>                 //
>                 ret = band->RasterIO(GF_Read, 0, 0, 
>                                      nRasterXSize, nRasterYSize,
>                                      *imgbuf, nRasterXSize, nRasterYSize, 
>                                      GDT_Byte, 3, 0);
>                         
>                 if (ret == CE_Failure) break;
> 
>                 for (unsigned char *data = *imgbuf;
>                      data != (*imgbuf+*imglen);
>                      data += 3)
>                 {
>                     if (*data == NO_DATA_VAL)
>                     {
>                         *(data + 0) = 3;
>                         *(data + 1) = 1;
>                         *(data + 2) = 4;
>                     }
>                     else
>                     {
>                         //pal->GetColorEntry(*data, &color);
> 
>                         //*(data + 0) = *data; // already correct
>                         *(data + 1) = *data;
>                         *(data + 2) = *data;
>                     }
>                 }
>                 break;
> 
>             default:
>                 fprintf(stderr,
>                         "GetImageData: Unsupported color interpretation '%s'\n",
>                         GDALGetColorInterpretationName(
>                            band->GetColorInterpretation()));
>                 break;
>         }
>     }
> 
>     if (ret != CE_None) 
>         if (imgbuf != NULL) delete imgbuf;
> 
>     return ret;
> }
> 
194,195c366,368
<     GDALDatasetH	hSrcDS, hDstDS;
<     const char         *pszFormat = "GTiff";
---
>     GDALDatasetH        hSrcDS = NULL, hDstDS = NULL;
>     const char         *pszFormat = "MEM";
>     const char         *pszDstFilename = "MEM:::"; 
205a379,380
>     unsigned char      *imgbuf = NULL;
>     unsigned int        imglen = 0;
207,208c382
<     PyObject * returnFileData = NULL;
< 
---
>     PyObject * pyImageData = NULL;
216,220d389
<     MFILEReceiver receiver;
<     MFILENAME(pszDstFilename, &receiver);
< 
<     //dummycall();
< 
245,246d413
<     pszFormat = "THUBANBMP";
< 
250c417
<     GDALRegister_THUBANBMP();
---
>     GDALRegister_MEM();
286c453,454
<     papszWarpOptions = CSLSetNameValue( papszWarpOptions, "INIT", "0" );
---
>     papszWarpOptions = CSLSetNameValue( papszWarpOptions, 
>                                         "INIT", NO_DATA_VAL_STR );
324a493
> 
347c516,517
< getOut:
---
>     imglen = 0;
>     imgbuf = NULL;
349,350c519,521
<     GDALClose( hDstDS );
<     GDALClose( hSrcDS );
---
>     if ( GetImageData((GDALDataset *)hDstDS, &imgbuf, &imglen) == CE_None)
>     {
>         //printf("imglen: %i\n", imglen);
352c523,528
<     if ( receiver.data != NULL )
---
>         pyImageData = PyString_FromStringAndSize( ( char * )imgbuf, imglen);
> 
>         delete imgbuf;
>         imgbuf = NULL;
>     }
>     else
354,362c530
<         returnFileData = PyString_FromStringAndSize( ( char * )receiver.data, 
<                                                  receiver.len );
< #if 0
<         FILE *fp;
<         fp = fopen("dummy.bmp", "w+b");
<         fwrite(receiver->data, receiver->len, 1, fp);
<         fclose(fp);
<         free( receiver->data );
< #endif
---
>         PYTHON_ERR( PyExc_StandardError );
364a533,537
> getOut:
> 
>     GDALClose( hDstDS );
>     GDALClose( hSrcDS );
> 
381c554
<         CPLError( CE_Failure, err, "" );
---
>         //CPLError( CE_Failure, err, "%s\n", CPLGetLastErrorMsg() );
386,387c559
<         Py_XINCREF( returnFileData );
<         return returnFileData;
---
>         return pyImageData;
389d560
<     
Index: test/test_baserenderer.py
===================================================================
RCS file: /home/thuban/jail/thubanrepository/thuban/test/test_baserenderer.py,v
retrieving revision 1.7
diff -r1.7 test_baserenderer.py
92c92
<     def draw_raster_data(self, data, format='BMP'):
---
>     def draw_raster_data(self, x, y, data, format='BMP', mask = None):
290c290
<         #hexed = binascii.b2a_base64(renderer.raster_data)
---
>         #hexed = binascii.b2a_base64(renderer.raster_data[2])
292,293c292,293
<         #    print repr(hexed[:65])
<         #    hexed = hexed[65:]
---
>             #print repr(hexed[:65])
>             #hexed = hexed[65:]
297,329c297,323
<             'Qk3GBQAAAAAAADYEAAAoAAAAFAAAABQAAAABAAgAAAAAAJABAAAAAAAAAAAAAAABA'
<             'AAAAAAAApYOAALGAgAGfjoAHmZyACZ2egAujo4AArICAE66GgACngIA5mZSAJqONg'
<             'ACzgIAAoIyABZqZgAO4uYAAtICAAKqAgAScloAAtYCADKepgAS2t4AAooiAALaAgA'
<             'CtgIAHsbOAAp2TgACogIAFtbaACqOigAidnoAAuICADKaogACfjoAAr4CAAKSFgAm'
<             'fnoAAo4eABrS1gAibnoAHsbKAAp6SgACmg4AGs7SACLCxgAqioIAAoYqAAZ6RgACm'
<             'goAKrK6AALmAgAC3gIAApIaABZqagACngYAAo4iAAKmAgAivsYAJoJ6AALCAgACyg'
<             'IAAq4CAAKWEgAOclYALpqeAAK6AgACgjYAEm5eAAKKKgAGekIAHmp6ABpmcgAChi4'
<             'ALpaaACJyegAClhYAEnJeAAZ+QgAqhoIADnZSAB5mdgACiiYAJnp6ACqGegAqrrYA'
<             'GmpuAB5megACkh4ALqqyAA52VgAulpYAAoI6AAZ+PgASbmIALpKWAA7m5gAWbmYAG'
<             'mpyAC6SjgAqioYADnZOAA7q6gAianoALqauABpqagAqgnoAEnJWAAp6RgAWbmIACu'
<             '7uACqGfgAqiooAMqauAAby8gAmusIAMp6qAC6WngAyoqoABvb2AC6SkgAS3uIAJra'
<             '+AB7KzgAynqIALq62ADKirgAC+voAGsrSABLi4gAG8vYADubqAC6qtgAuprIABvb6'
<             'ACLCygAW2t4AKra+AAru8gAS4uYACuruAAry8gAG+voAAEBAAFhkZABAQEAABp6fA'
<             'EBACAAAgPwAAPu/AJE9CgBACAAALj1BAEAICAAGPAAAQAgAAAY8+gBACL8AJTxXAA'
<             'gIQAAAPEAAAAgIAAY8QABACAgAAGQAAABAAAAALpoAAEBAAAAALgAAAEAABkAGAEA'
<             'IQAD2AEAAvwAIAJAu2ABAQEAALmQ5AEBAQAAAnp8AAEAIAAD4+gAAv78An5rDAEBA'
<             'QAAuhAcAQEBAAAb8AABAvwAAAGQKAABAAABpLksAQEAIAC4ACwBAAAAAAPkGAAC/Q'
<             'AD2APoAvwC/AJ0umgBAQEAAAGRkAABAQAAGnp8AQEAIAPcA/AC/AL8A7D0GAEAIQA'
<             'D4hAAAv0AAAAD8QAAAvwgA92T6AL9AvwDsLlcAQEBAAC4AQABAAAgA+EAAAL8IAAA'
<             '8AAAACAAAAJ8uVgBAQEAAAGQ5AABAQAAAnpcAAEBAAPYAQAC/AAgAnQsGAEAAQAAA'
<             'hG0AAEBAAB38PQAIv0AA9mT6AL9AvwAJLmwAZUBAAB0AQAAIAAgAHUAAAAgIAAAAA'
<             'AAAAAAAAACzbAAAQEAA//k5AH+/QAAGb5cAQEBAAACy5AAAQAgAAIpAAABACAAAAA'
<             'AAAAAAAAkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQk'
<             'JCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJ'
<             'CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJC'
<             'QkJCQkJCQkJCQkJCQkJCQkJCQkyEi8aQCEJCQkJCQkJCQkJCQkJCTI7OwgILzsyCg'
<             'kJCQkJCQkJCQkJCzcJFggvADwGEDc3EhYAMgkJCQkJEjcVJDohGj0LGgYAPT0hCT0'
<             'LDyI3CQoBLwAaFgkyEC9AJAE8OgsIMjoABi8kCx4JCQkJCQkeGko8KTcLCxIyNwkJ'
<             'CQkWEjwWNUAQPCEAMwgJCQkJCQkSQBcvEkAPAQkyN0AMCQkJCQhBFyEvNy89JCIkM'
<             'yItGQwJCQo9RxozIgkyCQoPFxAtDBkgIgkJCQkJCQkJMRoQECJQNi9EIAAgCQkJCQ'
<             'kSUA88UAYeBjELICA8HiI=\n')
<         self.assertEquals(renderer.raster_data, raw_data)
<         self.assertEquals(renderer.raster_format, "BMP")
---
>             'UmbmUmbmUmbmUmbmUmbmAtYCJooCAtICAq4CJooCArICAuICArICAuYCAs4COn4CO'
>             'n4CAq4CAuICFpICUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmAuYCAqICAqoCAqoCFp'
>             'ICJooCIo4CCpoCQnoGOn4CDpYCOn4CUmbmUmbmNo6aEpYCLoYCAqICGpICFpICUmb'
>             'mAt4CUmbmNo6aAtICArYCAqoCKoYCMoICTnYKOn4CFpICUmbmUmbmUmbmUmbmAp4C'
>             'NoICArYCAr4CCpoCAqYCCpoCEpYCHo4CFpICHo4CGpICFpICKoYCTnYKMoICAp4CU'
>             'mbmUmbmUmbmUmbmUmbmUmbmAtYCAroCArYCCpoCAtYCAroCAtICAsYCUmbmAt4CAq'
>             'YCAroCMoICAs4CAs4CAtYCAt4CAqYCUmbmUmbmUmbmUmbmAtoCAtYCAq4CAtoCBp4'
>             'CAroCAqoCAq4CAr4CDpYCGpICAt4CAsICDpYCArICCpoCHo4CAs4CAuICUmbmUmbm'
>             'UmbmUmbmUmbmUmbmAuICAqICFpYCAq4CDpoCAqYCFpICAqYCUmbmNo6aAsYCCpoCD'
>             'pYCAqICAtoCUmbmAt4CAqoCCpoCAroCHo4CAsYCAq4CAsICAs4CAp4CUmbmAtYCAq'
>             'YCIooCHo4CAsICAr4CAqICEpYCAs4CAqICArICDpYCEpYCEpYCAr4CUmbmEpYCAs4'
>             'CAtICAs4CAqYCUmbmAtoCAp4CCpoCDpYCAq4CArICAqoCAqYCAqYCAtYCAtoCDpYC'
>             'At4CUmbmUmbmUmbmUmbmAt4CAsoCAsoCAp4CAp4CCpoCAsoCAt4CNo6aUmbmUmbmU'
>             'mbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmAt4CAtYCCpoCAqICAroCAr4CUmbmUm'
>             'bmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmb'
>             'mUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbm'
>             'UmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmU'
>             'mbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUm'
>             'bmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmb'
>             'mUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbm'
>             'UmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmU'
>             'mbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUm'
>             'bmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmb'
>             'mUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbm'
>             'UmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbm\n')
>         self.assertEquals(renderer.raster_data, [20,20,raw_data])
>         self.assertEquals(renderer.raster_format, "RAW")
