bool OGG::Decode (Resource *resource, AudioBuffer *audioBuffer) { OggVorbis_File oggFile; Bytes *data = NULL; OAL_OggMemoryFile fakeFile; if (resource->path) { FILE_HANDLE *file = lime::fopen (resource->path, "rb"); if (!file) { return false; } if (file->isFile ()) { if (ov_open (file->getFile (), &oggFile, NULL, file->getLength ()) != 0) { lime::fclose (file); return false; } } else { lime::fclose (file); data = new Bytes (resource->path); fakeFile = OAL_OggMemoryFile (); fakeFile.data = data->Data (); fakeFile.size = data->Length (); fakeFile.pos = 0; if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) { delete data; return false; } } } else { fakeFile = OAL_OggMemoryFile (); fakeFile.data = resource->data->Data (); fakeFile.size = resource->data->Length (); fakeFile.pos = 0; if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) { return false; } } // 0 for Little-Endian, 1 for Big-Endian #ifdef HXCPP_BIG_ENDIAN #define BUFFER_READ_TYPE 1 #else #define BUFFER_READ_TYPE 0 #endif int bitStream; long bytes = 1; int totalBytes = 0; #define BUFFER_SIZE 4096 vorbis_info *pInfo = ov_info (&oggFile, -1); if (pInfo == NULL) { //LOG_SOUND("FAILED TO READ OGG SOUND INFO, IS THIS EVEN AN OGG FILE?\n"); ov_clear (&oggFile); if (data) { delete data; } return false; } audioBuffer->channels = pInfo->channels; audioBuffer->sampleRate = pInfo->rate; audioBuffer->bitsPerSample = 16; int dataLength = ov_pcm_total (&oggFile, -1) * audioBuffer->channels * audioBuffer->bitsPerSample / 8; audioBuffer->data->Resize (dataLength); while (bytes > 0) { bytes = ov_read (&oggFile, (char *)audioBuffer->data->Data () + totalBytes, BUFFER_SIZE, BUFFER_READ_TYPE, 2, 1, &bitStream); totalBytes += bytes; } if (dataLength != totalBytes) { audioBuffer->data->Resize (totalBytes); } ov_clear (&oggFile); #undef BUFFER_READ_TYPE if (data) { delete data; } return true; }
bool OGG::Decode (Resource *resource, AudioBuffer *audioBuffer) { OggVorbis_File oggFile; if (resource->path) { FILE_HANDLE *file = lime::fopen (resource->path, "rb"); if (!file) { return false; } if (file->isFile ()) { ov_open (file->getFile (), &oggFile, NULL, file->getLength ()); } else { ByteArray data = ByteArray (resource->path); OAL_OggMemoryFile fakeFile = { data.Bytes (), data.Size (), 0 }; if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) { return false; } } } else { OAL_OggMemoryFile fakeFile = { resource->data->Bytes (), resource->data->Size (), 0 }; if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) { return false; } } // 0 for Little-Endian, 1 for Big-Endian #ifdef HXCPP_BIG_ENDIAN #define BUFFER_READ_TYPE 1 #else #define BUFFER_READ_TYPE 0 #endif int bitStream; long bytes = 1; int totalBytes = 0; #define BUFFER_SIZE 32768 vorbis_info *pInfo = ov_info (&oggFile, -1); if (pInfo == NULL) { //LOG_SOUND("FAILED TO READ OGG SOUND INFO, IS THIS EVEN AN OGG FILE?\n"); return false; } audioBuffer->channels = pInfo->channels; audioBuffer->sampleRate = pInfo->rate; //default to 16? todo audioBuffer->bitsPerSample = 16; // Seem to need four times the read PCM total audioBuffer->data->Resize (ov_pcm_total (&oggFile, -1) * 4); while (bytes > 0) { if (audioBuffer->data->Size () < totalBytes + BUFFER_SIZE) { audioBuffer->data->Resize (totalBytes + BUFFER_SIZE); } bytes = ov_read (&oggFile, (char *)audioBuffer->data->Bytes () + totalBytes, BUFFER_SIZE, BUFFER_READ_TYPE, 2, 1, &bitStream); totalBytes += bytes; } audioBuffer->data->Resize (totalBytes); ov_clear (&oggFile); #undef BUFFER_SIZE #undef BUFFER_READ_TYPE return true; }
bool JPEG::Decode (Resource *resource, ImageBuffer* imageBuffer, bool decodeData) { struct jpeg_decompress_struct cinfo; //struct jpeg_error_mgr jerr; //cinfo.err = jpeg_std_error (&jerr); struct ErrorData jpegError; cinfo.err = jpeg_std_error (&jpegError.base); jpegError.base.error_exit = OnError; jpegError.base.output_message = OnOutput; FILE_HANDLE *file = NULL; if (resource->path) { file = lime::fopen (resource->path, "rb"); if (!file) { return false; } } if (setjmp (jpegError.on_error)) { if (file) { lime::fclose (file); } jpeg_destroy_decompress (&cinfo); return false; } jpeg_create_decompress (&cinfo); if (file) { if (file->isFile ()) { jpeg_stdio_src (&cinfo, file->getFile ()); } else { Bytes data = Bytes (resource->path); MySrcManager manager (data.Data (), data.Length ()); cinfo.src = &manager.pub; } } else { MySrcManager manager (resource->data->Data (), resource->data->Length ()); cinfo.src = &manager.pub; } bool decoded = false; if (jpeg_read_header (&cinfo, TRUE) == JPEG_HEADER_OK) { cinfo.out_color_space = JCS_RGB; if (decodeData) { jpeg_start_decompress (&cinfo); int components = cinfo.output_components; imageBuffer->Resize (cinfo.output_width, cinfo.output_height, 32); unsigned char *bytes = imageBuffer->data->Data (); unsigned char *scanline = new unsigned char [imageBuffer->width * imageBuffer->height * components]; while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines (&cinfo, &scanline, 1); // convert 24-bit scanline to 32-bit const unsigned char *line = scanline; const unsigned char *const end = line + imageBuffer->width * components; while (line != end) { *bytes++ = *line++; *bytes++ = *line++; *bytes++ = *line++; *bytes++ = 0xFF; } } delete[] scanline; jpeg_finish_decompress (&cinfo); } else { imageBuffer->width = cinfo.image_width; imageBuffer->height = cinfo.image_height; } decoded = true; } if (file) { lime::fclose (file); } jpeg_destroy_decompress (&cinfo); return decoded; }
bool PNG::Decode (Resource *resource, ImageBuffer *imageBuffer) { unsigned char png_sig[PNG_SIG_SIZE]; png_structp png_ptr; png_infop info_ptr; png_uint_32 width, height; int bit_depth, color_type, interlace_type; FILE_HANDLE *file = NULL; if (resource->path) { file = lime::fopen (resource->path, "rb"); if (!file) return false; int read = lime::fread (png_sig, PNG_SIG_SIZE, 1, file); if (png_sig_cmp (png_sig, 0, PNG_SIG_SIZE)) { lime::fclose (file); return false; } } else { memcpy (png_sig, resource->data->Bytes (), PNG_SIG_SIZE); if (png_sig_cmp (png_sig, 0, PNG_SIG_SIZE)) { return false; } } if ((png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL) { if (file) lime::fclose (file); return false; } if ((info_ptr = png_create_info_struct (png_ptr)) == NULL) { png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL); if (file) lime::fclose (file); return false; } // sets the point which libpng will jump back to in the case of an error if (setjmp (png_jmpbuf (png_ptr))) { png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp)NULL); if (file) lime::fclose (file); return false; } if (file) { if (file->isFile ()) { png_init_io (png_ptr, file->getFile ()); png_set_sig_bytes (png_ptr, PNG_SIG_SIZE); } else { ByteArray data = ByteArray (resource->path); ReadBuffer buffer (data.Bytes (), data.Size ()); png_set_read_fn (png_ptr, &buffer, user_read_data_fn); } } else { ReadBuffer buffer (resource->data->Bytes (), resource->data->Size ()); png_set_read_fn (png_ptr, &buffer, user_read_data_fn); } png_read_info (png_ptr, info_ptr); png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); //bool has_alpha = (color_type == PNG_COLOR_TYPE_GRAY_ALPHA || color_type == PNG_COLOR_TYPE_RGB_ALPHA || png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)); png_set_expand (png_ptr); png_set_filler (png_ptr, 0xff, PNG_FILLER_AFTER); //png_set_gray_1_2_4_to_8 (png_ptr); png_set_palette_to_rgb (png_ptr); png_set_gray_to_rgb (png_ptr); if (bit_depth < 8) { png_set_packing (png_ptr); } else if (bit_depth == 16) { png_set_scale_16 (png_ptr); } //png_set_bgr (png_ptr); int bpp = 4; const unsigned int stride = width * bpp; imageBuffer->Resize (width, height, bpp); unsigned char *bytes = imageBuffer->data->Bytes (); int number_of_passes = png_set_interlace_handling (png_ptr); for (int pass = 0; pass < number_of_passes; pass++) { for (int i = 0; i < height; i++) { png_bytep anAddr = (png_bytep)(bytes + i * stride); png_read_rows (png_ptr, (png_bytepp) &anAddr, NULL, 1); } } png_read_end (png_ptr, NULL); png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp)NULL); if (file) lime::fclose (file); return true; }