예제 #1
0
void PixMap::read_direct_image(ReadSource in, unique_ptr<RasterImage>& image) const {
    if (pixel_type != RGB_DIRECT) {
        throw Exception("image is not direct");
    }
    if (pack_type != 4) {
        throw Exception(format("unsupported pack_type {0}", pack_type));
    }
    image.reset(new RasterImage(bounds));
    if (row_bytes == 0) {
        return;
    }
    size_t bytes_read = 0;
    for (int y = 0; y < bounds.height(); ++y) {
        Bytes bytes;
        if (row_bytes <= 250) {
            bytes.resize(read<uint8_t>(in));
            bytes_read += 1;
        } else {
            bytes.resize(read<uint16_t>(in));
            bytes_read += 2;
        }
        in.shift(bytes.data(), bytes.size());
        bytes_read += bytes.size();

        BytesSlice remainder(bytes);
        Bytes components;
        while (!remainder.empty()) {
            uint8_t header = read<uint8_t>(remainder);
            if (header >= 0x80) {
                components.push(0x101 - header, read<uint8_t>(remainder));
            } else {
                size_t size = header + 1;
                components.push(size, '\0');
                uint8_t* data = components.data() + components.size() - size;
                remainder.shift(data, size);
            }
        }
        const int16_t w = bounds.width();
        const BytesSlice red = components.slice((cmp_count - 3) * w, w);
        const BytesSlice green = components.slice((cmp_count - 2) * w, w);
        const BytesSlice blue = components.slice((cmp_count - 1) * w);
        for (int x = 0; x < w; ++x) {
            image->set(x, y, AlphaColor(red.at(x), green.at(x), blue.at(x)));
        }
    }
    if ((bytes_read % 2) != 0) {
        in.shift(1);
    }
}
예제 #2
0
void read_from(ReadSource in, BitMap& out) {
    read(in, out.base_addr);
    read(in, out.row_bytes);
    read(in, out.bounds);

    if (out.base_addr != 0) {
        throw Exception("PixMap::base_addr must be 0");
    }
}
예제 #3
0
 virtual void visit_object(const StringMap<Json>& value) const {
     if (_state == NEW) {
         _state = UNLOCKED_CHAPTERS;
         if (value.find("unlocked-levels") != value.end()) {
             value.find("unlocked-levels")->second.accept(*this);
         }
         _state = NEW;
         return;
     }
     throw Exception("invalid ledger content");
 }
예제 #4
0
void PixMap::read_packed_image(
        sfz::ReadSource in, const ColorTable& clut, unique_ptr<RasterImage>& image) const {
    if (pixel_type != INDEXED) {
        throw Exception("image is not indexed");
    }
    image.reset(new RasterImage(bounds));
    if (row_bytes == 0) {
        return;
    }
    size_t bytes_read = 0;
    for (int y = 0; y < bounds.height(); ++y) {
        Bytes bytes;
        if (row_bytes <= 250) {
            bytes.resize(read<uint8_t>(in));
            bytes_read += 1;
        } else {
            bytes.resize(read<uint16_t>(in));
            bytes_read += 2;
        }
        in.shift(bytes.data(), bytes.size());
        bytes_read += bytes.size();

        int32_t x = 0;
        BytesSlice remainder = bytes;
        while (!remainder.empty()) {
            uint8_t header = read<uint8_t>(remainder);
            if (header >= 0x80) {
                uint8_t value = read<uint8_t>(remainder);
                uint8_t size = 0x101 - header;
                for (int j = 0; j < size; ++j) {
                    if (x < bounds.width()) {
                        image->set(x + bounds.left, y + bounds.top, lookup(clut, value));
                    }
                    ++x;
                }
            } else {
                uint8_t size = header + 1;
                for (int j = 0; j < size; ++j) {
                    if (x < bounds.width()) {
                        uint8_t value = read<uint8_t>(remainder);
                        image->set(x + bounds.left, y + bounds.top, lookup(clut, value));
                    }
                    ++x;
                }
            }
        }
    }
    if ((bytes_read % 2 == 1)) {
        in.shift(1);
    }
}
예제 #5
0
void BitsSlice::shift(uint8_t* data, size_t size) {
    if (size == 0) {
        return;
    } else if (size + _bit_index > 8) {
        throw Exception(format("unhandled case ({0} + {1})", size, _bit_index));
    }

    uint8_t byte = _bytes.at(0);
    *data = bits(byte, _bit_index, _bit_index + size);

    _bit_index += size;
    if (_bit_index == 8) {
        _bytes.shift(1);
        _bit_index = 0;
    }
}
예제 #6
0
void read_from(ReadSource in, PixMap& out) {
    read(in, out.row_bytes);
    out.row_bytes &= 0x3fff;
    read(in, out.bounds);
    read(in, out.pm_version);
    read(in, out.pack_type);
    read(in, out.pack_size);
    read(in, out.h_res);
    read(in, out.v_res);
    read(in, out.pixel_type);
    read(in, out.pixel_size);
    read(in, out.cmp_count);
    read(in, out.cmp_size);
    read(in, out.plane_bytes);
    read(in, out.pm_table);
    read(in, out.pm_reserved);

    if (out.plane_bytes != 0) {
        throw Exception("PixMap::plane_bytes must be 0");
    }
    if (out.pm_reserved != 0) {
        throw Exception("PixMap::pm_reserved must be 0");
    }

    switch (out.pixel_type) {
        case INDEXED: {
            switch (out.pixel_size) {
              case 1:
              case 2:
              case 4:
              case 8:
                break;

              default:
                throw Exception(format("indexed pixels may not have size {0}", out.pixel_size));
            }
            if ((out.pack_type != 0) || (out.pack_size != 0)) {
                throw Exception("indexed pixels may not be packed");
            }
            if ((out.cmp_count != 1) || (out.cmp_size != out.pixel_size)) {
                throw Exception("indexed pixels must have one component");
            }
            break;
        }

        case RGB_DIRECT: {
            switch (out.pixel_size) {
                case 16: {
                    throw Exception(format("unsupported pixel_size {0}", out.pixel_size));
                    break;
                }

                case 32: {
                    if (out.cmp_size != 8) {
                        throw Exception("32-bit direct pixels must have cmp_size 8");
                    }
                    break;
                }

                default: {
                    throw Exception(format("direct pixels may not have size {0}", out.pixel_size));
                }
            }
            if ((out.cmp_count != 3) && (out.cmp_count != 4)) {
                throw Exception("direct pixels must have three or four components");
            }
            break;
        }

        default: {
            throw Exception(format("illegal PixMap pixel_type {0}", out.pixel_type));
        }
    }
}