+/*
+ * Copies the integer value of size #sourceSize# stored in #source# to the
+ * #destinationSize#-long area #destination#. #signedType# indicates whether
+ * or not the source integer is signed; #lowOrderFirst# whether or not the
+ * bytes run least-significant to most-significant.
+ *
+ * It should be thread safe (operates on local variables and calls mem*)
+ */
+static void
+gras_dd_resize_int(const void *source,
+ size_t sourceSize,
+ void *destination,
+ size_t destinationSize,
+ int signedType,
+ int lowOrderFirst) {
+
+ unsigned char *destinationSign;
+ int padding;
+ int sizeChange = destinationSize - sourceSize;
+ unsigned char *sourceSign;
+
+ if(sizeChange == 0) {
+ memcpy(destination, source, destinationSize);
+ } else if(sizeChange < 0) {
+ /* Truncate high-order bytes. */
+ memcpy(destination,
+ lowOrderFirst?source:((char*)source-sizeChange),
+ destinationSize);
+ if(signedType) {
+ /* Make sure the high order bit of source and
+ * destination are the same */
+ destinationSign = lowOrderFirst ? ((unsigned char*)destination + destinationSize - 1) : (unsigned char*)destination;
+ sourceSign = lowOrderFirst ? ((unsigned char*)source + sourceSize - 1) : (unsigned char*)source;
+ if((*sourceSign > 127) != (*destinationSign > 127)) {
+ if(*sourceSign > 127)
+ *destinationSign += 128;
+ else
+ *destinationSign -= 128;
+ }
+ }
+ } else {
+ /* Pad with zeros or extend sign, as appropriate. */
+ if(!signedType)
+ padding = 0;
+ else {
+ sourceSign = lowOrderFirst ? ((unsigned char*)source + sourceSize - 1)
+ : (unsigned char*)source;
+ padding = (*sourceSign > 127) ? 0xff : 0;
+ }
+ memset(destination, padding, destinationSize);
+ memcpy(lowOrderFirst ? destination
+ : ((char *)destination + sizeChange),
+ source, sourceSize);
+ }
+}
+
+