NRTAPI(NRT_BOOL) nrt_Utils_parseGeographicString(char *dms, int *degrees, int *minutes, double *seconds, nrt_Error * error) { int degreeOffset = 0; int len = strlen(dms); char dir; char d[4]; char m[3]; char s[3]; /* ddmmssX or dddmmssY */ if (len == 7) { degreeOffset = 2; } else if (len == 8) { degreeOffset = 3; } else { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INVALID_PARAMETER, "Invalid decimal string: %s. Should be ddmmssX or dddmmssY", dms); return NRT_FAILURE; } dir = dms[len - 1]; if (dir != 'N' && dir != 'S' && dir != 'E' && dir != 'W') { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INVALID_PARAMETER, "Invalid direction: %s. Should be [NSEW]", dms); return NRT_FAILURE; } /* Now replace all spaces */ nrt_Utils_replace(dms, ' ', '0'); /* Now get the corners out as geographic coords */ d[degreeOffset] = 0; memcpy(d, dms, degreeOffset); memcpy(m, &dms[degreeOffset], 2); m[2] = 0; memcpy(s, &dms[degreeOffset + 2], 2); s[2] = 0; *degrees = NRT_ATO32(d); *minutes = NRT_ATO32(m); *seconds = (double) NRT_ATO32(s); if ((degreeOffset == 2 && dir == 'S') || (degreeOffset == 3 && dir == 'W')) { *degrees *= -1; } return NRT_SUCCESS; }
NRTAPI(NRT_BOOL) nrt_Utils_parseDecimalString(char *d, double *decimal, nrt_Error * error) { /* +-dd.ddd or += ddd.ddd */ int degreeOffset = 0; int len = strlen(d); char sign = d[0]; if (len == 7) { degreeOffset = 2; } else if (len == 8) { degreeOffset = 3; } else { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INVALID_PARAMETER, "Invalid decimal string: '%s'. Should be +-dd.ddd or +-ddd.ddd", d); return NRT_FAILURE; } /* Now replace all spaces */ nrt_Utils_replace(d, ' ', '0'); *decimal = atof(&(d[1])); if (sign == '-') { *decimal *= -1; } return NRT_SUCCESS; }
NRTPROT(int) nrt_IntStack_pop(nrt_IntStack * stack, nrt_Error * error) { if ((stack->sp >= 0) && (stack->sp < NRT_INT_STACK_DEPTH)) { return stack->st[(stack->sp)--]; } /* This return value is nonsense. We need to */ nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INT_STACK_OVERFLOW, "Stack pointing at depth: %d", stack->sp); return 2147483647; }
NRTPROT(int) nrt_IntStack_push(nrt_IntStack * stack, int n, nrt_Error * error) { /* TODO: See above */ if ((stack->sp >= -1) && (stack->sp < NRT_INT_STACK_DEPTH - 1)) { stack->st[++(stack->sp)] = n; return 1; } nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INT_STACK_OVERFLOW, "Stack pointing at depth: %d", stack->sp); return 0; }
NRTPROT(int) nrt_IntStack_top(nrt_IntStack * stack, nrt_Error * error) { /* TODO: Someone should rewrite this class to not be so quirky */ /* It is inconsistent with the rest of the library */ if ((stack->sp >= 0) && (stack->sp < NRT_INT_STACK_DEPTH)) { return stack->st[stack->sp]; } nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INT_STACK_OVERFLOW, "Stack pointing at depth: %d", stack->sp); return 0; }
NRTAPI(nrt_DateTime *) nrt_DateTime_fromString(const char *string, const char *format, nrt_Error * error) { struct tm t; nrt_DateTime *dateTime = NULL; double millis = 0.0; /* NOTE: _NRT_strptime() does not use the tm_isdst flag at all. */ t.tm_isdst = -1; if (!_NRT_strptime(string, format, &t, &millis)) { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INVALID_OBJECT, "Unknown error caused by the call to strptime with string [%s] and format string [%s]", string, format); return NULL; } /* Create a DateTime object */ dateTime = (nrt_DateTime *) NRT_MALLOC(sizeof(nrt_DateTime)); if (!dateTime) { nrt_Error_init(error, NRT_STRERROR(NRT_ERRNO), NRT_CTXT, NRT_ERR_MEMORY); return NULL; } /* Initialize it from the tm struct * TODO: Update _NRT_strptime() to just use a DateTime directly */ dateTime->year = t.tm_year + 1900; /* 0-based so add 1 */ dateTime->month = t.tm_mon + 1; dateTime->dayOfMonth = t.tm_mday; dateTime->dayOfWeek = t.tm_wday + 1; dateTime->dayOfYear = t.tm_yday + 1; dateTime->hour = t.tm_hour; dateTime->minute = t.tm_min; dateTime->second = t.tm_sec + millis / 1000.0; /* Compute the # of milliseconds */ if (!nrt_DateTime_updateMillis(dateTime, error)) { NRT_FREE(dateTime); return NULL; } return dateTime; }
NRTAPI(nrt_Off) nrt_IOHandle_getSize(nrt_IOHandle handle, nrt_Error * error) { DWORD ret; DWORD highOff; nrt_Uint64 off; ret = GetFileSize(handle, &highOff); if ((ret == -1)) { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_STAT_FILE, "GetFileSize failed with error [%d]", GetLastError()); return (nrt_Off) - 1; } off = (nrt_Uint64)highOff; return (nrt_Off)((off << 32) + ret); }
NRTAPI(nrt_Off) nrt_IOHandle_seek(nrt_IOHandle handle, nrt_Off offset, int whence, nrt_Error * error) { LARGE_INTEGER largeInt; int lastError; largeInt.QuadPart = offset; largeInt.LowPart = SetFilePointer(handle, largeInt.LowPart, &largeInt.HighPart, whence); lastError = GetLastError(); if ((largeInt.LowPart == INVALID_SET_FILE_POINTER) && (lastError != NO_ERROR)) { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_SEEKING_IN_FILE, "SetFilePointer failed with error [%d]", lastError); return (nrt_Off) - 1; } return (nrt_Off) largeInt.QuadPart; }
NRTAPI(nrt_List *) nrt_List_clone(nrt_List * source, NRT_DATA_ITEM_CLONE cloner, nrt_Error * error) { nrt_List *l = NULL; if (source) { nrt_ListIterator iter = nrt_List_begin(source); nrt_ListIterator end = nrt_List_end(source); l = nrt_List_construct(error); if (!l) return NULL; while (nrt_ListIterator_notEqualTo(&iter, &end)) { /* Foreach item in each list... */ NRT_DATA *data = nrt_ListIterator_get(&iter); /* Use the function pointer to clone the object... */ NRT_DATA *newData = (NRT_DATA *) cloner(data, error); if (!newData) return NULL; /* ... and then insert it with the key into the new table */ if (!nrt_List_pushBack(l, newData, error)) { /* destruct the created list. NOTE - there is no way for us to * destroy the NRT_DATA* chunks that have already been cloned */ nrt_List_destruct(&l); return NULL; } nrt_ListIterator_increment(&iter); } } else { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INVALID_OBJECT, "Trying to clone NULL pointer"); } return l; }
NRTAPI(NRT_BOOL) nrt_DateTime_formatMillis(double millis, const char *format, char *outBuf, size_t maxSize, nrt_Error * error) { time_t timeInSeconds; double fractSeconds; struct tm t; char *newFmtString = NULL; const char *endString = NULL; size_t begStringLen = 0; size_t formatLength; size_t startIndex = 0; size_t i, j; NRT_BOOL found = 0; timeInSeconds = (time_t) (millis / 1000); t = *gmtime(&timeInSeconds); fractSeconds = (millis / 1000.0) - timeInSeconds; /* Search for "%...S" string */ formatLength = strlen(format); for (i = 0; i < formatLength && !found; ++i) { if (format[i] == '%') { startIndex = i; for (j = startIndex + 1; j < formatLength; ++j) { if (format[j] == '%') { break; } if (format[j] == 'S') { found = 1; formatLength = j - startIndex + 1; begStringLen = startIndex; endString = format + j + 1; } } } } /* If we found a "%...S" string, parse it */ /* to find out how many decimal places to use */ if (found) { int decimalPlaces = 0; /* Figure out how many decimal places we need... */ for (i = startIndex + 1; i < startIndex + (formatLength - 1); ++i) { if (format[i] == '.') { /* The digits that follow should be */ /* the number of decimal places */ sscanf(format + i + 1, "%d", &decimalPlaces); } } if (decimalPlaces > 0) { char buf[256]; size_t newFmtLen = 0; size_t bufIdx = 0; size_t endStringLen = endString ? strlen(endString) : 0; newFmtLen = begStringLen + 1; newFmtString = (char *) NRT_MALLOC(newFmtLen); if (!newFmtString) { nrt_Error_init(error, NRT_STRERROR(NRT_ERRNO), NRT_CTXT, NRT_ERR_MEMORY); goto CATCH_ERROR; } memset(newFmtString, 0, newFmtLen); if (begStringLen > 0) { /* do the first part of the format */ strncpy(newFmtString, format, begStringLen); if (strftime(outBuf, maxSize, newFmtString, &t) == 0) { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INVALID_OBJECT, "Unknown error caused by the call to strftime with format string: [%s]", format); goto CATCH_ERROR; } bufIdx = strlen(outBuf); } /* do the seconds - separately */ memset(buf, 0, 256); if (strftime(buf, 256, "%S", &t) == 0) { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INVALID_OBJECT, "Unknown error caused by the call to strftime with format string: [%s]", format); goto CATCH_ERROR; } if (strlen(buf) + bufIdx + 1 > maxSize) { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INVALID_OBJECT, "Format string will cause buffer to overflow: [%s]", format); goto CATCH_ERROR; } /* tack it on the end */ strcpy(outBuf + bufIdx, buf); bufIdx = strlen(outBuf); memset(buf, 0, 256); NRT_SNPRINTF(buf, 256, "%.*f", decimalPlaces, fractSeconds); if (strlen(buf) + bufIdx + 1 > maxSize) { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INVALID_OBJECT, "Format string will cause buffer to overflow: [%s]", format); goto CATCH_ERROR; } /* tack on the fractional seconds - spare the leading 0 */ strcpy(outBuf + bufIdx, buf + 1); bufIdx = strlen(outBuf); if (endStringLen > 0) { /* tack on the end part */ memset(buf, 0, 256); if (strftime(buf, 256, endString, &t) == 0) { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INVALID_OBJECT, "Unknown error caused by the call to strftime with format string: [%s]", format); goto CATCH_ERROR; } if (strlen(buf) + bufIdx + 1 > maxSize) { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INVALID_OBJECT, "Format string will cause buffer to overflow: [%s]", format); goto CATCH_ERROR; } strcpy(outBuf + bufIdx, buf); } } } if (newFmtString == NULL) { if (strftime (outBuf, maxSize, newFmtString != NULL ? newFmtString : format, &t) == 0) { nrt_Error_initf(error, NRT_CTXT, NRT_ERR_INVALID_OBJECT, "Unknown error caused by the call to strftime with format string: [%s]", newFmtString != NULL ? newFmtString : format); goto CATCH_ERROR; } } else NRT_FREE(newFmtString); return NRT_SUCCESS; CATCH_ERROR: if (newFmtString) NRT_FREE(newFmtString); return NRT_FAILURE; }
int main(int argc, char **argv) { int rc = 0; int argIt = 0; char *inName = NULL, *outName = NULL; nrt_Error error; j2k_Component *component = NULL; j2k_Container *container = NULL; j2k_Writer *writer = NULL; j2k_WriterOptions options; char *buf = NULL; nrt_Uint64 bufSize; nrt_IOInterface *outIO = NULL; nrt_Uint32 width, height, precision, tileWidth, tileHeight; for (argIt = 1; argIt < argc; ++argIt) { if (!inName) { inName = argv[argIt]; } else if (!outName) { outName = argv[argIt]; } } /* hardcoded for now... */ width = 128; height = 128; precision = 8; tileWidth = width; tileHeight = height; if (!inName || !outName) { nrt_Error_initf(&error, NRT_CTXT, NRT_ERR_INVALID_OBJECT, "Usage: %s <raw-input> <output-j2k>", argv[0]); goto CATCH_ERROR; } if (!(component = j2k_Component_construct(width, height, precision, 0, 0, 0, 1, 1, &error))) { goto CATCH_ERROR; } if (!(container = j2k_Container_construct(width, height, 1, &component, tileWidth, tileHeight, J2K_TYPE_MONO, &error))) { goto CATCH_ERROR; } memset(&options, 0, sizeof(j2k_WriterOptions)); /* TODO set some options here */ if (!(writer = j2k_Writer_construct(container, &options, &error))) { goto CATCH_ERROR; } if (!readFile(inName, &buf, &bufSize, &error)) { goto CATCH_ERROR; } if (!j2k_Writer_setTile(writer, 0, 0, (nrt_Uint8*)buf, (nrt_Uint32)bufSize, &error)) { goto CATCH_ERROR; } if (!(outIO = nrt_IOHandleAdapter_open(outName, NRT_ACCESS_WRITEONLY, NRT_CREATE, &error))) goto CATCH_ERROR; if (!j2k_Writer_write(writer, outIO, &error)) goto CATCH_ERROR; goto CLEANUP; CATCH_ERROR: { nrt_Error_print(&error, stdout, "Exiting..."); rc = 1; } CLEANUP: { if (container) j2k_Container_destruct(&container); if (writer) j2k_Writer_destruct(&writer); if (buf) J2K_FREE(buf); if (outIO) nrt_IOInterface_destruct(&outIO); } return rc; }