VBoolean VUnpackData (VRepnKind repn, size_t nels, VPointer packed, VPackOrder packed_order, size_t *length, VPointer *unpacked, VBoolean *alloced) { VPackOrder unpacked_order; size_t unpacked_elsize = VRepnSize (repn) * CHAR_BIT; size_t packed_elsize = VRepnPrecision (repn); size_t unpacked_length = nels * VRepnSize (repn); /* If a space for the unpacked data was supplied, ensure there's enough of it: */ if (! alloced && unpacked_length > *length) { VWarning ("VUnpackData: Insufficient space for unpacked data"); return FALSE; } *length = unpacked_length; /* Determine the present machine's internal byte order: */ unpacked_order = MachineByteOrder (); /* If the desired byte order matches that of the present machine's, and the unpacked and packed data element sizes are identical, just return the packed data: */ if (unpacked_order == packed_order && unpacked_elsize == packed_elsize) { if (alloced) { *unpacked = packed; *alloced = FALSE; } else if (packed != *unpacked) memcpy (*unpacked, packed, unpacked_length); return TRUE; } /* Unpack data elements into the buffer: */ if (packed_elsize == unpacked_elsize) { /* If the packed and unpacked are the same size, do a straight copy: */ if (packed != *unpacked) memcpy (*unpacked, packed, unpacked_length); /* Swap bytes if necessary: */ if (packed_order != unpacked_order && packed_elsize > 8) SwapBytes (nels, packed_elsize / 8, (char *) *unpacked); } else if (packed_elsize == 1) { /* If the elements are VBits, this unpacks them: */ VUnpackBits (nels, packed_order, (char *) packed, (char *) *unpacked); } else /* Unpacking multi-byte integers or floats is currently not supported: */ VError ("VUnpackData: " "Unpacking %s from %d to %d bits is not supported", VRepnName (repn), packed_elsize, unpacked_elsize); return TRUE; }
static int ParseArgValues (int *arg, int argc, char **argv, VOptionDescRec *opt) { VArgVector *vec = (VArgVector *) opt->value; VPointer values; int nvalues = 0; VDictEntry *dict = opt->dict; char *cp; /* Locate the place we're to store the argument values: */ if (opt->number == 0) { /* If a variable number of arguments is expected, allocate storage to hold them: */ vec->vector = values = VMalloc ((argc - *arg) * VRepnSize (opt->repn)); } else values = opt->value; /* If no dictionary is specified for a boolean-valued option, use the default one of true, false, yes, no... */ if (opt->repn == VBooleanRepn && ! dict) dict = VBooleanDict; /* Parse argument values until we've reached the required number, we've run out of entered arguments, or we encounter one that is ill-formed: */ while ((opt->number == 0 || nvalues < opt->number) && (*arg < argc)) { cp = argv[*arg]; /* Special treatment for string-valued options: */ if (opt->repn == VStringRepn) { /* An argument of the form -string is not interpreted as a string value: */ if (cp[0] == '-' && cp[1] != 0 && cp[1] != '-') break; /* An argument of the form --string is interpreted as string: */ if (cp[0] == '-' && cp[1] == '-' && cp[2] != 0) cp += 2; } /* Convert the argument to the specified internal form: */ if (! VDecodeAttrValue (cp, dict, opt->repn, values)) break; nvalues++; values = (VPointer) ((char *) values + VRepnSize (opt->repn)); argv[(*arg)++] = NULL; } /* Special treatment of boolean-valued options: if the option has just one value associated with it then treat -option <other options> like -option true <other options>: */ if (opt->repn == VBooleanRepn && opt->number == 1 && nvalues == 0) { * (VBoolean *) opt->value = TRUE; nvalues = 1; } return nvalues; }
int VPrintOptionValue (FILE *f, VOptionDescRec *option) { int n, i, col = 0; char *vp; VDictEntry *dict; VLong ivalue; VDouble fvalue = 0.0; VStringConst svalue; if (option->number == 0) { n = ((VArgVector *) option->value)->number; vp = (char *) ((VArgVector *) option->value)->vector; } else { n = option->number; vp = (char *) option->value; } for (i = 0; i < n; i++, vp += VRepnSize (option->repn)) { if (i > 0) fputc (' ', f); switch (option->repn) { case VBitRepn: ivalue = * (VBit *) vp; goto PrintLong; case VUByteRepn: ivalue = * (VUByte *) vp; goto PrintLong; case VSByteRepn: ivalue = * (VSByte *) vp; goto PrintLong; case VShortRepn: ivalue = * (VShort *) vp; goto PrintLong; case VLongRepn: ivalue = * (VLong *) vp; PrintLong: if (option->dict && (dict = VLookupDictValue (option->dict, VLongRepn, ivalue))) col += fprintf (f, "%s", dict->keyword); else col += fprintf (f, "%ld", ivalue); break; case VFloatRepn: fvalue = * (VFloat *) vp; goto PrintDbl; case VDoubleRepn: fvalue = * (VDouble *) vp; PrintDbl: if (option->dict && (dict = VLookupDictValue (option->dict, VDoubleRepn, fvalue))) col += fprintf (f, "%s", dict->keyword); else col += fprintf (f, "%g", fvalue); break; case VBooleanRepn: col += fprintf (f, "%s", * (VBoolean *) vp ? "true" : "false"); break; case VStringRepn: svalue = * (VString *) vp; if (! svalue) svalue = "(none)"; else if (option->dict && (dict = VLookupDictValue (option->dict, VDoubleRepn, svalue))) svalue = dict->keyword; col += fprintf (f, "%s", svalue); break; default: break; } } return col; }
VImage VCreateImage (int nbands, int nrows, int ncolumns, VRepnKind pixel_repn) { size_t row_size = ncolumns * VRepnSize (pixel_repn); size_t data_size = nbands * nrows * row_size; size_t row_index_size = nbands * nrows * sizeof (char *); size_t band_index_size = nbands * sizeof (char **); size_t pixel_size; char *p; VImage image; int band, row; #define AlignUp(v, b) ((((v) + (b) - 1) / (b)) * (b)) /* Check parameters: */ if (nbands < 1) { VWarning ("VCreateImage: Invalid number of bands: %d", (int) nbands); return NULL; } if (nrows < 1) { VWarning ("VCreateImage: Invalid number of rows: %d", (int) nrows); return NULL; } if (ncolumns < 1) { VWarning ("VCreateImage: Invalid number of columns: %d", (int) ncolumns); return NULL; } if (pixel_repn != VBitRepn && pixel_repn != VUByteRepn && pixel_repn != VSByteRepn && pixel_repn != VShortRepn && pixel_repn != VLongRepn && pixel_repn != VFloatRepn && pixel_repn != VDoubleRepn) { VWarning ("VCreateImage: Invalid pixel representation: %d", (int) pixel_repn); return NULL; } /* Allocate memory for the VImage, its indices, and pixel values, while padding enough to ensure pixel values are appropriately aligned: */ pixel_size = VRepnSize (pixel_repn); p = VMalloc (AlignUp (sizeof (VImageRec) + row_index_size + band_index_size, pixel_size) + data_size); /* Initialize the VImage: */ image = (VImage) p; image->nbands = nbands; image->nrows = nrows; image->ncolumns = ncolumns; image->flags = VImageSingleAlloc; image->pixel_repn = pixel_repn; image->attributes = VCreateAttrList (); image->band_index = (VPointer **) (p += sizeof (VImageRec)); image->row_index = (VPointer *) (p += band_index_size); image->data = (VPointer) AlignUp ((long) p + row_index_size, pixel_size); image->nframes = nbands; image->nviewpoints = image->ncolors = image->ncomponents = 1; /* Initialize the indices: */ for (band = 0; band < nbands; band++) image->band_index[band] = image->row_index + band * nrows; for (row = 0, p = image->data; row < nbands * nrows; row++, p += row_size) image->row_index[row] = p; return image; #undef AlignUp }