/**************************************************************************** * * MODULE: r.terraflow * * COPYRIGHT (C) 2007 Laura Toma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * *****************************************************************************/ #ifndef __3SCAN_H #define __3SCAN_H #include #include #include "types.h" /* ********************************************************************** */ template void scan3line(FUN &funobj, AMI_STREAM *prev, AMI_STREAM *crt, AMI_STREAM *next, BASETYPE nodata, dimension_type i) { dimension_type j=0; AMI_err ae; BASETYPE a[3], b[3], c[3]; T *tmp, center[2]; int done; /* LOG_DEBUG_ID("scan3line: begin"); if(prev) LOG_DEBUG_ID(prev->sprint()); if(crt) LOG_DEBUG_ID(crt->sprint()); if(next) LOG_DEBUG_ID(next->sprint()); */ /* seek 0 */ if (prev) { ae = prev->seek(0); assert(ae == AMI_ERROR_NO_ERROR); } assert(crt); ae = crt->seek(0); assert(ae == AMI_ERROR_NO_ERROR); if (next) { ae = next->seek(0); assert(ae == AMI_ERROR_NO_ERROR); } /* read first 2 elements of each line */ /* read prev */ a[0] = b[0] = c[0] = nodata; if (prev) { ae = prev->read_item(&tmp); assert(ae == AMI_ERROR_NO_ERROR); a[1] = *tmp; ae = prev->read_item(&tmp); assert(ae == AMI_ERROR_NO_ERROR); a[2] = *tmp; } else { a[1] = a[2] = nodata; } /* read crt */ ae = crt->read_item(&tmp); assert(ae == AMI_ERROR_NO_ERROR); center[0] = *tmp; b[1] = *tmp; ae = crt->read_item(&tmp); assert(ae == AMI_ERROR_NO_ERROR); center[1] = *tmp; b[2] = *tmp; /* read next */ if (next) { ae = next->read_item(&tmp); assert(ae == AMI_ERROR_NO_ERROR); c[1] = *tmp; ae = next->read_item(&tmp); assert(ae == AMI_ERROR_NO_ERROR); c[2] = *tmp; } else { c[1] = c[2] = nodata; } done = 0; do { funobj.processWindow(i, j, center[0], a, b, c); /* process current window*/ /* slide one over */ a[0] = a[1]; a[1] = a[2]; b[0] = b[1]; b[1] = b[2]; center[0] = center[1]; c[0] = c[1]; c[1] = c[2]; j++; /* read next item from crt and check for EOS */ ae = crt->read_item(&tmp); if (ae == AMI_ERROR_END_OF_STREAM) { done = 1; b[2] = nodata; center[1] = T(); } else { assert(ae == AMI_ERROR_NO_ERROR); b[2] = *tmp; center[1] = *tmp; } /* read next item from prev */ if (prev) { ae = prev->read_item(&tmp); if (!done) { assert(ae == AMI_ERROR_NO_ERROR); a[2]=*tmp; } else { a[2] = nodata; assert(ae == AMI_ERROR_END_OF_STREAM); } } else { a[2] = nodata; } /* read next item from next */ if (next) { ae = next->read_item(&tmp); if (!done) { assert(ae == AMI_ERROR_NO_ERROR); c[2] = *tmp; } else { c[2] = nodata; assert(ae == AMI_ERROR_END_OF_STREAM); } } else { c[2] = nodata; } } while (!done); /* write last window */ funobj.processWindow(i, j, center[0], a, b, c); /* process current window */ /* LOG_DEBUG_ID("scan3line: end"); */ return; } /****************************************************************/ /* amis0 = data (T) in */ template void scan3(AMI_STREAM &amis0, const dimension_type nr, const dimension_type nc, BASETYPE nodata, FUN &funobj) { AMI_STREAM *l_prev, *l_crt, *l_next; AMI_err ae; ae = amis0.seek(0); assert( ae == AMI_ERROR_NO_ERROR); /* scan simultaneously 3 lines in the grid and fill in the windows use a substream for each line to trigger prefetching */ /* initialize first 2 lines */ ae = amis0.new_substream(AMI_READ_STREAM, 0, nc-1, &l_crt); assert( ae == AMI_ERROR_NO_ERROR); ae = amis0.new_substream(AMI_READ_STREAM, nc, 2*nc-1, &l_next); assert( ae == AMI_ERROR_NO_ERROR); /* LOG_DEBUG_ID("substreams created"); */ /* process lines, 3 at a time */ l_prev = NULL; for (dimension_type i=0;i T * readLine(T *buf, AMI_STREAM &str, const dimension_type len, const T &nodata) { AMI_err ae; buf[0] = nodata; buf[len+1] = nodata; for(dimension_type i=0; i T * setNodata(T *buf, const dimension_type len, const T &nodata) { for(dimension_type j=0; j void memoryScan(AMI_STREAM &str, const dimension_type nrows, const dimension_type ncols, const T nodata, FUN &fo) { T *a, *b, *c; T *buf[3]; str.seek(0); assert(nrows > 1); assert(nrows * ncols == str.stream_len()); buf[0] = new T[ncols+2]; buf[1] = new T[ncols+2]; buf[2] = new T[ncols+2]; unsigned int k; a = setNodata(buf[0], ncols, nodata); b = readLine(buf[1], str, ncols, nodata); k = 2; for(dimension_type i=0; i void memoryScan(AMI_STREAM &str1, AMI_STREAM &str2, const dimension_type nrows, const dimension_type ncols, const T1 nodata1, const T2 nodata2, FUN &fo) { T1 *a1, *b1, *c1; T1 *buf1[3]; T2 *a2, *b2, *c2; T2 *buf2[3]; str1.seek(0); str2.seek(0); assert(nrows > 1); assert(nrows * ncols == str1.stream_len()); assert(nrows * ncols == str2.stream_len()); buf1[0] = new T1[ncols+2]; buf1[1] = new T1[ncols+2]; buf1[2] = new T1[ncols+2]; buf2[0] = new T2[ncols+2]; buf2[1] = new T2[ncols+2]; buf2[2] = new T2[ncols+2]; unsigned int k; a1 = setNodata(buf1[0], ncols, nodata1); a2 = setNodata(buf2[0], ncols, nodata2); b1 = readLine(buf1[1], str1, ncols, nodata1); b2 = readLine(buf2[1], str2, ncols, nodata2); k = 2; for(dimension_type i=0; i