void MPEGCodec::decompress(const DataChunk &data) { const int channels = 3; const size_t bytes_per_channel = sizeof(unsigned char); const UInt32 width = _descriptor.getStoredWidth(); const UInt32 height = _descriptor.getStoredHeight(); const ptrdiff_t stride = bytes_per_channel * channels; const size_t rowbytes = width * stride; const size_t data_size = rowbytes * height; DataChunkPtr buf_data = new DataChunk(data_size); char *data_origin = (char *)buf_data->Data; FrameBufferPtr buf = new FrameBuffer(width, height); buf->insert("R", Slice(MoxFiles::UINT8, data_origin + (bytes_per_channel * 0), stride, rowbytes)); buf->insert("G", Slice(MoxFiles::UINT8, data_origin + (bytes_per_channel * 1), stride, rowbytes)); buf->insert("B", Slice(MoxFiles::UINT8, data_origin + (bytes_per_channel * 2), stride, rowbytes)); memset(data_origin, 0, data_size); buf->attachData(buf_data); storeFrame(buf); }
//============================================================================== bool cVideo::update() { if (!m_clip) { return false; } bool newFrame = false; // check if a new frame is available if (!((TheoraVideoClip*)m_clip)->isDone()) { // check if a new one is available TheoraVideoFrame *frame = ((TheoraVideoClip*)m_clip)->getNextFrame(); if (frame) { m_frameIndex++; newFrame = true; storeFrame(frame); } // update video timebase double t = m_clock.getCurrentTimeSeconds(); ((TheoraVideoManager*)m_manager)->update((float)(t-m_lastUpdate)); m_lastUpdate = t; } // report beginning of stream if (m_firstFrame) { newFrame = true; m_firstFrame = false; } // report end of stream if (((TheoraVideoClip*)m_clip)->isDone()) { reset(); newFrame = true; } return newFrame; }
//============================================================================== bool cVideo::seekFrame(unsigned int a_index) { // check that requested frame exists, and that video clip exists if (!m_clip || a_index >= m_frameCount) { return false; } // move clip to desired time ((TheoraVideoClip*)m_clip)->seekToFrame(a_index); // get initial frame TheoraVideoFrame *frame = NULL; while (!frame) frame = ((TheoraVideoClip*)m_clip)->getNextFrame(); // flip frame storeFrame(frame); return true; }
//============================================================================== void cVideo::reset() { if (m_clip) { // put the movie back to the beginning m_clock.stop(); m_clock.reset(); m_lastUpdate = 0.0; ((TheoraVideoClip*)m_clip)->stop(); m_frameIndex = 0; // get initial frame TheoraVideoFrame *frame = NULL; while (!frame) frame = ((TheoraVideoClip*)m_clip)->getNextFrame(); // flip first frame storeFrame(frame); // mark frame as first frame m_firstFrame = true; } }
int main (int argc, char** argv) { CvCapture* capture; //Get capture structure for camera, -1 refers to any camera device. //If multiple cameras used, need to use specific camera ID capture = cvCreateCameraCapture(-1); //If cvCreateCameraCapture returns NULL there is an error with the camera if( capture == NULL) return -1; int i; for( i=0;i<10;i++) { if( !storeFrame( capture)) return -1; sleep(1); //for now just to make the camera take 1 shot a second, as that's all my camera seems to be able to take/save (camera or function causing this? is 1 second per frame enough?) } //Need to determine how the function is called in respect to system. just leave it running with a while loop? will something turn it on and off? will the function be called once from elsewhere? cvReleaseCapture( &capture); }
void DPXCodec::decompress(const DataChunk &data) { MemoryFile file(data); DPXCodec_InStream istream(file); dpx::Reader dpx; dpx.SetInStream(&istream); const bool header_read = dpx.ReadHeader(); if(header_read) { const int dpx_width = dpx.header.Width(); const int dpx_height = dpx.header.Height(); const int dpx_channels = dpx.header.ImageElementComponentCount(0); assert(dpx_width == _descriptor.getStoredWidth()); assert(dpx_height == _descriptor.getStoredHeight()); assert(dpx_channels == (_channels == DPX_RGBA ? 4 : 3)); const Box2i dataW = dataWindow(); if(dpx_width != (dataW.max.x - dataW.min.x + 1)) throw MoxMxf::InputExc("Stored data is wrong width"); if(dpx_height != (dataW.max.y - dataW.min.y + 1)) throw MoxMxf::InputExc("Stored data is wrong height"); const size_t pixsize = (_depth == DPX_8 ? sizeof(unsigned char) : sizeof(unsigned short)); const size_t rowbytes = dpx_width * pixsize * dpx_channels; const size_t buffer_size = rowbytes * dpx_height; DataChunkPtr frame_data = new DataChunk(buffer_size); char *origin = (char *)frame_data->Data; FrameBufferPtr frame_buffer = new FrameBuffer(dataW); const PixelType pixel_type = (_depth == DPX_8 ? MoxFiles::UINT8 : MoxFiles::UINT16); const size_t bytes_per_subpixel = PixelSize(pixel_type); const size_t bytes_per_pixel = bytes_per_subpixel * dpx_channels; frame_buffer->insert("R", Slice(pixel_type, origin + (bytes_per_subpixel * 0), bytes_per_pixel, rowbytes)); frame_buffer->insert("G", Slice(pixel_type, origin + (bytes_per_subpixel * 1), bytes_per_pixel, rowbytes)); frame_buffer->insert("B", Slice(pixel_type, origin + (bytes_per_subpixel * 2), bytes_per_pixel, rowbytes)); if(_channels == DPX_RGBA) frame_buffer->insert("A", Slice(pixel_type, origin + (bytes_per_subpixel * 3), bytes_per_pixel, rowbytes)); frame_buffer->attachData(frame_data); dpx::Block block(0, 0, dpx_width - 1, dpx_height - 1); const dpx::Descriptor dpx_desc = dpx.header.ImageDescriptor(0); const dpx::DataSize dpx_size = (_depth == DPX_8 ? dpx::kByte : dpx::kWord); const bool image_read = dpx.ReadBlock((void *)origin, dpx_size, block, dpx_desc); if(image_read) { storeFrame(frame_buffer); } else assert(false); } else assert(false); }
void JPEGLSCodec::decompress(const DataChunk &data) { ByteStreamInfo inStream = FromByteArray(data.Data, data.Size); struct JlsParameters info; JLS_ERROR err = JpegLsReadHeaderStream(inStream, &info); if(err == OK) { const int width = info.width; const int height = info.height; assert(info.components == (_channels == JPEGLS_RGBA ? 4 : 3)); assert(info.colorTransform == COLORXFORM_NONE); const PixelType pixType = (_depth == JPEGLS_8 ? UINT8 : _depth == JPEGLS_10 ? UINT10 : _depth == JPEGLS_12 ? UINT12 : _depth == JPEGLS_16 ? UINT16 : UINT8); const size_t pixSize = PixelSize(pixType); const unsigned int bitDepth = PixelBits(pixType); assert(info.bitspersample == bitDepth); const size_t pixelSize = (info.components * PixelSize(pixType)); const size_t rowBytes = (width * pixelSize); const size_t bufSize = (height * rowBytes); DataChunkPtr frameData = new DataChunk(bufSize); char *buf = (char *)frameData->Data; const Box2i dataW = dataWindow(); assert(width == (dataW.max.x - dataW.min.x + 1)); assert(height == (dataW.max.y - dataW.min.y + 1)); assert(dataW.min.x == 0); assert(dataW.min.y == 0); FrameBufferPtr frameBuffer = new FrameBuffer(dataW); frameBuffer->insert("R", Slice(pixType, &buf[0 * pixSize], pixelSize, rowBytes)); frameBuffer->insert("G", Slice(pixType, &buf[1 * pixSize], pixelSize, rowBytes)); frameBuffer->insert("B", Slice(pixType, &buf[2 * pixSize], pixelSize, rowBytes)); if(info.components >= 4) frameBuffer->insert("A", Slice(pixType, &buf[3 * pixSize], pixelSize, rowBytes)); frameBuffer->attachData(frameData); ByteStreamInfo outStream = FromByteArray(frameData->Data, frameData->Size); err = JpegLsDecodeStream(outStream, inStream, &info); if(err == OK) { storeFrame(frameBuffer); } } if(err != OK) throw MoxMxf::ArgExc("JPEG-LS decompression error"); }
void JPEGCodec::decompress(const DataChunk &data) { struct jpeg_error_mgr jerr; jerr.error_exit = my_error_exit; jerr.emit_message = my_emit_message; jerr.output_message = my_output_message; jerr.format_message = my_format_message; jerr.reset_error_mgr = my_reset_error_mgr; jerr.trace_level = 0; jerr.num_warnings = 0; jerr.msg_code = 0; jerr.jpeg_message_table = jpeg_std_message_table; jerr.last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; jerr.addon_message_table = NULL; jerr.first_addon_message = 0; jerr.last_jpeg_message = 0; my_source_mgr mgr; mgr.infile = new MemoryFile(data); mgr.buffer = (JOCTET *)malloc(4096 * sizeof(JOCTET)); mgr.bufferSize = 4096; mgr.pub.bytes_in_buffer = 0; mgr.pub.next_input_byte = NULL; if(mgr.buffer == NULL) throw MoxMxf::NullExc("out of memory"); mgr.pub.init_source = my_init_source; mgr.pub.fill_input_buffer = my_fill_input_buffer; mgr.pub.skip_input_data = my_skip_input_data; mgr.pub.resync_to_restart = jpeg_resync_to_restart; mgr.pub.term_source = my_term_source; struct jpeg_decompress_struct cinfo; cinfo.err = &jerr; jpeg_create_decompress(&cinfo); cinfo.src = (jpeg_source_mgr *)&mgr; bool success = true; try { const int status = jpeg_read_header(&cinfo, TRUE); if(status == JPEG_HEADER_OK) { jpeg_start_decompress(&cinfo); const JDIMENSION width = cinfo.image_width; const JDIMENSION height = cinfo.image_height; assert(cinfo.num_components == 3); assert(cinfo.out_color_space == JCS_RGB); const size_t pixelSize = (3 * PixelSize(UINT8)); const size_t rowBytes = (width * pixelSize); const size_t bufSize = (height * rowBytes); DataChunkPtr frameData = new DataChunk(bufSize); char *buf = (char *)frameData->Data; const Box2i dataW = dataWindow(); assert(width == (dataW.max.x - dataW.min.x + 1)); assert(height == (dataW.max.y - dataW.min.y + 1)); assert(dataW.min.x == 0); assert(dataW.min.y == 0); FrameBufferPtr frameBuffer = new FrameBuffer(dataW); frameBuffer->insert("R", Slice(UINT8, &buf[0], pixelSize, rowBytes)); frameBuffer->insert("G", Slice(UINT8, &buf[1], pixelSize, rowBytes)); frameBuffer->insert("B", Slice(UINT8, &buf[2], pixelSize, rowBytes)); frameBuffer->attachData(frameData); JSAMPARRAY scanlines = (JSAMPARRAY)malloc(height * sizeof(JSAMPROW)); if(scanlines == NULL) throw MoxMxf::NullExc("out of memory"); for(int y=0; y < height; y++) { scanlines[y] = (JSAMPROW)(buf + (y * rowBytes)); } JDIMENSION linesRead = 0; while(linesRead < height) { linesRead += jpeg_read_scanlines(&cinfo, &scanlines[linesRead], height - linesRead); } free(scanlines); jpeg_finish_decompress(&cinfo); storeFrame(frameBuffer); } else throw MoxMxf::ArgExc("Error reading header"); } catch(...) { success = false; } jpeg_destroy_decompress(&cinfo); free(mgr.buffer); delete mgr.infile; if(!success) throw MoxMxf::ArgExc("JPEG decompression error"); }