X& btm_slot() const { #if 0 if (size == 0) throw StringError("ClumpBuffer is empty"); #endif return data[tail * width]; }
X* btm_line() const { #if 0 if (size == 0) throw StringError("ClumpBuffer is empty"); #endif return &(data[tail * width]); }
X* getLine(unsigned int idx) { #if 0 if (idx >= size) throw StringError("Index into ClumpBuffer out of range"); #endif idx = idx + head; if (idx >= total) idx -= total; return &(data[idx * width]); }
X& operator[] (unsigned int idx) { #if 0 if (idx >= size) throw StringError("Index into ClumpBuffer out of range"); #endif idx += head; if (idx >= total) idx -= total; return data[idx*width]; }
static int ReadTag(GTIF *gt,GTIFReadMethod scan,void *aux) { int i,j,tag; char *vptr; char tagname[100]; double *data,*dptr; int count,nrows,ncols,num; char message[1024]; scan(message,aux); if (!strncmp(message,FMT_TAGEND,8)) return 0; num=sscanf(message,"%[^( ] (%d,%d):\n",tagname,&nrows,&ncols); if (num!=3) return StringError(message); tag = GTIFTagCode(tagname); if (tag < 0) return StringError(tagname); count = nrows*ncols; data = (double *) _GTIFcalloc(count * sizeof(double)); dptr = data; for (i=0; i<nrows; i++) { scan(message,aux); vptr = message; for (j=0; j<ncols; j++) { if (!sscanf(vptr,"%lg",dptr++)) return StringError(vptr); FINDCHAR(vptr,' '); SKIPWHITE(vptr); } } (gt->gt_methods.set)(gt->gt_tif, (pinfo_t) tag, count, data ); _GTIFFree( data ); return 1; }
X* next_line() { #if 0 if (size == total) throw StringError("ClumpBuffer is full"); #endif X* temp = &(data[tail*width]); ++tail; if (tail == total) tail=0; ++size; return temp; }
X& next_slot() { #if 0 if (size == total) throw StringError("ClumpBuffer is full"); #endif X& temp = data[tail * width]; ++tail; if (tail == total) tail = 0; ++size; return temp; }
X* pull_line() { #if 0 if (size == 0) throw StringError("ClumpBuffer is empty"); #endif X* temp = &(data[head * width]); ++head; if (head == total) head = 0; --size; return temp; }
X& pull_slot() { #if 0 if (size == 0) throw StringError("ClumpBuffer is empty"); #endif X& temp = data[head * width]; ++head; if (head == total) head = 0; --size; return temp; }
ClumpBuffer(unsigned int sz, unsigned int w=1) { #if 0 if (sz < 1) throw StringError("Attempt to make ClumpBuffer with 0 slots"); if (w < 1) throw StringError("Attempt to make ClumpBuffer with 0 width"); #endif width = 0; head = 0; tail = 0; size = 0; total = 0; if (w >= 1 && sz >= 1) { data=new X[sz*w]; if (data) { width=w; total=sz; } } }
void apply_avg(ClumpBuffer<double>& vals, X* dest) { static double den; static SmartRGBA sum; static unsigned int i, j; den = 0.0; #if 0 if (vals.length() != size) throw StringError("Size of pixel/proportion ClumpBuffers do not match"); #endif for (i = 0; i < size; ++i) den += vals[i]; #if 0 if (den == 1.0) throw StringError("Identical axes should copy"); if (den <= 1.0) throw StringError("Enlargement should interpolate"); if (den == 0.0) throw StringError("Averaging has a denominator of zero"); #endif if (width < 2) { sum = 0.0; for (i = 0; i < size; ++i) sum += ((SmartRGBA)(data[(head + i) % total]) * (vals[i])); *dest = (RGBA)(sum / den); } else { for (j = 0; j < (unsigned int) width; ++j) { sum = 0.0; for (i = 0; i < size; ++i) { sum += ((SmartRGBA)(data[((head+i)%total)*width+j]) * (vals[i])); } dest[j] = (RGBA)(sum / den); } } }
void apply(ClumpBuffer<double>& vals, X* dest) { static double den; static int i, j; static SmartRGBA sum; den = 0.0; #if 0 if (vals.length() != size) throw StringError("Size of pixel/proportion ClumpBuffers do not match"); #endif for (i = 0; i < (int)size; ++i) den += vals[i]; #if 0 if (den != 1.0) throw StringError("Interpolation factors should add to 1"); #endif if (width < 2) { sum = 0.0; for (i = 0; i < (int)size; ++i) { sum += ((SmartRGBA)(data[(head+i)%total]) * (vals[i])); } *dest = (RGBA)sum; } else { for (j = 0; j < width; ++j) { sum = 0.0; for (i = 0; i < (int)size; ++i) { sum += ((SmartRGBA)(data[((head+i)%total)*width+j]) * (vals[i])); } dest[j] = (RGBA)sum; } } }
std::ostream& dumpLine(std::ostream& os, unsigned int idx) { #if 0 if (idx >= size) throw StringError("Index into ClumpBuffer out of range"); #endif idx = idx + head; if (idx >= total) idx -= total; os << "[" << idx << "]: "; for (int w_idx = 0; w_idx < width; ++w_idx) { os << data[idx * width + w_idx]; if ((w_idx + 1) < width) os << ", "; } os << std::endl; return os; }
static int ReadKey(GTIF *gt, GTIFReadMethod scan, void *aux) { tagtype_t ktype; int count,outcount; int vals_now,i; geokey_t key; int icode; pinfo_t code; short *sptr; char name[1000]; char type[20]; double data[100]; double *dptr; char *vptr; int num; char message[2048]; scan(message,aux); if (!strncmp(message,FMT_KEYEND,8)) return 0; num=sscanf(message,"%[^( ] (%[^,],%d):\n",name,type,&count); if (num!=3) return StringError(message); vptr = message; FINDCHAR(vptr,':'); if (!*vptr) return StringError(message); vptr+=2; if( GTIFKeyCode(name) < 0 ) return StringError(name); else key = (geokey_t) GTIFKeyCode(name); if( GTIFTypeCode(type) < 0 ) return StringError(type); else ktype = (tagtype_t) GTIFTypeCode(type); /* skip white space */ SKIPWHITE(vptr); if (!*vptr) return StringError(message); switch (ktype) { case TYPE_ASCII: { char *cdata; int out_char = 0; FINDCHAR(vptr,'"'); if (!*vptr) return StringError(message); cdata = (char *) _GTIFcalloc( count+1 ); vptr++; while( out_char < count-1 ) { if( *vptr == '\0' ) break; else if( vptr[0] == '\\' && vptr[1] == 'n' ) { cdata[out_char++] = '\n'; vptr += 2; } else if( vptr[0] == '\\' && vptr[1] == '\\' ) { cdata[out_char++] = '\\'; vptr += 2; } else cdata[out_char++] = *(vptr++); } if( out_char < count-1 ) return StringError(message); if( *vptr != '"' ) return StringError(message); cdata[count-1] = '\0'; GTIFKeySet(gt,key,ktype,count,cdata); _GTIFFree( cdata ); } break; case TYPE_DOUBLE: outcount = count; for (dptr = data; count > 0; count-= vals_now) { vals_now = count > 3? 3: count; for (i=0; i<vals_now; i++,dptr++) { if (!sscanf(vptr,"%lg" ,dptr)) StringError(vptr); FINDCHAR(vptr,' '); SKIPWHITE(vptr); } if (vals_now<count) { scan(message,aux); vptr = message; } } if (outcount==1) GTIFKeySet(gt,key,ktype,outcount,data[0]); else GTIFKeySet(gt,key,ktype,outcount,data); break; case TYPE_SHORT: if (count==1) { icode = GTIFValueCode(key,vptr); if (icode < 0) return StringError(vptr); code = (pinfo_t) icode; GTIFKeySet(gt,key,ktype,count,code); } else /* multi-valued short - no such thing yet */ { char* cdata; memcpy(&cdata, &data, sizeof(void*)); sptr = (short *)cdata; outcount = count; for (; count > 0; count-= vals_now) { vals_now = count > 3? 3: count; for (i=0; i<vals_now; i++,sptr++) { int work_int; /* note: FMT_SHORT (%11hd) not supported on IRIX */ sscanf(message,"%11d",&work_int); *sptr = (short) work_int; scan(message,aux); } if (vals_now<count) { scan(message,aux); vptr = message; } } GTIFKeySet(gt,key,ktype,outcount,sptr); } break; default: return -1; } return 1; }
/* * call-seq: * Win32::API.new(function, prototype='V', return='L', dll='kernel32') * * Creates and returns a new Win32::API object. The +function+ is the name * of the Windows function. * * The +prototype+ is the function prototype for +function+. This can be a * string or an array of characters. The possible valid characters are 'I' * (integer), 'L' (long), 'V' (void), 'P' (pointer), 'K' (callback) or 'S' * (string). * * The default is void ('V'). * * Constant (const char*) strings should use 'S'. Pass by reference string * buffers should use 'P'. The former is faster, but cannot be modified. * * The +return+ argument is the return type for the function. The valid * characters are the same as for the +prototype+. The default is 'L' (long). * * The +dll+ is the name of the DLL file that the function is exported from. * The default is 'kernel32'. * * If the function cannot be found then an API::Error is raised (a subclass * of RuntimeError). * * Example: * * require 'win32/api' * include Win32 * * buf = 0.chr * 260 * len = [buf.length].pack('L') * * GetUserName = API.new('GetUserName', 'PP', 'I', 'advapi32') * GetUserName.call(buf, len) * * puts buf.strip */ static VALUE api_init(int argc, VALUE* argv, VALUE self) { HMODULE hLibrary; FARPROC fProc; Win32API* ptr; int i; char* first = "A"; char* second = "W"; VALUE v_proc, v_proto, v_return, v_dll; rb_scan_args(argc, argv, "13", &v_proc, &v_proto, &v_return, &v_dll); Data_Get_Struct(self, Win32API, ptr); // Convert a string prototype to an array of characters if(rb_respond_to(v_proto, rb_intern("split"))) v_proto = rb_str_split(v_proto, ""); // Convert a nil or empty prototype to 'V' (void) automatically if(NIL_P(v_proto) || RARRAY_LEN(v_proto) == 0){ v_proto = rb_ary_new(); rb_ary_push(v_proto, rb_str_new2("V")); } // Set an arbitrary limit of 20 parameters if(20 < RARRAY_LEN(v_proto)) rb_raise(rb_eArgError, "too many parameters: %d\n", RARRAY_LEN(v_proto)); // Set the default dll to 'kernel32' if(NIL_P(v_dll)) v_dll = rb_str_new2("kernel32"); // Set the default return type to 'L' (DWORD) if(NIL_P(v_return)) v_return = rb_str_new2("L"); SafeStringValue(v_dll); SafeStringValue(v_proc); hLibrary = LoadLibrary(TEXT(RSTRING_PTR(v_dll))); // The most likely cause of failure is a bad DLL load path if(!hLibrary){ rb_raise(cAPILoadError, "LoadLibrary() function failed for '%s': %s", RSTRING_PTR(v_dll), StringError(GetLastError()) ); } ptr->library = hLibrary; /* Attempt to get the function. If it fails, try again with an 'A' * appended. If that fails, try again with a 'W' appended. If that * still fails, raise an API::LoadLibraryError. */ fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_proc))); // Skip the ANSI and Wide function checks for MSVCRT functions. if(!fProc){ if(strstr(RSTRING_PTR(v_dll), "msvcr")){ rb_raise( cAPILoadError, "Unable to load function '%s'", RSTRING_PTR(v_proc) ); } else{ VALUE v_ascii = rb_str_new3(v_proc); v_ascii = rb_str_cat(v_ascii, first, 1); fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_ascii))); if(!fProc){ VALUE v_unicode = rb_str_new3(v_proc); v_unicode = rb_str_cat(v_unicode, second, 1); fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_unicode))); if(!fProc){ rb_raise( cAPILoadError, "Unable to load function '%s', '%s', or '%s'", RSTRING_PTR(v_proc), RSTRING_PTR(v_ascii), RSTRING_PTR(v_unicode) ); } else{ rb_iv_set(self, "@effective_function_name", v_unicode); } } else{ rb_iv_set(self, "@effective_function_name", v_ascii); } } } else{ rb_iv_set(self, "@effective_function_name", v_proc); } ptr->function = fProc; // Push the numeric prototypes onto our int array for later use. for(i = 0; i < RARRAY_LEN(v_proto); i++){ SafeStringValue(RARRAY_PTR(v_proto)[i]); switch(*(char*)StringValuePtr(RARRAY_PTR(v_proto)[i])){ case 'L': ptr->prototype[i] = _T_LONG; break; case 'P': ptr->prototype[i] = _T_POINTER; break; case 'I': case 'B': ptr->prototype[i] = _T_INTEGER; break; case 'V': ptr->prototype[i] = _T_VOID; break; case 'K': ptr->prototype[i] = _T_CALLBACK; break; case 'S': ptr->prototype[i] = _T_STRING; break; default: rb_raise(cAPIProtoError, "Illegal prototype '%s'", StringValuePtr(RARRAY_PTR(v_proto)[i]) ); } } // Store the return type for later use. // Automatically convert empty strings or nil to type void. if(NIL_P(v_return) || RSTRING_LEN(v_return) == 0){ v_return = rb_str_new2("V"); ptr->return_type = _T_VOID; } else{ SafeStringValue(v_return); switch(*RSTRING_PTR(v_return)){ case 'L': ptr->return_type = _T_LONG; break; case 'P': ptr->return_type = _T_POINTER; break; case 'I': case 'B': ptr->return_type = _T_INTEGER; break; case 'V': ptr->return_type = _T_VOID; break; case 'S': ptr->return_type = _T_STRING; break; default: rb_raise(cAPIProtoError, "Illegal return type '%s'", RSTRING_PTR(v_return) ); } } rb_iv_set(self, "@dll_name", v_dll); rb_iv_set(self, "@function_name", v_proc); rb_iv_set(self, "@prototype", v_proto); rb_iv_set(self, "@return_type", v_return); return self; }