static enum mad_flow IoMP3Decoder_inputCallback(void *data, struct mad_stream *stream) { IoMP3Decoder *self = data; struct mad_decoder *decoder = &(DATA(self)->decoder); IoMessage_locals_performOn_(DATA(self)->willProcessMessage, self, self); if (DATA(self)->isRunning) { UArray *ba = IoSeq_rawUArray(DATA(self)->inputBuffer); UArray_removeRange(ba, 0, DATA(self)->lastInputPos); { size_t size = UArray_size(ba); UArray_setSize_(ba, size + MAD_BUFFER_GUARD); memset(UArray_bytes(ba) + size, 0x0, MAD_BUFFER_GUARD); UArray_setSize_(ba, size); } if (UArray_size(ba) == 0) { return MAD_FLOW_CONTINUE; } DATA(self)->lastInputPos = UArray_size(ba); mad_stream_buffer(stream, UArray_bytes(ba), UArray_size(ba)); } return DATA(self)->isRunning ? MAD_FLOW_CONTINUE : MAD_FLOW_STOP; }
void Image_makeRGBA(Image *self) { if (self->componentCount == 3) { //Image_addAlpha(self); //printf("converted component count from 3 to 4\n"); } else if (self->componentCount == 1) { UArray *outUArray = UArray_new(); UArray_setSize_(outUArray, 4 * self->width * self->height); uint8_t *outData = (uint8_t *)UArray_bytes(outUArray); uint8_t *inData = (uint8_t *)UArray_bytes(self->byteArray); size_t numPixels = self->width * self->height; size_t p1; size_t p2 = 0; for (p1 = 0; p1 < numPixels; p1 ++) { outData[p2] = inData[p1]; p2 ++; outData[p2] = inData[p1]; p2 ++; outData[p2] = inData[p1]; p2 ++; outData[p2] = 255; p2 ++; } UArray_copy_(self->byteArray, outUArray); UArray_free(outUArray); self->componentCount = 4; //printf("converted component count from 1 to 4\n"); } }
UArray *Date_asString(const Date *self, const char *format) { UArray *u = UArray_new(); time_t t = self->tv.tv_sec; struct tm *tm = localtime(&t); // what about unicode formats? UArray_setSize_(u, 1024 + strlen(format)); strftime((char *)UArray_bytes(u), 1024, format, tm); UArray_setSize_(u, strlen((char *)UArray_bytes(u))); return u; }
IoObject *IoAsyncRequest_write(IoAsyncRequest *self, IoObject *locals, IoMessage *m) { /*doc AsyncRequest write(fileOffset, aSeq, bufferOffset, numberOfBytesToWrite) Submits an async write request. Returns nil on error, self otherwise. */ int r; IoSeq *data; UArray *ba; int bufferOffset; int bytesToWrite; IOCB(self)->aio_offset = (size_t)CNUMBER(IoMessage_locals_numberArgAt_(m, locals, 0)); data = IoMessage_locals_seqArgAt_(m, locals, 1); ba = IoSeq_rawUArray(data); bufferOffset = IoMessage_locals_intArgAt_(m, locals, 2); bytesToWrite = IoMessage_locals_intArgAt_(m, locals, 3); if (bytesToWrite > UArray_size(ba) - bufferOffset) { bytesToWrite = UArray_size(ba) - bufferOffset; } IOCB(self)->aio_nbytes = bytesToWrite; IOCB(self)->aio_buf = realloc(IOCB_BUFFER(self), bytesToWrite); memcpy(IOCB_BUFFER(self), UArray_bytes(ba), bytesToWrite); r = aio_write(IOCB(self)); return r == 0 ? self : IONIL(self); }
IO_METHOD(IoSeq, asBinaryNumber) { /*doc Sequence asBinaryNumber Returns a Number containing the first 8 bytes of the receiver without casting them to a double. Endian is same as machine. */ IoNumber *byteCount = IoMessage_locals_valueArgAt_(m, locals, 0); size_t max = UArray_size(DATA(self)); int bc = sizeof(double); double d = 0; if (!ISNIL(byteCount)) { bc = IoNumber_asInt(byteCount); } if (max < bc) { IoState_error_(IOSTATE, m, "requested first %i bytes, but Sequence only contians %i bytes", bc, max); } memcpy(&d, UArray_bytes(DATA(self)), bc); return IONUMBER(d); }
Datum Datum_FromUArray_(UArray *ba) { Datum d; d.data = (unsigned char *)UArray_bytes(ba); d.size = UArray_sizeInBytes(ba); return d; }
IO_METHOD(IoSeq, asBinarySignedInteger) { /*doc Sequence asBinarySignedInteger Returns a Number with the bytes of the receiver interpreted as a binary signed integer. Endian is same as machine. */ const void *bytes = UArray_bytes(DATA(self)); size_t byteCount = UArray_size(DATA(self)); if(byteCount == 1) { return IONUMBER(*((const int8_t *)bytes)); } else if(byteCount == 2) { return IONUMBER(*((const int16_t *)bytes)); } else if(byteCount == 4) { return IONUMBER(*((const int32_t *)bytes)); } else { IoState_error_(IOSTATE, m, "Sequence is %i bytes but only conversion of 1, 2, or 4 bytes is supported", byteCount); } return IONIL(self); }
ImageBounds Image_bounds(Image *self, int cutoff) { int componentCount = self->componentCount; uint8_t *d = (uint8_t *)UArray_bytes(self->byteArray); ImageBounds bounds; int x, y; bounds.xmin = self->width; bounds.xmax = 0; bounds.ymin = self->height; bounds.ymax = 0; for (y = 0; y < self->height; y ++) { for (x = 0; x < self->width; x ++) { int p = (x + (y * self->width)) * componentCount; int c; for (c = 0; c < componentCount; c ++) { if (d[p + c] < cutoff) { if(x < bounds.xmin) bounds.xmin = x; if(x > bounds.xmax) bounds.xmax = x; if(y < bounds.ymin) bounds.ymin = y; if(y > bounds.ymax) bounds.ymax = y; break; } } } } return bounds; }
static enum mad_flow IoMP3Decoder_outputCallback(void *data, struct mad_header const *header, struct mad_pcm *pcm) { IoMP3Decoder *self = data; UArray *ba = IoSeq_rawUArray(DATA(self)->outputBuffer); unsigned int oldSize = UArray_size(ba); unsigned int newSize = oldSize + (pcm->length * 2 * sizeof(float)); UArray_setSize_(ba, newSize); if (!DATA(self)->isRunning) { return MAD_FLOW_STOP; } // MAD data is in 4 byte signed ints // and on separated (not interleaved channels) // so we interleave them here { float *out = (float *)(UArray_bytes(ba) + oldSize); unsigned int nsamples = pcm->length; mad_fixed_t const *left = pcm->samples[0]; mad_fixed_t const *right = pcm->samples[1]; if (pcm->channels == 2) { // this would be much faster as a vector op while (nsamples --) { *out = ((float)(*left)) / INT_MAX; out ++; *out = ((float)(*right)) / INT_MAX; out ++; left ++; right ++; } } else { while (nsamples --) { float f = ((float)(*left)) / INT_MAX; *out = f; out ++; *out = f; out ++; left ++; } } } IoMessage_locals_performOn_(DATA(self)->didProcessMessage, self, self); return DATA(self)->isRunning ? MAD_FLOW_CONTINUE : MAD_FLOW_STOP; }
IoObject *IoZlibEncoder_process(IoZlibEncoder *self, IoObject *locals, IoMessage *m) { /*doc ZlibEncoder process Process the inputBuffer and appends the result to the outputBuffer. The processed inputBuffer is empties except for the spare bytes at the end which don't fit into a cipher block. */ z_stream *strm = DATA(self)->strm; UArray *input = IoObject_rawGetMutableUArraySlot(self, locals, m, IOSYMBOL("inputBuffer")); UArray *output = IoObject_rawGetMutableUArraySlot(self, locals, m, IOSYMBOL("outputBuffer")); uint8_t *inputBytes = (uint8_t *)UArray_bytes(input); size_t inputSize = UArray_sizeInBytes(input); if (inputSize) { int ret; size_t oldOutputSize = UArray_size(output); size_t outputRoom = (inputSize * 2); uint8_t *outputBytes; UArray_setSize_(output, oldOutputSize + outputRoom); outputBytes = (uint8_t *)UArray_bytes(output) + oldOutputSize; strm->next_in = inputBytes; strm->avail_in = inputSize; strm->next_out = outputBytes; strm->avail_out = outputRoom; ret = deflate(strm, Z_NO_FLUSH); //assert(ret != Z_STREAM_ERROR); { size_t outputSize = outputRoom - strm->avail_out; UArray_setSize_(output, oldOutputSize + outputSize); } UArray_setSize_(input, 0); } return self; }
ColorStruct Image_averageColor(Image *self) { int componentCount = self->componentCount; uint8_t *d = (uint8_t *)UArray_bytes(self->byteArray); int x, y, c; long cs[4]; ColorStruct s; cs[0] = 0; cs[1] = 0; cs[2] = 0; cs[3] = 0; for (y = 0; y < self->height; y ++) { for (x = 0; x < self->width; x ++) { int p = (x + (y * self->width))*componentCount; int c; for (c = 0; c < componentCount; c ++) { cs[c] += d[p + c]; } } } //printf("color %i %i %i\n", (int)cs[0], (int)cs[1], (int)cs[2]); for (c = 0; c < componentCount; c ++) { cs[c] /= (self->width * self->height); } //printf("color %i %i %i\n", (int)cs[0], (int)cs[1], (int)cs[2]); if (componentCount == 1) { s.r = cs[0]; s.g = cs[0]; s.b = cs[0]; s.a = cs[0]; } else { s.r = cs[0]; s.g = cs[1]; s.b = cs[2]; s.a = cs[3]; } //printf("color struct %i %i %i\n", s.r, s.g, s.b); return s; }
uint8_t BStream_readUint8(BStream *self) { if (self->index < UArray_size(self->ba)) { unsigned char b = UArray_bytes(self->ba)[self->index]; self->index ++; return b; } return 0; }
unsigned char *BStream_readDataOfLength_(BStream *self, size_t length) { if (self->index + length <= UArray_size(self->ba)) { unsigned char *b = (unsigned char *)UArray_bytes(self->ba) + self->index; self->index += length; return b; } return NULL; }
int IoSeq_rawIsNotAlphaNumeric(IoSeq *self) { char *s = (char *)UArray_bytes(DATA(self)); while (!isalnum((int)*s) && *s != 0) { s ++; } return (*s == 0); }
IoObject *IoLZOEncoder_process(IoLZOEncoder *self, IoObject *locals, IoMessage *m) { /*doc LZOEncoder process Process the inputBuffer and appends the result to the outputBuffer. The processed inputBuffer is emptied except for the spare bytes at the end which don't fit into a cipher block. */ lzo_align_t __LZO_MMODEL *wrkmem = DATA(self)->wrkmem; UArray *input = IoObject_rawGetMutableUArraySlot(self, locals, m, IOSYMBOL("inputBuffer")); UArray *output = IoObject_rawGetMutableUArraySlot(self, locals, m, IOSYMBOL("outputBuffer")); unsigned char *inputBytes = (uint8_t *)UArray_bytes(input); size_t inputSize = UArray_sizeInBytes(input); if (inputSize) { int r; size_t oldOutputSize = UArray_size(output); lzo_uint outputRoom = (inputSize + inputSize / 64 + 16 + 3); unsigned char *outputBytes; UArray_setSize_(output, oldOutputSize + outputRoom); outputBytes = (uint8_t *)UArray_bytes(output) + oldOutputSize; r = lzo1x_1_compress(inputBytes, inputSize, outputBytes, &outputRoom, wrkmem); // r = lzo1x_decompress(in, in_len, out, &out_len, wrkmem); if (r != LZO_E_OK) { IoState_error_(IOSTATE, m, "LZO compression failed: %d", r); } UArray_setSize_(output, oldOutputSize + outputRoom); UArray_setSize_(input, 0); } return self; }
inline unsigned char *Image_pixelAt(Image *self, int x, int y) { int bps = 8; int spp = Image_componentCount(self); int w = self->width; int h = self->height; uint8_t *p = (uint8_t *)UArray_bytes(self->byteArray); if (x < 0) { x = 0; } else if (x > w - 1) { x = w - 1; } if (y < 0) { y = 0; } else if (y > h - 1) { y = h - 1; } return p + (((x + (y * w)) * (spp * bps)) / 8); }
IoObject *IoBlowfish_beginProcessing(IoObject *self, IoObject *locals, IoMessage *m) { /*doc Blowfish beginProcessing Sets the key from the key slot and initializes the cipher. */ UArray *key = IoObject_rawGetUArraySlot(self, locals, m, IOSYMBOL("key")); blowfish_ctx *context = &(DATA(self)->context); blowfish_init(context, (uint8_t *)UArray_bytes(key), UArray_sizeInBytes(key)); return self; }
int UArray_isMultibyte(const UArray *self) { if (self->encoding == CENCODING_UTF8) { size_t i, max = UArray_sizeInBytes(self); const uint8_t *bytes = UArray_bytes(self); for (i = 0; i < max; i ++) { if (UArray_SizeOfUTF8Char(bytes + i) > 1) return 1; } //UARRAY_INTFOREACH(self, i, v, if (ismbchar((int)v)) return 1; ); } return 0; }
IoObject *IoMP3Encoder_encode(IoMP3Encoder *self, IoObject *locals, IoMessage *m) { UArray *inBa = IoBuffer_rawUArray(IoMessage_locals_bufferArgAt_(m, locals, 0)); /*UArray *outBa = IoBuffer_rawUArray(DATA(self)->outBuffer);*/ int start = 0; int end = UArray_length(inBa); if (IoMessage_argCount(m) > 1) start = IoMessage_locals_intArgAt_(m, locals, 1); if (IoMessage_argCount(m) > 2) end = IoMessage_locals_intArgAt_(m, locals, 2); if (start > end) { IoState_error_description_(IOSTATE, m, "MP3Encoder", "range error: start > end"); } if (end > UArray_length(inBa)) { IoState_error_description_(IOSTATE, m, "MP3Encoder", "range error: end > length of input buffer"); } MP3Encoder_encode(DATA(self)->encoder, UArray_bytes(inBa) + start, end); return IoMP3Encoder_checkError(self, locals, m); }
void Image_resizeTo(Image *self, int w, int h, Image *outImage) { int componentCount = self->componentCount; int inStride = self->width * componentCount; uint8_t *inPtr = Image_data(self); int outStride = w * componentCount; uint8_t *outPtr; int y; UArray *outUArray = UArray_new(); UArray_setSize_(outUArray, h * outStride); outPtr = (uint8_t *)UArray_bytes(outUArray); for (y=0; y < self->height; y++, inPtr += inStride, outPtr += outStride) memcpy(outPtr, inPtr, inStride); Image_setData_width_height_componentCount_(outImage, outUArray, w, h, componentCount); }
IoObject *IoTokyoCabinetPrefixCursor_last(IoObject *self, IoObject *locals, IoMessage *m) { /*doc TokyoCabinetPrefixCursor last Move cursor to last record. Returns self */ IoSeq *prefix = IoObject_getSlot_(self, IOSYMBOL("prefix")); IOASSERT(ISSEQ(prefix), "prefix must be a sequence"); IOASSERT(TokyoCabinetPrefixCursor(self), "invalid TokyoCabinetPrefixCursor"); { UArray *p = UArray_clone(IoSeq_rawUArray(prefix)); UArray_appendCString_(p, " "); // space preceeds . tcbdbcurjump(TokyoCabinetPrefixCursor(self), (const void *)UArray_bytes(p), (int)UArray_size(p)); UArray_free(p); } return IOBOOL(self, IoTokyoCabinetPrefixCursor_keyBeginsWithPrefix_(self, prefix)); }
IoObject *IoBlowfish_process(IoBlowfish *self, IoObject *locals, IoMessage *m) { /*doc Blowfish process Process the inputBuffer and appends the result to the outputBuffer. The processed inputBuffer is empties except for the spare bytes at the end which don't fit into a cipher block. */ blowfish_ctx *context = &(DATA(self)->context); int isEncrypting = DATA(self)->isEncrypting; UArray *input = IoObject_rawGetMutableUArraySlot(self, locals, m, IOSYMBOL("inputBuffer")); UArray *output = IoObject_rawGetMutableUArraySlot(self, locals, m, IOSYMBOL("outputBuffer")); const unsigned char *inputBytes = (uint8_t *)UArray_bytes(input); size_t inputSize = UArray_sizeInBytes(input); unsigned long lr[2]; size_t i, runs = inputSize / sizeof(lr); for (i = 0; i < runs; i ++) { memcpy(lr, inputBytes, sizeof(lr)); inputBytes += sizeof(lr); if (isEncrypting) { blowfish_encrypt(context, &lr[0], &lr[1]); } else { blowfish_decrypt(context, &lr[0], &lr[1]); } UArray_appendBytes_size_(output, (unsigned char *)&lr, sizeof(lr)); } UArray_removeRange(input, 0, runs * sizeof(lr)); return self; }
void BStream_readNumber_size_(BStream *self, unsigned char *v, int size) { if (self->index + size <= UArray_size(self->ba)) { const uint8_t *b = UArray_bytes(self->ba); memcpy(v, b + self->index, size); if (self->flipEndian) { reverseBytes(v, size); } self->index += size; return; } while (size--) { *v = 0; v ++; } }
void TIFFImage_save(TIFFImage *self) { TIFF *out = TIFFOpen(self->path, "w"); if (out == NULL) { TIFFImage_error_(self, "error opening tiff for writing"); } /*TIFFSetField(out, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE);*/ TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) self->width); TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) self->height); /* ????? */ TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, (uint32) self->height); /* ????? */ TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, (uint16) 8); TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, (uint16) self->components); TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS); TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); /* cpTag(in, out, TIFFTAG_SOFTWARE, (uint16) -1, TIFF_ASCII); cpTag(in, out, TIFFTAG_IMAGEDESCRIPTION, (uint16) -1, TIFF_ASCII); cpTag(in, out, TIFFTAG_DATETIME, (uint16) -1, TIFF_ASCII); cpTag(in, out, TIFFTAG_HOSTCOMPUTER, (uint16) -1, TIFF_ASCII); */ { uint32 diroff[1]; diroff[0] = 0; TIFFSetField(out, TIFFTAG_SUBIFD, 1, diroff); } if (TIFFWriteEncodedStrip(out, 0, (tdata_t)(UArray_bytes(self->byteArray)), self->width*self->height*self->components) != -1) { TIFFImage_error_(self, "error writing tiff"); } /* else if (TIFFWriteDirectory(out) != -1); { TIFFImage_error_(self, "error writing tiff directory"); } */ (void) TIFFClose(out); }
IoObject *IoBlowfish_endProcessing(IoBlowfish *self, IoObject *locals, IoMessage *m) { /*doc Blowfish endProcessing Finish processing remaining bytes of inputBuffer. */ blowfish_ctx *context = &(DATA(self)->context); unsigned long lr[2]; IoBlowfish_process(self, locals, m); // process the full blocks first { int isEncrypting = DATA(self)->isEncrypting; UArray *input = IoObject_rawGetMutableUArraySlot(self, locals, m, IOSYMBOL("inputBuffer")); UArray *output = IoObject_rawGetMutableUArraySlot(self, locals, m, IOSYMBOL("outputBuffer")); IOASSERT(UArray_sizeInBytes(input) < sizeof(lr), "internal error - too many bytes left in inputBuffer"); memset(lr, 0, sizeof(lr)); memcpy(lr, (uint8_t *)UArray_bytes(input), UArray_sizeInBytes(input)); if (isEncrypting) { blowfish_encrypt(context, &lr[0], &lr[1]); } else { blowfish_decrypt(context, &lr[0], &lr[1]); } UArray_appendBytes_size_(output, (unsigned char *)&lr, sizeof(lr)); UArray_setSize_(input, 0); } return self; }
int IoAVCodec_decodeAudioPacket(IoAVCodec *self, AVCodecContext *c, uint8_t *inbuf, size_t size) { UArray *outba = IoSeq_rawUArray(DATA(self)->outputBuffer); uint8_t *outbuf = DATA(self)->audioOutBuffer; //UArray_setItemType_(outba, CTYPE_float32_t); while (size > 0) { int outSize; int len = avcodec_decode_audio2(c, (int16_t *)outbuf, &outSize, inbuf, size); if (len < 0) { printf("Error while decoding audio packet\n"); return -1; } if (outSize > 0) { // if a frame has been decoded, output it // convert short ints to floats size_t sampleCount = outSize / c->channels; size_t oldSize = UArray_size(outba); //UArray_setSize_(outba, oldSize + sampleCount); // knows it's a float32 array UArray_setSize_(outba, oldSize + sampleCount * sizeof(float)); // knows it's a float32 array IoAVCodec_ConvertShortToFloat((short *)outbuf, (float *)(UArray_bytes(outba) + oldSize), sampleCount); } size -= len; inbuf += len; } return 0; }
int Image_baselineHeight(Image *self) { //size_t numPixels = self->width * self->height; /* printf("self->componentCount: %i\n", self->componentCount); printf("numPixels: %i\n", (int)numPixels); printf("height: %i\n", (int)self->height); printf("width: %i\n", (int)self->width); */ // optimize later int componentCount = self->componentCount; int base = 0; uint8_t *d = (uint8_t *)UArray_bytes(self->byteArray); int x, y; for (y = 0; y < self->height; y ++) //for (y = self->height; y > 0; y --) { for (x = 0; x < self->width; x ++) { int p = (x + (y * self->width))*componentCount; int c; for (c = 0; c < componentCount; c ++) { if (d[p + c] < 200) { base = y; break; } } } } //printf("base = %i\n", base); return self->height - base; }
IoObject *IoTokyoCabinetPrefixCursor_jump(IoObject *self, IoObject *locals, IoMessage *m) { /*doc TokyoCabinetPrefixCursor jump(key) Move cursor to record before key. Returns self */ IoSeq *key = IoMessage_locals_seqArgAt_(m, locals, 0); int result; UArray *p; IoSeq *prefix = IoObject_getSlot_(self, IOSYMBOL("prefix")); IOASSERT(ISSEQ(prefix), "prefix must be a sequence"); p = UArray_clone(IoSeq_rawUArray(prefix)); UArray_appendPath_(p, IoSeq_rawUArray(key)); result = tcbdbcurjump(TokyoCabinetPrefixCursor(self), (const void *)UArray_bytes(p), (int)UArray_sizeInBytes(p)); UArray_free(p); IOASSERT(TokyoCabinetPrefixCursor(self), "invalid TokyoCabinetPrefixCursor"); return IOBOOL(self, result); }
int IoSeq_rawEqualsCString_(IoSeq *self, const char *s) { return (strcmp((char *)UArray_bytes(DATA(self)), s) == 0); }
double IoSeq_asDouble(IoSeq *self) { return strtod((char *)UArray_bytes(DATA(self)), NULL); }