#!/usr/bin/python2 # -*- coding: utf-8 -*- # ***************************************************************************** # $Id: gdalpythonserver.py 7464f4b11b93bb2d1098d1b962907228932bf8c1 2018-05-03 19:56:49 +1000 Ben Elliston $ # # Project: GDAL # Purpose: GDAL API_PROXY server written in Python # Author: Even Rouault, <even dot rouault at mines-paris dot org> # # ***************************************************************************** # Copyright (c) 2013, Even Rouault <even dot rouault at mines-paris dot org> # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # ***************************************************************************/ # WARNING: only Python 2 compatible for now import os import struct import sys from osgeo import gdal class GDALPythonServerRasterBand(object): def __init__(self, gdal_band): self.gdal_band = gdal_band self.XSize = gdal_band.XSize self.YSize = gdal_band.YSize self.Band = gdal_band.GetBand() (self.BlockXSize, self.BlockYSize) = gdal_band.GetBlockSize() self.DataType = gdal_band.DataType self.mask_band = None self.ovr_bands = None def FlushCache(self): return self.gdal_band.FlushCache() def GetColorInterpretation(self): return self.gdal_band.GetColorInterpretation() def GetNoDataValue(self): return self.gdal_band.GetNoDataValue() def GetMinimum(self): return self.gdal_band.GetMinimum() def GetMaximum(self): return self.gdal_band.GetMaximum() def GetOffset(self): return self.gdal_band.GetOffset() def GetScale(self): return self.gdal_band.GetScale() def HasArbitraryOverviews(self): return self.gdal_band.HasArbitraryOverviews() def GetOverviewCount(self): return self.gdal_band.GetOverviewCount() def GetMaskFlags(self): return self.gdal_band.GetMaskFlags() def GetMaskBand(self): if self.mask_band is None: gdal_mask_band = self.gdal_band.GetMaskBand() if gdal_mask_band is not None: self.mask_band = GDALPythonServerRasterBand(gdal_mask_band) return self.mask_band def GetOverview(self, iovr): if self.ovr_bands is None: self.ovr_bands = [None] * self.GetOverviewCount() if self.ovr_bands[iovr] is None: gdal_ovr_band = self.gdal_band.GetOverview(iovr) if gdal_ovr_band is not None: self.ovr_bands[iovr] = GDALPythonServerRasterBand(gdal_ovr_band) return self.ovr_bands[iovr] def GetMetadata(self, domain): return self.gdal_band.GetMetadata(domain) def GetMetadataItem(self, key, domain): return self.gdal_band.GetMetadataItem(key, domain) def IReadBlock(self, nXBlockOff, nYBlockOff): return self.gdal_band.ReadBlock(nXBlockOff, nYBlockOff) def IRasterIO_Read(self, nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize, nBufType): return self.gdal_band.ReadRaster(nXOff, nYOff, nXSize, nYSize, buf_xsize=nBufXSize, buf_ysize=nBufYSize, buf_type=nBufType) def GetUnitType(self): return self.gdal_band.GetUnitType() def GetStatistics(self, approx_ok, force): return self.gdal_band.GetStatistics(approx_ok, force) def ComputeRasterMinMax(self, approx_ok): return self.gdal_band.ComputeRasterMinMax(approx_ok) def GetColorTable(self): return self.gdal_band.GetColorTable() def GetHistogram(self, dfMin, dfMax, nBuckets, bIncludeOutOfRange, bApproxOK): return self.gdal_band.GetHistogram(dfMin, dfMax, nBuckets, include_out_of_range=bIncludeOutOfRange, approx_ok=bApproxOK) class GDALPythonServerDataset(object): def __init__(self, filename, access=gdal.GA_ReadOnly, open_options=None): nFlags = 0 if access == gdal.GA_Update: nFlags |= gdal.OF_UPDATE if open_options is None: open_options = [] self.gdal_ds = gdal.OpenEx(filename, nFlags, open_options=open_options) if self.gdal_ds is None: raise Exception(gdal.GetLastErrorMsg()) self.RasterXSize = self.gdal_ds.RasterXSize self.RasterYSize = self.gdal_ds.RasterYSize self.RasterCount = self.gdal_ds.RasterCount self.bands = [] for i in range(self.RasterCount): gdal_band = self.gdal_ds.GetRasterBand(i + 1) self.bands.append(GDALPythonServerRasterBand(gdal_band)) def __del__(self): self.gdal_ds = None def GetDriver(self): return self.gdal_ds.GetDriver() def GetRasterBand(self, i): return self.bands[i - 1] def GetDescription(self): return self.gdal_ds.GetDescription() def GetGeoTransform(self): return self.gdal_ds.GetGeoTransform() def GetProjectionRef(self): return self.gdal_ds.GetProjectionRef() def GetGCPCount(self): return self.gdal_ds.GetGCPCount() def GetFileList(self): return self.gdal_ds.GetFileList() def GetMetadata(self, domain): return self.gdal_ds.GetMetadata(domain) def GetMetadataItem(self, key, domain): return self.gdal_ds.GetMetadataItem(key, domain) def FlushCache(self): self.gdal_ds.FlushCache() def IRasterIO_Read(self, nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize, nBufType, panBandMap, nPixelSpace, nLineSpace, nBandSpace): return self.gdal_ds.ReadRaster(nXOff, nYOff, nXSize, nYSize, buf_xsize=nBufXSize, buf_ysize=nBufYSize, buf_type=nBufType, band_list=panBandMap, buf_pixel_space=nPixelSpace, buf_line_space=nLineSpace, buf_band_space=nBandSpace) INSTR_GetGDALVersion = 1 INSTR_EXIT = 2 INSTR_EXIT_FAIL = 3 INSTR_SetConfigOption = 4 # INSTR_Progress = 5 INSTR_Reset = 6 INSTR_Open = 7 INSTR_Identify = 8 INSTR_Create = 9 INSTR_CreateCopy = 10 INSTR_QuietDelete = 11 # INSTR_AddBand = 12 INSTR_GetGeoTransform = 13 # INSTR_SetGeoTransform = 14 INSTR_GetProjectionRef = 15 # INSTR_SetProjection = 16 INSTR_GetGCPCount = 17 # INSTR_GetGCPProjection = 18 # INSTR_GetGCPs = 19 # INSTR_SetGCPs = 20 INSTR_GetFileList = 21 INSTR_FlushCache = 22 # INSTR_SetDescription = 23 INSTR_GetMetadata = 24 INSTR_GetMetadataItem = 25 # INSTR_SetMetadata = 26 # INSTR_SetMetadataItem = 27 INSTR_IRasterIO_Read = 28 # INSTR_IRasterIO_Write = 29 # INSTR_IBuildOverviews = 30 # INSTR_AdviseRead = 31 # INSTR_CreateMaskBand = 32 INSTR_Band_First = 33 INSTR_Band_FlushCache = 34 INSTR_Band_GetCategoryNames = 35 # INSTR_Band_SetCategoryNames = 36 # INSTR_Band_SetDescription = 37 INSTR_Band_GetMetadata = 38 INSTR_Band_GetMetadataItem = 39 INSTR_Band_SetMetadata = 40 INSTR_Band_SetMetadataItem = 41 INSTR_Band_GetColorInterpretation = 42 # INSTR_Band_SetColorInterpretation = 43 INSTR_Band_GetNoDataValue = 44 INSTR_Band_GetMinimum = 45 INSTR_Band_GetMaximum = 46 INSTR_Band_GetOffset = 47 INSTR_Band_GetScale = 48 # INSTR_Band_SetNoDataValue = 49 # INSTR_Band_SetOffset = 50 # INSTR_Band_SetScale = 51 INSTR_Band_IReadBlock = 52 # INSTR_Band_IWriteBlock = 53 INSTR_Band_IRasterIO_Read = 54 # INSTR_Band_IRasterIO_Write = 55 INSTR_Band_GetStatistics = 56 # INSTR_Band_ComputeStatistics = 57 # INSTR_Band_SetStatistics = 58 INSTR_Band_ComputeRasterMinMax = 59 INSTR_Band_GetHistogram = 60 INSTR_Band_GetDefaultHistogram = 61 # INSTR_Band_SetDefaultHistogram = 62 INSTR_Band_HasArbitraryOverviews = 63 INSTR_Band_GetOverviewCount = 64 INSTR_Band_GetOverview = 65 INSTR_Band_GetMaskBand = 66 INSTR_Band_GetMaskFlags = 67 # INSTR_Band_CreateMaskBand = 68 # INSTR_Band_Fill = 69 INSTR_Band_GetColorTable = 70 # INSTR_Band_SetColorTable = 71 INSTR_Band_GetUnitType = 72 # INSTR_Band_SetUnitType = 73 # INSTR_Band_BuildOverviews = 74 INSTR_Band_GetDefaultRAT = 75 # INSTR_Band_SetDefaultRAT = 76 # INSTR_Band_AdviseRead = 77 # INSTR_Band_DeleteNoDataValue=78 INSTR_Band_End = 79 # INSTR_END = 80 caps_list = [ INSTR_GetGDALVersion, INSTR_EXIT, INSTR_EXIT_FAIL, INSTR_SetConfigOption, # INSTR_Progress, INSTR_Reset, INSTR_Open, INSTR_Identify, INSTR_Create, INSTR_CreateCopy, INSTR_QuietDelete, # INSTR_AddBand, INSTR_GetGeoTransform, # INSTR_SetGeoTransform, INSTR_GetProjectionRef, # INSTR_SetProjection, INSTR_GetGCPCount, # INSTR_GetGCPProjection, # INSTR_GetGCPs, # INSTR_SetGCPs, INSTR_GetFileList, INSTR_FlushCache, # INSTR_SetDescription, INSTR_GetMetadata, INSTR_GetMetadataItem, # INSTR_SetMetadata, # INSTR_SetMetadataItem, INSTR_IRasterIO_Read, # INSTR_IRasterIO_Write, # INSTR_IBuildOverviews, # INSTR_AdviseRead, # INSTR_CreateMaskBand, # INSTR_Band_First, INSTR_Band_FlushCache, INSTR_Band_GetCategoryNames, # INSTR_Band_SetCategoryNames, # INSTR_Band_SetDescription, INSTR_Band_GetMetadata, INSTR_Band_GetMetadataItem, INSTR_Band_SetMetadata, INSTR_Band_SetMetadataItem, INSTR_Band_GetColorInterpretation, # INSTR_Band_SetColorInterpretation, INSTR_Band_GetNoDataValue, INSTR_Band_GetMinimum, INSTR_Band_GetMaximum, INSTR_Band_GetOffset, INSTR_Band_GetScale, # INSTR_Band_SetNoDataValue, # INSTR_Band_SetOffset, # INSTR_Band_SetScale, INSTR_Band_IReadBlock, # INSTR_Band_IWriteBlock, INSTR_Band_IRasterIO_Read, # INSTR_Band_IRasterIO_Write, INSTR_Band_GetStatistics, # INSTR_Band_ComputeStatistics, # INSTR_Band_SetStatistics, INSTR_Band_ComputeRasterMinMax, INSTR_Band_GetHistogram, # INSTR_Band_GetDefaultHistogram, # INSTR_Band_SetDefaultHistogram, INSTR_Band_HasArbitraryOverviews, INSTR_Band_GetOverviewCount, INSTR_Band_GetOverview, INSTR_Band_GetMaskBand, INSTR_Band_GetMaskFlags, # INSTR_Band_CreateMaskBand, # INSTR_Band_Fill, INSTR_Band_GetColorTable, # INSTR_Band_SetColorTable, INSTR_Band_GetUnitType, # INSTR_Band_SetUnitType, # INSTR_Band_BuildOverviews, # INSTR_Band_GetDefaultRAT, # INSTR_Band_SetDefaultRAT, # INSTR_Band_AdviseRead , # INSTR_Band_End, # INSTR_END = 80 ] CE_None = 0 CE_Failure = 3 VERBOSE = 0 def read_int(): if sys.version_info >= (3, 0, 0): return struct.unpack('i', sys.stdin.read(4).encode('latin1'))[0] return struct.unpack('i', sys.stdin.read(4))[0] def read_bigint(): if sys.version_info >= (3, 0, 0): return struct.unpack('q', sys.stdin.read(8).encode('latin1'))[0] return struct.unpack('q', sys.stdin.read(8))[0] def read_double(): if sys.version_info >= (3, 0, 0): return struct.unpack('d', sys.stdin.read(8).encode('latin1'))[0] return struct.unpack('d', sys.stdin.read(8))[0] def read_str(): length = read_int() if length <= 0: return None line = sys.stdin.read(length) if line and line[-1] == '\0': line = line[:-1] return str def read_strlist(): count = read_int() strlist = [] for _ in range(count): strlist.append(read_str()) return strlist def write_int(i): if i is True: v = struct.pack('i', 1) elif i is False or i is None: v = struct.pack('i', 0) else: v = struct.pack('i', i) if sys.version_info >= (3, 0, 0): sys.stdout.write(v.decode('latin1')) else: sys.stdout.write(v) def write_uint64(i): v = struct.pack('Q', i) if sys.version_info >= (3, 0, 0): sys.stdout.write(v.decode('latin1')) else: sys.stdout.write(v) def write_double(d): if sys.version_info >= (3, 0, 0): sys.stdout.write(struct.pack('d', d).decode('latin1')) else: sys.stdout.write(struct.pack('d', d)) def write_str(s): if s is None: write_int(0) else: write_int(len(s) + 1) sys.stdout.write(s) sys.stdout.write('\x00') def write_band(band, isrv_num): if band is not None: write_int(isrv_num) # srv band count write_int(band.Band) # band number write_int(0) # access write_int(band.XSize) # X write_int(band.YSize) # Y write_int(band.DataType) # data type write_int(band.BlockXSize) # block x size write_int(band.BlockYSize) # block y size write_str('') # band description else: write_int(-1) def write_ct(ct): if ct is None: write_int(-1) else: write_int(ct.GetPaletteInterpretation()) nCount = ct.GetCount() write_int(nCount) for i in range(nCount): entry = ct.GetColorEntry(i) write_int(entry[0]) write_int(entry[1]) write_int(entry[2]) write_int(entry[3]) def write_marker(): sys.stdout.write('\xDE\xAD\xBE\xEF') def write_zero_error(): write_int(0) def main_loop(): server_ds = None server_bands = [] gdal.SetConfigOption('GDAL_API_PROXY', 'NO') while 1: sys.stdout.flush() instr = read_int() if VERBOSE: sys.stderr.write('instr=%d\n' % instr) band = None if instr >= INSTR_Band_First and instr <= INSTR_Band_End: srv_band = read_int() band = server_bands[srv_band] if instr == INSTR_GetGDALVersion: if sys.version_info >= (3, 0, 0): lsb = struct.unpack('B', sys.stdin.read(1).encode('latin1'))[0] else: lsb = struct.unpack('B', sys.stdin.read(1))[0] ver = read_str() vmajor = read_int() vminor = read_int() protovmajor = read_int() protovminor = read_int() extra_bytes = read_int() if VERBOSE: sys.stderr.write('lsb=%d\n' % lsb) sys.stderr.write('ver=%s\n' % ver) sys.stderr.write('vmajor=%d\n' % vmajor) sys.stderr.write('vminor=%d\n' % vminor) sys.stderr.write('protovmajor=%d\n' % protovmajor) sys.stderr.write('protovminor=%d\n' % protovminor) sys.stderr.write('extra_bytes=%d\n' % extra_bytes) write_str('2.1dev') write_int(2) # vmajor write_int(1) # vminor write_int(3) # protovmajor write_int(0) # protovminor write_int(0) # extra bytes continue elif instr == INSTR_EXIT: server_ds = None server_bands = [] write_marker() write_int(1) sys.exit(0) elif instr == INSTR_EXIT_FAIL: server_ds = None server_bands = [] write_marker() write_int(1) sys.exit(1) elif instr == INSTR_SetConfigOption: key = read_str() val = read_str() gdal.SetConfigOption(key, val) if VERBOSE: sys.stderr.write('key=%s\n' % key) sys.stderr.write('val=%s\n' % val) continue elif instr == INSTR_Reset: # if server_ds is not None: # sys.stderr.write('Reset(%s)\n' % server_ds.GetDescription()) server_ds = None server_bands = [] write_marker() write_int(1) elif instr == INSTR_Open: access = read_int() filename = read_str() cwd = read_str() open_options = read_strlist() if cwd is not None: os.chdir(cwd) if VERBOSE: sys.stderr.write('access=%d\n' % access) sys.stderr.write('filename=%s\n' % filename) sys.stderr.write('cwd=%s\n' % cwd) sys.stderr.write('open_options=%s\n' % str(open_options)) # sys.stderr.write('Open(%s)\n' % filename) try: server_ds = GDALPythonServerDataset(filename, access, open_options) except: server_ds = None write_marker() if server_ds is None: write_int(0) # Failure else: write_int(1) # Success write_int(16) # caps length caps = [0 for i in range(16)] for cap in caps_list: caps[int(cap / 8)] = caps[int(cap / 8)] | (1 << (cap % 8)) for i in range(16): sys.stdout.write(struct.pack('B', caps[i])) # caps write_str(server_ds.GetDescription()) drv = server_ds.GetDriver() if drv is not None: write_str(drv.GetDescription()) write_int(0) # End of driver metadata else: write_str(None) write_int(server_ds.RasterXSize) # X write_int(server_ds.RasterYSize) # Y write_int(server_ds.RasterCount) # Band count write_int(1) # All bands are identical if server_ds.RasterCount > 0: write_band(server_ds.GetRasterBand(1), len(server_bands)) for i in range(server_ds.RasterCount): server_bands.append(server_ds.GetRasterBand(i + 1)) elif instr == INSTR_Identify: filename = read_str() cwd = read_str() dr = gdal.IdentifyDriver(filename) write_marker() if dr is None: write_int(0) else: write_int(1) elif instr == INSTR_Create: filename = read_str() cwd = read_str() read_int() # xsize = read_int() # ysize = read_int() # bands = read_int() # datatype = read_strlist() # options = write_marker() # FIXME write_int(0) elif instr == INSTR_CreateCopy: filename = read_str() read_str() # src_description = cwd = read_str() read_int() # strict = read_strlist() # options = # FIXME write_int(0) elif instr == INSTR_QuietDelete: filename = read_str() cwd = read_str() write_marker() # FIXME elif instr == INSTR_GetGeoTransform: gt = server_ds.GetGeoTransform() write_marker() if gt is not None: write_int(CE_None) write_int(6 * 8) for i in range(6): write_double(gt[i]) else: write_int(CE_Failure) elif instr == INSTR_GetProjectionRef: write_marker() write_str(server_ds.GetProjectionRef()) elif instr == INSTR_GetGCPCount: write_marker() write_int(server_ds.GetGCPCount()) elif instr == INSTR_GetFileList: write_marker() fl = server_ds.GetFileList() write_int(len(fl)) for f in fl: write_str(f) elif instr == INSTR_GetMetadata: domain = read_str() md = server_ds.GetMetadata(domain) write_marker() write_int(len(md)) for key in md: write_str('%s=%s' % (key, md[key])) elif instr == INSTR_GetMetadataItem: key = read_str() domain = read_str() val = server_ds.GetMetadataItem(key, domain) write_marker() write_str(val) elif instr == INSTR_IRasterIO_Read: nXOff = read_int() nYOff = read_int() nXSize = read_int() nYSize = read_int() nBufXSize = read_int() nBufYSize = read_int() nBufType = read_int() nBandCount = read_int() panBandMap = [] read_int() # size = for i in range(nBandCount): panBandMap.append(read_int()) nPixelSpace = read_bigint() nLineSpace = read_bigint() nBandSpace = read_bigint() val = server_ds.IRasterIO_Read(nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize, nBufType, panBandMap, nPixelSpace, nLineSpace, nBandSpace) write_marker() if val is None: write_int(CE_Failure) write_int(0) else: write_int(CE_None) write_int(len(val)) sys.stdout.write(val) elif instr == INSTR_FlushCache: if server_ds is not None: server_ds.FlushCache() write_marker() elif instr == INSTR_Band_FlushCache: val = band.FlushCache() write_marker() write_int(val) elif instr == INSTR_Band_GetCategoryNames: write_marker() # FIXME write_int(-1) elif instr == INSTR_Band_GetMetadata: domain = read_str() md = band.GetMetadata(domain) write_marker() write_int(len(md)) for key in md: write_str('%s=%s' % (key, md[key])) elif instr == INSTR_Band_GetMetadataItem: key = read_str() domain = read_str() val = band.GetMetadataItem(key, domain) write_marker() write_str(val) elif instr == INSTR_Band_GetColorInterpretation: val = band.GetColorInterpretation() write_marker() write_int(val) elif instr == INSTR_Band_GetNoDataValue: val = band.GetNoDataValue() write_marker() if val is None: write_int(0) write_double(0) else: write_int(1) write_double(val) elif instr == INSTR_Band_GetMinimum: val = band.GetMinimum() write_marker() if val is None: write_int(0) write_double(0) else: write_int(1) write_double(val) elif instr == INSTR_Band_GetMaximum: val = band.GetMaximum() write_marker() if val is None: write_int(0) write_double(0) else: write_int(1) write_double(val) elif instr == INSTR_Band_GetOffset: val = band.GetOffset() write_marker() if val is None: write_int(0) write_double(0) else: write_int(1) write_double(val) elif instr == INSTR_Band_GetScale: val = band.GetScale() write_marker() if val is None: write_int(0) write_double(1) # default value is 1 else: write_int(1) write_double(val) elif instr == INSTR_Band_IReadBlock: nXBlockOff = read_int() nYBlockOff = read_int() val = band.IReadBlock(nXBlockOff, nYBlockOff) write_marker() if val is None: write_int(CE_Failure) length = band.BlockXSize * band.BlockYSize * (gdal.GetDataTypeSize(band.DataType) / 8) write_int(length) sys.stdout.write(''.join('\0' for i in range(length))) else: write_int(CE_None) write_int(len(val)) sys.stdout.write(val) elif instr == INSTR_Band_IRasterIO_Read: nXOff = read_int() nYOff = read_int() nXSize = read_int() nYSize = read_int() nBufXSize = read_int() nBufYSize = read_int() nBufType = read_int() val = band.IRasterIO_Read(nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize, nBufType) write_marker() if val is None: write_int(CE_Failure) write_int(0) else: write_int(CE_None) write_int(len(val)) sys.stdout.write(val) elif instr == INSTR_Band_GetStatistics: approx_ok = read_int() force = read_int() val = band.GetStatistics(approx_ok, force) write_marker() if val is None or val[3] < 0: write_int(CE_Failure) else: write_int(CE_None) write_double(val[0]) write_double(val[1]) write_double(val[2]) write_double(val[3]) elif instr == INSTR_Band_ComputeRasterMinMax: approx_ok = read_int() val = band.ComputeRasterMinMax(approx_ok) write_marker() if val is None: write_int(CE_Failure) else: write_int(CE_None) write_double(val[0]) write_double(val[1]) elif instr == INSTR_Band_GetHistogram: dfMin = read_double() dfMax = read_double() nBuckets = read_int() bIncludeOutOfRange = read_int() bApproxOK = read_int() val = band.GetHistogram(dfMin, dfMax, nBuckets, bIncludeOutOfRange, bApproxOK) write_marker() if val is None: write_int(CE_Failure) else: write_int(CE_None) write_int(len(val) * 8) for v in val: write_uint64(v) # elif instr == INSTR_Band_GetDefaultHistogram: # bForce = read_int() # write_marker() # write_int(CE_Failure) elif instr == INSTR_Band_HasArbitraryOverviews: val = band.HasArbitraryOverviews() write_marker() write_int(val) elif instr == INSTR_Band_GetOverviewCount: val = band.GetOverviewCount() write_marker() write_int(val) elif instr == INSTR_Band_GetOverview: iovr = read_int() ovr_band = band.GetOverview(iovr) write_marker() write_band(ovr_band, len(server_bands)) if ovr_band is not None: server_bands.append(ovr_band) elif instr == INSTR_Band_GetMaskBand: msk_band = band.GetMaskBand() write_marker() write_band(msk_band, len(server_bands)) if msk_band is not None: server_bands.append(msk_band) elif instr == INSTR_Band_GetMaskFlags: val = band.GetMaskFlags() write_marker() write_int(val) elif instr == INSTR_Band_GetColorTable: ct = band.GetColorTable() write_marker() write_ct(ct) elif instr == INSTR_Band_GetUnitType: val = band.GetUnitType() write_marker() write_str(val) # elif instr == INSTR_Band_GetDefaultRAT: # write_marker() # # FIXME # write_int(0) else: break write_zero_error() main_loop()