Ejemplo n.º 1
0
bool
TIFFOutput::write_tile (int x, int y, int z,
                        TypeDesc format, const void *data,
                        stride_t xstride, stride_t ystride, stride_t zstride)
{
    if (! m_spec.valid_tile_range (x, x, y, y, z, z))
        return false;
    m_spec.auto_stride (xstride, ystride, zstride, format, spec().nchannels,
                        spec().tile_width, spec().tile_height);
    x -= m_spec.x;   // Account for offset, so x,y are file relative, not 
    y -= m_spec.y;   // image relative
    const void *origdata = data;   // Stash original pointer
    data = to_native_tile (format, data, xstride, ystride, zstride, m_scratch);
    if (m_planarconfig == PLANARCONFIG_SEPARATE && m_spec.nchannels > 1) {
        // Convert from contiguous (RGBRGBRGB) to separate (RRRGGGBBB)
        imagesize_t tile_pixels = m_spec.tile_pixels();
        imagesize_t plane_bytes = tile_pixels * m_spec.format.size();
        DASSERT (plane_bytes*m_spec.nchannels == m_spec.tile_bytes());
        m_scratch.resize (m_spec.tile_bytes());

        boost::scoped_array<char> separate_heap;
        char *separate = NULL;
        imagesize_t separate_size = plane_bytes * m_spec.nchannels;
        if (separate_size <= (1<<16))
            separate = ALLOCA (char, separate_size);  // <=64k ? stack
        else {                                        // >64k ? heap
Ejemplo n.º 2
0
bool
TIFFOutput::write_tile (int x, int y, int z,
                        TypeDesc format, const void *data,
                        stride_t xstride, stride_t ystride, stride_t zstride)
{
    if (! m_spec.valid_tile_range (x, x, y, y, z, z))
        return false;
    m_spec.auto_stride (xstride, ystride, zstride, format, spec().nchannels,
                        spec().tile_width, spec().tile_height);
    x -= m_spec.x;   // Account for offset, so x,y are file relative, not 
    y -= m_spec.y;   // image relative
    z -= m_spec.z;
    const void *origdata = data;   // Stash original pointer
    data = to_native_tile (format, data, xstride, ystride, zstride,
                           m_scratch, m_dither, x, y, z);

    // Handle weird photometric/color spaces
    if (m_photometric == PHOTOMETRIC_SEPARATED)
        data = convert_to_cmyk (spec().tile_pixels(), data);

    // Handle weird bit depths
    if (spec().format.size()*8 != m_bitspersample) {
        // Move to scratch area if not already there
        imagesize_t nbytes = spec().scanline_bytes();
        int nvals = int (spec().tile_pixels()) * spec().nchannels;
        if (data == origdata) {
            m_scratch.assign ((unsigned char *)data,
                              (unsigned char *)data+nbytes);
            data = &m_scratch[0];
        }
        if (spec().format == TypeDesc::UINT16 && m_bitspersample == 10) {
            convert_pack_bits<unsigned short, 10> ((unsigned short *)data, nvals);
        } else if (spec().format == TypeDesc::UINT16 && m_bitspersample == 12) {
            convert_pack_bits<unsigned short, 12> ((unsigned short *)data, nvals);
        } else if (spec().format == TypeDesc::UINT8 && m_bitspersample == 4) {
            convert_pack_bits<unsigned char, 4> ((unsigned char *)data, nvals);
        } else if (spec().format == TypeDesc::UINT8 && m_bitspersample == 2) {
            convert_pack_bits<unsigned char, 2> ((unsigned char *)data, nvals);
        } else {
            ASSERT (0 && "unsupported bit conversion -- shouldn't reach here");
        }
    }

    if (m_planarconfig == PLANARCONFIG_SEPARATE && m_spec.nchannels > 1) {
        // Convert from contiguous (RGBRGBRGB) to separate (RRRGGGBBB)
        imagesize_t tile_pixels = m_spec.tile_pixels();
        imagesize_t plane_bytes = tile_pixels * m_spec.format.size();
        DASSERT (plane_bytes*m_spec.nchannels == m_spec.tile_bytes());
        m_scratch.resize (m_spec.tile_bytes());

        boost::scoped_array<char> separate_heap;
        char *separate = NULL;
        imagesize_t separate_size = plane_bytes * m_spec.nchannels;
        if (separate_size <= (1<<16))
            separate = ALLOCA (char, separate_size);  // <=64k ? stack
        else {                                        // >64k ? heap
Ejemplo n.º 3
0
bool
TIFFOutput::write_tile (int x, int y, int z,
                        TypeDesc format, const void *data,
                        stride_t xstride, stride_t ystride, stride_t zstride)
{
    if (! m_spec.valid_tile_range (x, x, y, y, z, z))
        return false;
    m_spec.auto_stride (xstride, ystride, zstride, format, spec().nchannels,
                        spec().tile_width, spec().tile_height);
    x -= m_spec.x;   // Account for offset, so x,y are file relative, not 
    y -= m_spec.y;   // image relative
    const void *origdata = data;   // Stash original pointer
    data = to_native_tile (format, data, xstride, ystride, zstride, m_scratch);
    if (m_planarconfig == PLANARCONFIG_SEPARATE && m_spec.nchannels > 1) {
        // Convert from contiguous (RGBRGBRGB) to separate (RRRGGGBBB)
        imagesize_t tile_pixels = m_spec.tile_pixels();
        imagesize_t plane_bytes = tile_pixels * m_spec.format.size();
        DASSERT (plane_bytes*m_spec.nchannels == m_spec.tile_bytes());
        m_scratch.resize (m_spec.tile_bytes());
        contig_to_separate (tile_pixels, (const unsigned char *)data, &m_scratch[0]);
        for (int c = 0;  c < m_spec.nchannels;  ++c) {
            if (TIFFWriteTile (m_tif, (tdata_t)&m_scratch[plane_bytes*c], x, y, z, c) < 0) {
                error ("TIFFWriteTile failed");
                return false;
            }
        }
    } else {
        // No contig->separate is necessary.  But we still use scratch
        // space since TIFFWriteTile is destructive when
        // TIFFTAG_PREDICTOR is used.
        if (data == origdata) {
            m_scratch.assign ((unsigned char *)data,
                              (unsigned char *)data + m_spec.tile_bytes());
            data = &m_scratch[0];
        }
        if (TIFFWriteTile (m_tif, (tdata_t)data, x, y, z, 0) < 0) {
            error ("TIFFWriteTile failed");
            return false;
        }
    }
    
    // Should we checkpoint? Only if we have enough tiles and enough time has passed
    if (m_checkpointTimer() > DEFAULT_CHECKPOINT_INTERVAL_SECONDS && 
        m_checkpointItems >= MIN_SCANLINES_OR_TILES_PER_CHECKPOINT) {
        TIFFCheckpointDirectory (m_tif);
        m_checkpointTimer.lap();
        m_checkpointItems = 0;
    }
    else {
        ++m_checkpointItems;
    }
    
    return true;
}
Ejemplo n.º 4
0
bool
SocketOutput::write_tile (int x, int y, int z,
                          TypeDesc format, const void *data,
                          stride_t xstride, stride_t ystride, stride_t zstride)
{
    data = to_native_tile (format, data, xstride, ystride, zstride, m_scratch);

    try {
        socket_pvt::socket_write (socket, format, data, m_spec.tile_bytes ());
    } catch (boost::system::system_error &err) {
        error ("Error while writing: %s", err.what ());
        return false;
    } catch (...) {
        error ("Error while writing: unknown exception");
        return false;
    }

    return true;
}