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 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; }