www.pudn.com > dstile-0.2.rar > TileProcessor.cpp


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#include "exceptions.h"
#include "syskit.h"
#include "giskit.h"
#include "TileProcessor.h"

TileProcessor::TileProcessor() :
    m_minDataVal(0)
{
}

TileProcessor::~TileProcessor() {
}

void TileProcessor::Combine(GDALDataset *out, vector &ops) {
    int sx = out->GetRasterXSize();
    int sy = out->GetRasterYSize();
    GDALDataType dataType = out->GetRasterBand(1)->GetRasterDataType();
    int bands = out->GetRasterCount();
    int bandPixelSize = (GDALGetDataTypeSize(dataType) + 7) / 8;
    int pixelSize = bands * bandPixelSize;
    int lineSize = sx * pixelSize;
    char *d0, *d1;
    
    d0 = new char[lineSize];
    d1 = new char[lineSize];
    
    for (int y = 0; y < sy; ++y) {
	ops[0]->RasterIO(GF_Read, 0, y, sx, 1, d0, sx, 1, dataType, bands, 0, pixelSize, lineSize, bandPixelSize);
	for (int i = 1; i < ops.size(); ++i) {
	    ops[i]->RasterIO(GF_Read, 0, y, sx, 1, d1, sx, 1, dataType, bands, 0, pixelSize, lineSize, bandPixelSize);
	    switch (dataType) {
	    case GDT_Byte:
		unsigned char *p0 = reinterpret_cast(d0);
		unsigned char *p1 = reinterpret_cast(d1);
		int minDataVal = m_minDataVal;
		if (bands == 3) {
		    minDataVal *= 3;
		    for (int j = 0; j < (sx * 3); j += 3) {
			if ((static_cast(p1[j]) + static_cast(p1[j + 1]) + static_cast(p1[j + 2])) >= minDataVal) {
			    p0[j] = p1[j];
			    p0[j + 1] = p1[j + 1];
			    p0[j + 2] = p1[j + 2];
			} else if ((static_cast(p0[j]) + static_cast(p0[j + 1]) + static_cast(p0[j + 2])) < minDataVal) {
			    p0[j] = 0;
			    p0[j + 1] = 0;
			    p0[j + 2] = 0;
			}
		    }
		} else if (bands == 1) {
		    for (int j = 0; j < sx; j += 1) {
			if (p1[j] >= minDataVal) p0[j] = p1[j];
			else if (p0[j] < minDataVal) p0[j] = 0;
		    }
		}
		break;
	    default:
		break;
	    }
	}
	out->RasterIO(GF_Write, 0, y, sx, 1, d0, sx, 1, dataType, bands, 0, pixelSize, lineSize, bandPixelSize);
    }

    delete d1;
    delete d0;
}

void TileProcessor::Combine(GDALDataset *out, GDALDataset *op0, GDALDataset *op1) {
    vector v;

    v.push_back(op0);
    v.push_back(op1);
    Combine(out, v);
}

void TileProcessor::Subsample2x2(GDALDataset *out, vector &ops) {
    int sx = out->GetRasterXSize();
    int sy = out->GetRasterYSize();
    GDALDataType dataType = out->GetRasterBand(1)->GetRasterDataType();
    int bands = out->GetRasterCount();
    int bandPixelSize = (GDALGetDataTypeSize(dataType) + 7) / 8;
    int pixelSize = bands * bandPixelSize;
    int lineSize = sx * pixelSize;
    char *d0, *d1;
    int tx, ty;

    d0 = new char[lineSize * 2];
    d1 = new char[lineSize];
    
    for (int b = 0; b < 4; ++b) if (!ops[b]) {
	memset(d1, 0, lineSize / 2);
	for (int y = 0; y < sy; y += 2) {
	    tx = (b & 1) ? (sx / 2) : 0;
	    ty = y / 2 + ((b & 2) ? (sy / 2) : 0);
	    out->RasterIO(GF_Write, tx, ty, sx / 2, 1, d1, sx / 2, 1, dataType, bands, 0, pixelSize, lineSize, bandPixelSize);
	}
    } else {
	for (int y = 0; y < sy; y += 2) {
	    ops[b]->RasterIO(GF_Read, 0, y, sx, 2, d0, sx, 2, dataType, bands, 0, pixelSize, lineSize, bandPixelSize);
	    switch (dataType) {
	    case GDT_Byte:
		unsigned char *p0 = reinterpret_cast(d0);
	        unsigned char *p1 = reinterpret_cast(d1);
	        int minDataVal = m_minDataVal;
		if (bands == 3) {
		    unsigned char ic[4][3];
	    	    unsigned char nc[3];
	    	    for (int j = 0, k = 0; j < (sx * 3); j += 6, k += 3) {
                	for (int l = 0; l < 3; ++l) ic[0][l] = p0[j + l];
			for (int l = 0; l < 3; ++l) ic[1][l] = p0[j + l + 3];
			for (int l = 0; l < 3; ++l) ic[2][l] = p0[j + l + lineSize];
			for (int l = 0; l < 3; ++l) ic[3][l] = p0[j + l + lineSize + 3];
/*                	if (((ic[0][0] < minDataVal) && (ic[0][1] < minDataVal) && (ic[0][2] < minDataVal))
                        	|| ((ic[1][0] < minDataVal) && (ic[1][1] < minDataVal) && (ic[1][2] < minDataVal))
                        	|| ((ic[2][0] < minDataVal) && (ic[2][1] < minDataVal) && (ic[2][2] < minDataVal))
				|| ((ic[3][0] < minDataVal) && (ic[3][1] < minDataVal) && (ic[3][2] < minDataVal))) {
                	    for (int l = 0; l < 3; ++l) p1[k + l] = 0;
        		} else {*/
			    for (int l = 0; l < 3; ++l) p1[k + l] = (static_cast(2) + ic[0][l] + ic[1][l] + ic[2][l] + ic[3][l]) >> 2;
//                	}
		    }
		} else if (bands == 1) {
	    	    for (int j = 0, k = 0; j < sx; j += 2, k += 1) {
			if ((p0[j] < minDataVal) || (p0[j + 1] < minDataVal) || (p0[j + lineSize] < minDataVal) || (p0[j + lineSize + 1] < minDataVal)) p1[k] = 0;
			else p1[k] = (static_cast(2) + p0[j] + p0[j + 1] + p0[j + lineSize] + p0[j + lineSize + 1]) >> 2;
		    }
		}
		break;
	    default:
		break;
	    }
	    tx = (b & 1) ? (sx / 2) : 0;
	    ty = y / 2 + ((b & 2) ? (sy / 2) : 0);
	    out->RasterIO(GF_Write, tx, ty, sx / 2, 1, d1, sx / 2, 1, dataType, bands, 0, pixelSize, lineSize, bandPixelSize);
	}
    }

    delete d1;
    delete d0;
}

void TileProcessor::Subsample2x2(GDALDataset *out, GDALDataset *op00, GDALDataset *op01, GDALDataset *op10, GDALDataset *op11) {
    vector v;

    v.push_back(op00);
    v.push_back(op01);
    v.push_back(op10);
    v.push_back(op11);
    Subsample2x2(out, v);
}

bool TileProcessor::IsNull(GDALDataset *op0) {
    int sx = op0->GetRasterXSize();
    int sy = op0->GetRasterYSize();
    GDALDataType dataType = op0->GetRasterBand(1)->GetRasterDataType();
    int bands = op0->GetRasterCount();
    int bandPixelSize = (GDALGetDataTypeSize(dataType) + 7) / 8;
    int pixelSize = bands * bandPixelSize;
    int lineSize = sx * pixelSize;
    char *d0;
    
    d0 = new char[lineSize];
    
    for (int y = 0; y < sy; ++y) {
	op0->RasterIO(GF_Read, 0, y, sx, 1, d0, sx, 1, dataType, bands, 0, pixelSize, lineSize, bandPixelSize);
        switch (dataType) {
        case GDT_Byte:
	    unsigned char *p0 = reinterpret_cast(d0);
	    unsigned char minDataVal = m_minDataVal;
	    if (bands == 3) {
		minDataVal *= 3;
	        for (int j = 0; j < (sx * 3); j += 3) {
		    if ((static_cast(p0[j]) + static_cast(p0[j + 1]) + static_cast(p0[j + 2])) >= minDataVal) {
			delete d0;
			return false;
		    }
		}
	    } else if (bands == 1) {
		for (int j = 0; j < sx; j += 1) {
		    if (p0[j] >= minDataVal) {
			delete d0;
			return false;
		    }
		}
	    }
	    break;
	default:
	    break;
	}
    }

    delete d0;
    return true;
}

void TileProcessor::LinearTransform(GDALDataset *out, GDALDataset *in, int blackOut, int blackIn, int whiteOut, int whiteIn, int keepBlack, int whiteToBlack) {
    int sx = in->GetRasterXSize();
    int sy = in->GetRasterYSize();
    GDALDataType dataType = in->GetRasterBand(1)->GetRasterDataType();
    int bands = in->GetRasterCount();
    int bandPixelSize = (GDALGetDataTypeSize(dataType) + 7) / 8;
    int pixelSize = bands * bandPixelSize;
    int lineSize = sx * pixelSize;
    unsigned char *d0;
    unsigned char lut[256];
    
    for (int i = 0; i < blackIn; ++i) lut[i] = blackOut;
    for (int i = blackIn; i < whiteIn; ++i) lut[i] = blackOut + ((whiteOut - blackOut) * (i - blackIn)) / (whiteIn - blackIn);
    for (int i = whiteIn; i < 256; ++i) lut[i] = whiteOut;
    for (int i = 0; i < keepBlack; ++i) lut[i] = 0;

    d0 = new unsigned char[lineSize];

    for (int y = 0; y < sy; ++y) {
	in->RasterIO(GF_Read, 0, y, sx, 1, d0, sx, 1, dataType, bands, 0, pixelSize, lineSize, bandPixelSize);
	if (whiteToBlack > 0) {
	    for (int x = 0; x < (sx * bands); x += 3) {
		if ((static_cast(d0[x]) + static_cast(d0[x + 1]) + static_cast(d0[x + 2])) >= (whiteToBlack * 3)) {
		    d0[x] = 0;
		    d0[x + 1] = 0;
		    d0[x + 2] = 0;
		} else {
		    d0[x] = lut[d0[x]];
		    d0[x + 1] = lut[d0[x + 1]];
		    d0[x + 2] = lut[d0[x + 2]];
		}
	    }
	} else {
	    for (int x = 0; x < (sx * bands); ++x) d0[x] = lut[d0[x]];
	}
	out->RasterIO(GF_Write, 0, y, sx, 1, d0, sx, 1, dataType, bands, 0, pixelSize, lineSize, bandPixelSize);
    }

    delete d0;
}