Ejemplo n.º 1
0
static bool Bitmap_getTiffImageSize(StackBuffer<256> &data, const io::Producer &file, size_t &width, size_t &height) {
	auto reader = Reader(data.data() + 4, 4);
	auto offset = reader.readUnsigned32();

	data.clear();
	if (file.seekAndRead(offset, data, 2) != 2) {
		return false;
	}
	auto size = Reader(data.data(), 2).readUnsigned16();
	auto dictSize = size * 12;
	offset += 2;
	while (dictSize > 0) {
		data.clear();
		size_t blockSize = min(12 * 21, dictSize);
		if (file.read(data, blockSize) != blockSize) {
			return false;
		}

		auto blocks = blockSize / 12;
		reader = Reader(data.data(), blockSize);

		for (uint16_t i = 0; i < blocks; ++i) {
			auto tagid = reader.readUnsigned16();
			auto type = reader.readUnsigned16();
			auto count = reader.readUnsigned32();
			if (tagid == 256 && count == 1) {
				if (type == 3) {
					width = reader.readUnsigned16();
					reader.offset(2);
				} else if (type == 4) {
					width = reader.readUnsigned32();
				} else {
					reader.offset(4);
				}
			} else if (tagid == 257 && count == 1) {
				if (type == 3) {
					height = reader.readUnsigned16();
					reader.offset(2);
				} else if (type == 4) {
					height = reader.readUnsigned32();
				} else {
					reader.offset(4);
				}
				return true;
			} else {
				if (tagid > 257) {
					return false;
				}
				reader.offset(4);
			}
		}
	}
	return false;
}
Ejemplo n.º 2
0
bool Bitmap::getImageSize(const io::Producer &file, size_t &width, size_t &height) {
	StackBuffer<256> data;
    if (file.seekAndRead(0, data, 30) < 30) {
    	return false;
    }

	if (isPng(data.data(), data.size()) && data.size() >= 24) {
		auto reader = DataReader<ByteOrder::Network>(data.data() + 16, 8);

		width = reader.readUnsigned32();
		height = reader.readUnsigned32();

	    return true;
	} else if(isJpg(data.data(), data.size())) {
		size_t offset = 2;
		uint16_t len = 0;
		uint8_t marker = 0;

		auto reader = DataReader<ByteOrder::Network>(data.data() + 2, data.size() - 2);
		while (reader.is((uint8_t)0xFF)) {
			++ reader;
		}

		marker = reader.readUnsigned();
		len = reader.readUnsigned16();

		while (marker < 0xC0 || marker > 0xCF) {
			offset += 2 + len;
			data.clear();

			if (file.seekAndRead(offset, data, 12) != 12) {
				return false;
			}

			if (data.size() >= 12) {
				reader = data.get<DataReader<ByteOrder::Network>>();

				while (reader.is((uint8_t)0xFF)) {
					++ reader;
				}

				marker = reader.readUnsigned();
				len = reader.readUnsigned16();
			} else {
				reader.clear();
				break;
			}
		}

		if (reader >= 5 && marker >= 0xC0 && marker <= 0xCF) {
			++ reader;
			height = reader.readUnsigned16();
			width = reader.readUnsigned16();
			return true;
		}

		return false;
	} else if (isGif(data.data(), data.size())) {
		auto reader = DataReader<ByteOrder::Little>(data.data() + 6, 4);

		width = reader.readUnsigned16();
		height = reader.readUnsigned16();

	    return true;
	} else if (isWebp(data.data(), data.size())) {
		auto reader = DataReader<ByteOrder::Little>(data.data() + 26, 4);

		width = reader.readUnsigned16();
		height = reader.readUnsigned16();

	    return true;
	} else if (isTiff(data.data(), data.size())) {
		if (memcmp(data.data(), "II", 2) == 0) {
			if (Bitmap_getTiffImageSize<DataReader<ByteOrder::Little>>(data, file, width, height)) {
				return true;
			}
		} else {
			if (Bitmap_getTiffImageSize<DataReader<ByteOrder::Big>>(data, file, width, height)) {
				return true;
			}
		}
	}

    return false;
}
Ejemplo n.º 3
0
        void initFileObject(lua_State* L)
        {
            luaL_newmetatable(L, meta<File>());
            // Duplicate the metatable on the stack.
            lua_pushvalue(L, -1);
            // metatable.__index = metatable
            lua_setfield(L, -2, "__index");

            // Put the members into the metatable.
            const luaL_Reg functions[] = {
                {"__gc", [](lua_State* L) { return script::wrapped<File>(L, 1)->gc(L); }},
                {"__index", [](lua_State* L) { return script::wrapped<File>(L, 1)->index(L); }},
                {"__newindex", [](lua_State* L) { return script::wrapped<File>(L, 1)->newindex(L); }},
                {"__tostring", [](lua_State* L) { return script::wrapped<File>(L, 1)->tostring(L); }},
                {"__pairs", [](lua_State* L) { return script::wrapped<File>(L, 1)->pairs(L); }},
                {"close", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    file->close();
                    return 0;
                }},
                {"readUnsigned8", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    uint8_t value;
                    if(file->readUnsigned8(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readUnsigned16", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    uint16_t value;
                    if(file->readUnsigned16(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readUnsigned32", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    uint32_t value;
                    if(file->readUnsigned32(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readInt8", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    int8_t value;
                    if(file->readInt8(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readInt16", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    int16_t value;
                    if(file->readInt16(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readInt32", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    int32_t value;
                    if(file->readInt32(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readFloat", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    float value;
                    if(file->readFloat(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readDouble", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    double value;
                    if(file->readDouble(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readString", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto blockSize = script::get<int>(L, 2);

                    std::string buffer(blockSize, 0);
                    if(file->readString(buffer))
                    {
                        lua_pushlstring(L, buffer.data(), buffer.size());
                        return 1;
                    }
                    return 0;
                }},
                {"readLine", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    std::string value;
                    if(file->readLine(value))
                    {
                        script::push(L, value.c_str());
                        return 1;
                    }
                    return 0;
                }},
                {"readFully", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    // Get current position.
                    auto pos = file->tell();
                    if(pos == -1)
                    {
                        return 0;
                    }

                    // Length to read = position of end - current.
                    auto length = 0;
                    if(!file->seek(pos, FileSeekMode::End))
                    {
                        return 0;
                    }
                    length = file->tell() - pos;
                    if(!file->seek(pos, FileSeekMode::Start))
                    {
                        return 0;
                    }

                    // Read the entire file into a string.
                    std::string buf(length, 0);
                    if(file->readString(buf))
                    {
                        lua_pushlstring(L, buf.data(), buf.size());
                        return 1;
                    }
                    return 0;
                }},
                {"writeUnsigned8", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<int>(L, 2);

                    script::push(L, file->writeUnsigned8(value));
                    return 1;
                }},
                {"writeUnsigned16", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<int>(L, 2);

                    script::push(L, file->writeUnsigned16(value));
                    return 1;
                }},
                {"writeUnsigned32", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<int>(L, 2);

                    script::push(L, file->writeUnsigned32(value));
                    return 1;
                }},
                {"writeInt8", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<int>(L, 2);

                    script::push(L, file->writeInt8(value));
                    return 1;
                }},
                {"writeInt16", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<int>(L, 2);

                    script::push(L, file->writeInt16(value));
                    return 1;
                }},
                {"writeInt32", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<int>(L, 2);

                    script::push(L, file->writeInt32(value));
                    return 1;
                }},
                {"writeFloat", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<double>(L, 2);

                    script::push(L, file->writeFloat((float) value));
                    return 1;
                }},
                {"writeDouble", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<double>(L, 2);

                    script::push(L, file->writeDouble(value));
                    return 1;
                }},
                {"writeString", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    size_t length = 0;
                    const char* buffer = luaL_checklstring(L, 2, &length);
                    std::string value(buffer, buffer + length);
                    script::push(L, file->writeString(value));
                    return 1;
                }},
                {"writeLine", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    size_t length = 0;
                    const char* buffer = luaL_checklstring(L, 2, &length);
                    std::string value(buffer, buffer + length);
                    script::push(L, file->writeLine(value));
                    return 1;
                }},
                {"tell", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    script::push(L, int(file->tell()));
                    return 1;
                }},
                {"seek", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto position = script::get<int>(L, 2);
                    auto mode = FileSeekMode(script::get<int>(L, 3));
                    script::push(L, file->seek(position, mode));
                    return 1;
                }},
                {"flush", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    file->flush();
                    return 0;
                }},
                {nullptr, nullptr},
            };
            luaL_setfuncs(L, functions, 0);

            lua_pop(L, 1);
                
            // Push plum namespace.
            lua_getglobal(L, "plum");

            // plum.File = <function create>
            script::push(L, "File");
            lua_pushcfunction(L, [](lua_State* L)
            {
                auto filename = script::get<const char*>(L, 1);
                auto mode = FileOpenMode(script::get<int>(L, 2));
                auto f = new File(filename, mode);
                // Failure.
                if(!f->isActive())
                {    
                    delete f;
                    return 0;
                }

                script::push(L, f, LUA_NOREF);
                return 1;
            });
            lua_settable(L, -3);

            // Pop plum namespace.
            lua_pop(L, 1);
        }