Exemplo n.º 1
0
Animation::Animation(FileType aftype, IStream *file, const ReadOptions& options) :
    fileType(aftype),
    inFile(file),
    outFile(NULL),
    readOptions(options)
{
    float seconds = 0.0f;

    currentFrame = 0;

    switch(fileType)
    {
        case AVI:
        //  state = Avi::ReadFileHeader(inFile, seconds, totalFrames, codec, width, height, readOptions, warnings);
            break;
        case MOV:
            state = Moov::ReadFileHeader(inFile, seconds, totalFrames, codec, width, height, readOptions, warnings);
            break;
        case MPEG:
        //  state = Mpeg::ReadFileHeader(inFile, seconds, totalFrames, codec, width, height, readOptions, warnings);
            break;
    }

    if(state == NULL)
        throw POV_EXCEPTION(kCannotHandleDataErr, "Cannot read animation file header in the specified format!");

    frameDuration = seconds / float(totalFrames);
}
Exemplo n.º 2
0
Image *Animation::ReadFrame(IStream *file)
{
    POV_LONG bytes = 0;
    Image *image = NULL;
    Image::ReadOptions options;

    options.defaultGamma = PowerLawGammaCurve::GetByDecodingGamma(readOptions.gamma);
    options.gammacorrect = readOptions.gammacorrect;
    options.itype = Image::RGBFT_Float;

    switch(fileType)
    {
        case AVI:
        //  Avi::PreReadFrame(file, currentFrame, bytes, codec, readOptions, warnings, state);
            break;
        case MOV:
            Moov::PreReadFrame(file, currentFrame, bytes, codec, readOptions, warnings, state);
            break;
    }

    POV_LONG prepos = file->tellg();

    switch(codec)
    {
        case PNGCodec:
            image = Png::Read(file, options);
            break;
        case BMPCodec:
            image = Bmp::Read(file, options);
            break;
        case JPEGCodec:
            image = Jpeg::Read(file, options);
            break;
        case MPEG1Codec:
        case MPEG2Codec:
        //  image = Mpeg::ReadFrame(file, currentFrame, codec, readOptions, warnings, state);
            break;
    }

    if(file->tellg() < (prepos + bytes))
        warnings.push_back("Frame decompressor read fewer bytes than expected.");
    else if(file->tellg() > (prepos + bytes))
        throw POV_EXCEPTION(kInvalidDataSizeErr, "Frame decompressor read more bytes than expected. The input file may be corrupted!");

    file->seekg(prepos + bytes, SEEK_END);

    switch(fileType)
    {
        case AVI:
        //  Avi::PostReadFrame(file, currentFrame, bytes, codec, readOptions, warnings, state);
            break;
        case MOV:
            Moov::PostReadFrame(file, currentFrame, bytes, codec, readOptions, warnings, state);
            break;
    }

    return image;
}
Exemplo n.º 3
0
OTextStream::OTextStream(const UCS2 *sname, unsigned int stype, bool append)
{
	if(sname == NULL)
		throw POV_EXCEPTION_CODE(kParamErr);

	stream = NewOStream(sname, stype, append);
	if(stream == NULL)
		throw POV_EXCEPTION(kCannotOpenFileErr, string("Cannot open file '") + UCS2toASCIIString(sname) + "' for output.");

	filename = UCS2String(sname);
}
Exemplo n.º 4
0
    void png_pov_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
    {
        OStream *file = reinterpret_cast<OStream *>(png_get_io_ptr(png_ptr));

        if (!file->write (data, length))
        {
            Messages *m = reinterpret_cast<Messages *>(png_get_error_ptr(png_ptr));
            if (m)
                m->error = string("Cannot write PNG data");
            throw POV_EXCEPTION(kFileDataErr, "Cannot write PNG data");
        }
    }
Exemplo n.º 5
0
	void png_pov_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
	{
		OStream *file = (OStream *)png_get_io_ptr(png_ptr);

		if (!file->write ((char *)data, length))
		{
			Messages *m = (Messages *)png_get_error_ptr(png_ptr);
			if (m)
				m->error = string("Cannot write PNG data");
			throw POV_EXCEPTION(kFileDataErr, "Cannot write PNG data");
		}
	}
Exemplo n.º 6
0
IStream *NewIStream(const Path& p, unsigned int stype)
{
    if (POV_ALLOW_FILE_READ(p().c_str(), stype) == false) // TODO FIXME - this is handled by the frontend, but that code isn't completely there yet [trf]
    {
        string str ("IO Restrictions prohibit read access to '") ;
        str += UCS2toASCIIString(p());
        str += "'";
        throw POV_EXCEPTION(kCannotOpenFileErr, str);
    }

    return new IFileStream(p().c_str());
}
Exemplo n.º 7
0
OStream *NewOStream(const Path& p, unsigned int stype, bool sappend)
{
    unsigned int Flags = IOBase::none;

    if(sappend)
        Flags |= IOBase::append;

    if (POV_ALLOW_FILE_WRITE(p().c_str(), stype) == false) // TODO FIXME - this is handled by the frontend, but that code isn't completely there yet [trf]
    {
        string str ("IO Restrictions prohibit write access to '") ;
        str += UCS2toASCIIString(p());
        str += "'";
        throw POV_EXCEPTION(kCannotOpenFileErr, str);
    }

    return new OStream(p().c_str(), Flags);
}
Exemplo n.º 8
0
IStream *NewIStream(const Path& p, const unsigned int stype)
{
    Pointer<IStream> istreamptr(POV_PLATFORM_BASE.CreateIStream(stype));

    if(istreamptr == NULL)
        return NULL;

    if (POV_ALLOW_FILE_READ(p().c_str(), stype) == false) // TODO FIXME - this is handled by the frontend, but that code isn't completely there yet [trf]
    {
        string str ("IO Restrictions prohibit read access to '") ;
        str += UCS2toASCIIString(p());
        str += "'";
        throw POV_EXCEPTION(kCannotOpenFileErr, str);
    }
    if(istreamptr->open(p().c_str()) == 0)
        return NULL;

    return istreamptr.release();
}
Exemplo n.º 9
0
void PostWriteFrame(OStream *file, POV_LONG bytes, const Animation::WriteOptions&, vector<string>&, void *state)
{
    PrivateData *pd = reinterpret_cast<PrivateData *>(state);

    if(pd == NULL)
        throw POV_EXCEPTION_CODE(kNullPointerErr);

    // update mdat size

    file->seekg(0, SEEK_END);
    pd->mdatsize = file->tellg() + 16;
    file->seekg(8, SEEK_SET);
    WriteInt8(file, pd->mdatsize);
    file->seekg(0, SEEK_END);

    if(bytes > 2147483647) // 2^31 - 1
        throw POV_EXCEPTION(kInvalidDataSizeErr, "Cannot handle frame data larger than 2^31 bytes!");

    pd->imagesizes.push_back(int(bytes));
}
Exemplo n.º 10
0
Animation::Animation(FileType aftype, CodecType c, OStream *file, unsigned int w, unsigned int h, const WriteOptions& options) :
    fileType(aftype),
    inFile(NULL),
    outFile(file),
    width(w),
    height(h),
    writeOptions(options),
    codec(c)
{
    totalFrames = 0;
    frameDuration = 1.0f / options.framespersecond;

    blurMatrixRadius = 7;

    switch(fileType)
    {
        case AVI:
        //  state = Avi::WriteFileHeader(outFile, codec, width, height, writeOptions, warnings);
            break;
        case MOV:
            state = Moov::WriteFileHeader(outFile, codec, width, height, writeOptions, warnings);
            break;
        case MPEG:
        //  state = Mpeg::WriteFileHeader(outFile, codec, width, height, writeOptions, warnings);
            break;
    }

    if(state == NULL)
        throw POV_EXCEPTION(kCannotHandleDataErr, "Cannot write animation file with the specified format and codec!");

    // TODO FIXME - build blur matrix (this code only builds an identity matrix)
    for(size_t y = 0; y < 15; y++)
    {
        for(size_t x = 0; x < 15; x++)
            blurMatrix[x][y] = 0.0f;
    }
    blurMatrix[blurMatrixRadius + 1][blurMatrixRadius + 1] = 1.0f;
}
Exemplo n.º 11
0
OStream *NewOStream(const Path& p, const unsigned int stype, const bool sappend)
{
    Pointer<OStream> ostreamptr(POV_PLATFORM_BASE.CreateOStream(stype));
    unsigned int Flags = IOBase::none;

    if(ostreamptr == NULL)
        return NULL;

    if(sappend)
        Flags |= IOBase::append;

    if (POV_ALLOW_FILE_WRITE(p().c_str(), stype) == false) // TODO FIXME - this is handled by the frontend, but that code isn't completely there yet [trf]
    {
        string str ("IO Restrictions prohibit write access to '") ;
        str += UCS2toASCIIString(p());
        str += "'";
        throw POV_EXCEPTION(kCannotOpenFileErr, str);
    }
    if(ostreamptr->open(p().c_str(), Flags) == 0)
        return NULL;

    return ostreamptr.release();
}
Exemplo n.º 12
0
ITextStream::ITextStream(const UCS2 *sname, unsigned int stype)
{
	if(sname == NULL)
		throw POV_EXCEPTION_CODE(kParamErr);

	stream = NewIStream(sname, stype);
	if(stream == NULL)
		throw POV_EXCEPTION(kCannotOpenFileErr, string("Cannot open file '") + UCS2toASCIIString(sname) + "' for input.");

	filename = UCS2String(sname);
	lineno = 1;
	bufferoffset = 0;
	maxbufferoffset = 0;
	filelength = 0;
	ungetbuffer = EOF;
	curpos = 0 ;

	stream->seekg(0, IOBase::seek_end);
	filelength = stream->tellg();
	stream->seekg(0, IOBase::seek_set);

	RefillBuffer();
}
Exemplo n.º 13
0
// TODO: make sure we don't leak an image object if we throw an exception.
Image *Read (IStream *file, const Image::ReadOptions& options, bool IsPOTFile)
{
	int                             data ;
	int                             width;
	int                             height;
	Image                           *image ;
	unsigned char                   buffer[256];
	vector<Image::RGBAMapEntry>     colormap ;
	int                             alphaIdx = -1; // assume no transparency color

	// GIF files used to have no clearly defined gamma by default, but a W3C recommendation exists for them to use sRGB.
	// Anyway, use whatever the user has chosen as default.
	GammaCurvePtr gamma;
	if (options.gammacorrect)
	{
		if (options.defaultGamma)
			gamma = TranscodingGammaCurve::Get(options.workingGamma, options.defaultGamma);
		else
			gamma = TranscodingGammaCurve::Get(options.workingGamma, SRGBGammaCurve::Get());
	}

	int status = 0;

	/* Get the screen description. */
	if (!file->read (buffer, 13))
		throw POV_EXCEPTION(kFileDataErr, "Cannot read GIF file header");

	/* Use updated GIF specs. */
	if (memcmp ((char *) buffer, "GIF", 3) != 0)
		throw POV_EXCEPTION(kFileDataErr, "File is not in GIF format");

	if (buffer[3] != '8' || (buffer[4] != '7' && buffer[4] != '9') || buffer[5] < 'A' || buffer[5] > 'z')
		throw POV_EXCEPTION(kFileDataErr, "Unsupported GIF version");

	int planes = ((unsigned) buffer [10] & 0x0F) + 1;
	int colourmap_size = (1 << planes);

	/* Color map (better be!) */
	if ((buffer[10] & 0x80) == 0)
		throw POV_EXCEPTION(kFileDataErr, "Error in GIF color map");

	for (int i = 0; i < colourmap_size ; i++)
	{
		Image::RGBAMapEntry entry;
		if (!file->read (buffer, 3))
			throw POV_EXCEPTION(kFileDataErr, "Cannot read GIF colormap");
		entry.red   = IntDecode(gamma, buffer[0], 255);
		entry.green = IntDecode(gamma, buffer[1], 255);
		entry.blue  = IntDecode(gamma, buffer[2], 255);
		entry.alpha = 1.0f;
		colormap.push_back(entry);
	}

	/* Now read one or more GIF objects. */
	bool finished = false;

	while (!finished)
	{
		switch (file->Read_Byte())
		{
			case EOF:
				throw POV_EXCEPTION(kFileDataErr, "Unexpected EOF reading GIF file");
				finished = true;
				break ;

			case ';': /* End of the GIF dataset. */
				finished = true;
				status = 0;
				break;

			case '!': /* GIF Extension Block. */
				/* Read (and check) the ID. */
				if (file->Read_Byte() == 0xF9)
				{
					if ((data = file->Read_Byte()) > 0)
					{
						if (!file->read (buffer, data))
							throw POV_EXCEPTION(kFileDataErr, "Unexpected EOF reading GIF file");
						// check transparency flag, and set transparency color index if appropriate
						if (data >= 3 && buffer[0] & 0x01)
						{
							int alphaIdx = buffer[3];
							if (alphaIdx < colourmap_size)
								colormap[alphaIdx].alpha = 0.0f;
						}
					}
					else
						break;
				}
				while ((data = file->Read_Byte()) > 0)
					if (!file->read (buffer, data))
						throw POV_EXCEPTION(kFileDataErr, "Unexpected EOF reading GIF file");
				break;

			case ',': /* Start of image object. Get description. */
				for (int i = 0; i < 9; i++)
				{
					if ((data = file->Read_Byte()) == EOF)
						throw POV_EXCEPTION(kFileDataErr, "Unexpected EOF reading GIF file");
					buffer[i] = (unsigned char) data;
				}

				/* Check "interlaced" bit. */
				if ((buffer[9] & 0x40) != 0)
					throw POV_EXCEPTION(kFileDataErr, "Interlacing in GIF image unsupported");

				width  = (int) buffer[4] | ((int) buffer[5] << 8);
				height = (int) buffer[6] | ((int) buffer[7] << 8);
				image = Image::Create (width, height, Image::Colour_Map, colormap) ;
				// [CLi] GIF only uses full opacity or full transparency, so premultiplied vs. non-premultiplied alpha is not an issue

				/* Get bytes */
				Decode (file, image);
				finished = true;
				break;

			default:
				status = -1;
				finished = true;
				break;
		}
	}

	if (IsPOTFile == false)
	{
		if (!image)
			throw POV_EXCEPTION(kFileDataErr, "Cannot find GIF image data block");
		return (image);
	}

	// POT files are GIF files where the right half of the image contains
	// a second byte for each pixel on the left, thus allowing 16-bit
	// indexes. In this case the palette data is ignored and we convert
	// the image into a 16-bit grayscale version.
	if ((width & 0x01) != 0)
		throw POV_EXCEPTION(kFileDataErr, "Invalid width for POT file");
	int newWidth = width / 2 ;
	Image *newImage = Image::Create (newWidth, height, Image::Gray_Int16) ;
	for (int y = 0 ; y < height ; y++)
		for (int x = 0 ; x < newWidth ; x++)
			newImage->SetGrayValue (x, y, (unsigned int) image->GetIndexedValue (x, y) << 8 | image->GetIndexedValue (x + newWidth, y)) ;
			// NB: POT files don't use alpha, so premultiplied vs. non-premultiplied is not an issue
			// NB: No gamma adjustment happening here!
	delete image ;
	return (newImage) ;
}