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 AudioDevice_clearBuffers(AudioDevice *self) { AudioDevice_lock(self); UArray_setSize_(self->readBuffer, 0); UArray_setSize_(self->nextReadBuffer, 0); AudioDevice_unlock(self); }
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; }
void UArray_setItemType_(UArray *self, CTYPE type) { size_t itemSize = CTYPE_size(type); div_t q = div(UArray_sizeInBytes(self), itemSize); if (q.rem != 0) { q.quot += 1; UArray_setSize_(self, (q.quot * itemSize) / self->itemSize); } self->itemType = type; self->itemSize = itemSize; self->size = q.quot; // ensure encoding is sane for type if (UArray_isFloatType(self)) { self->encoding = CENCODING_NUMBER; } else if (self->encoding == CENCODING_ASCII) { switch(self->itemSize) { case 2: self->encoding = CENCODING_UCS2; break; case 4: self->encoding = CENCODING_UCS4; break; case 8: self->encoding = CENCODING_NUMBER; break; } } }
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"); } }
IoObject *IoODEMass_parameters(IoODEMass *self, IoObject *locals, IoMessage *m) { // vector(theMass, cgx, cgy, cgz, I11, I22, I33, I12, I13, I23) UArray *u = UArray_new(); int i, j = 0; UArray_setItemType_(u, CTYPE_float32_t); UArray_setSize_(u, 10); UArray_at_putDouble_(u, j++, DATA(self)->mass); for(i=0; i < 3; i++) { UArray_at_putDouble_(u, j++, DATA(self)->c[i]); } // 0 1 2 3 4 5 6 7 8 9 10 11 // I == vector(I11, I12, I13, _, I12, I22, I23, _, I13, I23, I33, _) UArray_at_putDouble_(u, j++, DATA(self)->I[0 ]); // I11 UArray_at_putDouble_(u, j++, DATA(self)->I[5 ]); // I22 UArray_at_putDouble_(u, j++, DATA(self)->I[10]); // I33 UArray_at_putDouble_(u, j++, DATA(self)->I[1 ]); // I12 UArray_at_putDouble_(u, j++, DATA(self)->I[2 ]); // I13 UArray_at_putDouble_(u, j++, DATA(self)->I[6 ]); // I23 return IoSeq_newWithUArray_copy_(IOSTATE, u, 1); }
void UArray_removeLastPathComponent(UArray *self) { UArray seps = UArray_stackAllocedWithCString_(IO_PATH_SEPARATORS); long pos = UArray_findLastPathComponent(self); if (pos) pos --; UArray_setSize_(self, pos); }
IOIMAGE_API IoObject *IoImage_filterGauss(IoImage *self, IoObject *locals, IoMessage *m) { /*doc Image filterGauss(sigma) Returns new image as a result of applying filter. Implements Gauss smoothing filtering with parameter sigma. */ double sigma = IoMessage_locals_doubleArgAt_(m, locals, 0); int filterSize = round(sigma * 2.5) * 2 + 1; UArray* filter = UArray_new(); UArray_setItemType_(filter, CTYPE_int8_t); UArray_setEncoding_(filter, CENCODING_NUMBER); UArray_setSize_(filter, filterSize * filterSize); int8_t *filterBytes = UArray_mutableBytes(filter); int x, y, x1, y1; for(y = 0; y < filterSize; y++) { y1 = y - filterSize / 2; for(x = 0; x < filterSize; x++) { x1 = x - filterSize / 2; filterBytes[x + y * filterSize] = exp(-(x1*x1 + y1*y1)/2/sigma) * filterSize * filterSize * 2; } } IoImage* toReturn = IoImage_newWithImage_(IOSTATE, Image_applyLinearFilter(DATA(self)->image, filterSize, filterSize, filter)); UArray_free(filter); return toReturn; }
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; }
void UArray_removePathExtension(UArray *self) { long pos = UArray_findPathExtension(self); if (pos != -1) { UArray_setSize_(self, pos); } }
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; }
IO_METHOD(IoSeq, setSize) { /*doc Sequence setSize(aNumber) Sets the length in bytes of the receiver to aNumber. Return self. */ size_t len = IoMessage_locals_sizetArgAt_(m, locals, 0); IO_ASSERT_NOT_SYMBOL(self); UArray_setSize_(DATA(self), len); return self; }
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; }
IO_METHOD(IoSeq, empty) { /*doc Sequence empty Sets all bytes in the receiver to 0x0 and sets its length to 0. Returns self. */ IO_ASSERT_NOT_SYMBOL(self); UArray_clear(DATA(self)); UArray_setSize_(DATA(self), 0); return self; }
IoObject *IoSeq_empty(IoSeq *self, IoObject *locals, IoMessage *m) { /*doc Sequence empty Sets all bytes in the receiver to 0x0 and sets it's length to 0. Returns self. */ IO_ASSERT_NOT_SYMBOL(self); UArray_clear(DATA(self)); UArray_setSize_(DATA(self), 0); return self; }
UArray *UArray_fromHexStringUArray(UArray *self) { size_t i, newSize = self->size / 2; UArray *ba = UArray_new(); UArray_setSize_(ba, newSize); for(i = 0; i < newSize; i ++) { int h = self->data[i*2]; int l = self->data[i*2+1]; ba->data[i] = (charFromHex(h)<<4) + charFromHex(l); } return ba; }
IOIMAGE_API IoObject *IoImage_filterMedian(IoImage *self, IoObject *locals, IoMessage *m) { /*doc Image filterMedian(filterSizeX, filterSizeY) Returns new image as a result of applying filter. */ int filterSizeX = IoMessage_locals_intArgAt_(m, locals, 0); int filterSizeY = IoMessage_locals_intArgAt_(m, locals, 1); UArray* filter = UArray_new(); UArray_setItemType_(filter, CTYPE_int8_t); UArray_setEncoding_(filter, CENCODING_NUMBER); UArray_setSize_(filter, filterSizeX * filterSizeY); memset(UArray_mutableBytes(filter), 1, filterSizeX * filterSizeY); IoImage* toReturn = IoImage_newWithImage_(IOSTATE, Image_applyWeightedMedianFilter(DATA(self)->image, filterSizeX, filterSizeY, filter)); UArray_free(filter); return toReturn; }
int AudioDevice_swapWriteBuffers(AudioDevice *self) { /* clear the current buffer */ UArray_setSize_(self->writeBuffer, 0); self->writeFrame = 0; /* swap if the next one has data */ if (UArray_size(self->nextWriteBuffer)) { void *b = self->writeBuffer; self->writeBuffer = self->nextWriteBuffer; self->nextWriteBuffer = b; //printf("swapping buffers self->needsData = 1\n"); self->needsData = 1; } return 0; }
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); }
IOIMAGE_API IoObject *IoImage_filterUnsharpMask(IoImage *self, IoObject *locals, IoMessage *m) { /*doc Image filterUnsharpMask(a) Returns new image as a result of applying filter. Implements unsharp mask filtering. The result is sharpened image. The parameter value may by any but it makes sense if it is > 0. */ int a = IoMessage_locals_intArgAt_(m, locals, 0); UArray* filter = UArray_new(); UArray_setItemType_(filter, CTYPE_int8_t); UArray_setEncoding_(filter, CENCODING_NUMBER); UArray_setSize_(filter, 9); int8_t *filterBytes = UArray_mutableBytes(filter); filterBytes[0] = -1; filterBytes[1] = -1; filterBytes[2] = -1; filterBytes[3] = -1; filterBytes[4] = a + 8; filterBytes[5] = -1; filterBytes[6] = -1; filterBytes[7] = -1; filterBytes[8] = -1; IoImage* toReturn = IoImage_newWithImage_(IOSTATE, Image_applyLinearFilter(DATA(self)->image, 3, 3, filter)); UArray_free(filter); return toReturn; }
IoObject *IoODEMass_inertiaTensor(IoODEMass *self, IoObject *locals, IoMessage *m) { UArray *u = UArray_new(); int i, j; UArray_setItemType_(u, CTYPE_float32_t); UArray_setSize_(u, 9); // I == vector(I11, I12, I13, _, I12, I22, I23, _, I13, I23, I33, _) for(i = 0, j = 0; i < 12; i++) { if ((i + 1) % 4) { UArray_at_putDouble_(u, j++, DATA(self)->I[i]); } } return IoSeq_newWithUArray_copy_(IOSTATE, u, 1); }
int AudioDevice_swapReadBuffers(AudioDevice *self) { int didSwap = 0; if (UArray_size(self->readBuffer)) { /* clear the next buffer */ UArray_setSize_(self->nextReadBuffer, 0); self->readFrame = 0; /* swap */ { void *b = self->readBuffer; self->readBuffer = self->nextReadBuffer; self->nextReadBuffer = b; } didSwap = 1; } return didSwap; }
UArray *IoBox_rawResizeBy(IoBox *self, UArray *d, int resizeWidth, int resizeHeight, UArray *minSize, UArray *maxSize) { double x, w, y, h; UArray *position = IoSeq_rawUArray(IoBox_rawOrigin(self)); UArray *size = IoSeq_rawUArray(IoBox_rawSize(self)); UArray *outd = UArray_new(); UArray_setItemType_(outd, CTYPE_float32_t); UArray_setSize_(outd, 2); x = resizeXFunc(resizeWidth, UArray_x(d), UArray_x(position)); w = resizeWFunc(resizeWidth, UArray_x(d), UArray_x(size)); y = resizeXFunc(resizeHeight, UArray_y(d), UArray_y(position)); h = resizeWFunc(resizeHeight, UArray_y(d), UArray_y(size)); if (minSize) { w = max(w, UArray_x(minSize)); h = max(h, UArray_y(minSize)); } if (maxSize) { w = min(w, UArray_x(maxSize)); h = min(h, UArray_y(maxSize)); } UArray_setXY(outd, w - UArray_x(size), h - UArray_y(size)); UArray_setXY(position, x, y); UArray_setXY(size, w, h); UArray_round(position); UArray_round(size); return outd; }
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; }
IoObject *IoRegexMatches_setRegex(IoRegexMatches *self, IoObject *locals, IoMessage *m) { /*doc RegexMatches setRegex(aRegexOrString) Sets the regex to find matches in. Returns self. */ IoObject *arg = IoMessage_locals_valueArgAt_(m, locals, 0); if (ISREGEX(arg)) DATA(self)->regex = IOREF(arg); else if(ISSYMBOL(arg)) DATA(self)->regex = IoRegex_newWithPattern_(IOSTATE, arg); else IoState_error_(IOSTATE, m, "The argument to setRegex must be either a Regex or a Sequence"); { /* Make the capture array big enough to hold the capture information and any other data pcre_exec may want to put in it. */ int size = (IoRegex_rawRegex(DATA(self)->regex)->captureCount + 1) * 3; UArray_setSize_(DATA(self)->captureArray, size); } IoRegexMatches_rawsetPosition_(self, 0); return self; }
void Image_crop(Image *self, int cx, int cy, int w, int h) { int pixelSize = Image_componentCount(self); int x, y; if (cx > self->width) { Image_error_(self, "crop x > width"); return; } if (cy > self->height) { Image_error_(self, "crop y > height"); return; } if (cx+w > self->width) { w = self->width - cx; } if (cy+h > self->height) { h = self->height - cy; } for (x = 0; x < w; x ++) { for (y = 0; y < h; y ++) { unsigned char *ip = Image_pixelAt(self, cx+x, cy+y); unsigned char *op = Image_pixelAt(self, x, y); memcpy(op, ip, pixelSize); } } UArray_setSize_(self->byteArray, w*h*pixelSize); self->width = w; self->height = h; }
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; }
IOIMAGE_API IoObject *IoImage_filterKirsch(IoImage *self, IoObject *locals, IoMessage *m) { /*doc Image filterKirsch(a) Returns new image as a result of applying Kirsch filter. The argument denotes direction: 0, 1, 2, ... -> 0, pi / 4, pi / 2, ... */ int a = IoMessage_locals_intArgAt_(m, locals, 0); a = ((a % 8) + 8) % 8; static int mapOfPixels[8] = {0, 1, 2, 5, 8, 7, 6, 3}; static int contentsOfPixels[8] = {3, 3, 3, 3, -5, -5, -5, 3}; UArray* filter = UArray_new(); UArray_setItemType_(filter, CTYPE_int8_t); UArray_setEncoding_(filter, CENCODING_NUMBER); UArray_setSize_(filter, 9); int8_t *filterBytes = UArray_mutableBytes(filter); int i; for(i = 0; i < 8; i++) { filterBytes[(i + a) % 8] = contentsOfPixels[i]; } IoImage* toReturn = IoImage_newWithImage_(IOSTATE, Image_applyLinearFilter(DATA(self)->image, 3, 3, filter)); UArray_free(filter); return toReturn; }
void IoSeq_rawSetSize_(IoSeq *self, size_t size) { UArray_setSize_(DATA(self), size); }
void PNGImage_load(PNGImage *self) { png_structp png_ptr; png_infop info_ptr; int bit_depth; int color_type; int interlace_type; png_uint_32 w; png_uint_32 h; int palleteComponents = 3; int number_passes, row; FILE *fp = fopen(self->path, "rb"); PNGImage_error_(self, ""); if (!fp) { PNGImage_error_(self, "file not found"); return; } /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also supply the * the compiler header file version, so that we know if the application * was compiled with a compatible version of the library. REQUIRED */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { fclose(fp); PNGImage_error_(self, "unable to read png from file"); return; } /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_read_struct(&(png_ptr), png_infopp_NULL, png_infopp_NULL); PNGImage_error_(self, "error allocating png struct"); return; } /* Set error handling if you are using the setjmp/longjmp method (this is * the normal method of doing things with libpng). REQUIRED unless you * set up your own error handlers in the png_create_read_struct() earlier. */ if (setjmp(png_jmpbuf(png_ptr))) { /* Free all of the memory associated with the png_ptr and info_ptr */ png_destroy_read_struct(&(png_ptr), &(info_ptr), png_infopp_NULL); fclose(fp); PNGImage_error_(self, self->path); return; } /* Set up the input control if you are using standard C streams */ png_init_io(png_ptr, fp); png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &w, &h, &(bit_depth), &(color_type), &(interlace_type), int_p_NULL, int_p_NULL); self->width = w; self->height = h; /* tell libpng to strip 16 bit/color files down to 8 bits/color */ png_set_strip_16(png_ptr); /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single * byte into separate bytes (useful for paletted and grayscale images). */ png_set_packing(png_ptr); /* Expand paletted colors into true RGB triplets */ /* if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_rgb(png_ptr); */ /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr); /* Expand paletted or RGB images with transparency to full alpha channels * so the data will be available as RGBA quartets. */ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png_ptr); palleteComponents = 4; } /* swap bytes of 16 bit files to least significant byte first */ /*png_set_swap(png_ptr);*/ /* Add filler (or alpha) byte (before/after each RGB triplet) */ /*png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);*/ /* Turn on interlace handling. REQUIRED if you are not using * png_read_image(). To see how to handle interlacing passes, * see the png_read_row() method below: */ number_passes = png_set_interlace_handling(png_ptr); /* Allocate the memory to hold the image using the fields of info_ptr. */ /* The easiest way to read the image: */ { /*png_bytep row_pointers[height];*/ png_bytep *row_pointers = (png_bytep *)malloc(self->height*sizeof(void *)); for (row = 0; row < self->height; row++) { /*int bpr = png_get_rowbytes(png_ptr, info_ptr);*/ int bpr = png_get_rowbytes(png_ptr, info_ptr) * 4; row_pointers[row] = png_malloc(png_ptr, bpr); } /* Now it's time to read the image. One of these methods is REQUIRED */ png_read_image(png_ptr, row_pointers); { int bytesPerRow; switch(color_type) { case PNG_COLOR_TYPE_GRAY: self->components = 1; break; case PNG_COLOR_TYPE_PALETTE: self->components = palleteComponents; break; case PNG_COLOR_TYPE_RGB: self->components = 3; break; case PNG_COLOR_TYPE_RGB_ALPHA: self->components = 4; break; case PNG_COLOR_TYPE_GRAY_ALPHA: self->components = 2; break; } bytesPerRow = self->width * self->components; UArray_setSize_(self->byteArray, self->width * self->height * self->components); for (row = 0; row < self->height; row++) { int i = row*(self->width*self->components); memcpy((uint8_t *)UArray_bytes(self->byteArray) + i, row_pointers[row], bytesPerRow); free(row_pointers[row]); } } free(row_pointers); } /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ png_read_end(png_ptr, (info_ptr)); /* At this point you have read the entire image */ /* clean up after the read, and free any memory allocated - REQUIRED */ png_destroy_read_struct(&(png_ptr), &(info_ptr), png_infopp_NULL); fclose(fp); return; }