Пример #1
0
bool
ImageOutputWrap::write_tiles_bt (int xbegin, int xend, int ybegin, int yend,
                                 int zbegin, int zend, TypeDesc::BASETYPE format,
                                 object &buffer, stride_t xstride,
                                 stride_t ystride, stride_t zstride)
{
    return write_tiles (xbegin, xend, ybegin, yend, zbegin, zend,
                        format, buffer, xstride, ystride, zstride);    
}
Пример #2
0
bool
OpenEXROutput::write_tile (int x, int y, int z,
                           TypeDesc format, const void *data,
                           stride_t xstride, stride_t ystride, stride_t zstride)
{
    return write_tiles (x, std::min (x+m_spec.tile_width, m_spec.x+m_spec.width),
                        y, std::min (y+m_spec.tile_height, m_spec.y+m_spec.height),
                        z, std::min (z+m_spec.tile_depth, m_spec.z+m_spec.depth),
                        format, data, xstride, ystride, zstride);
}
Пример #3
0
bool VoxelsIOPlugin::save(const QString &formatName, const QString &fileName, MeshModel &m, const int mask,const RichParameterSet & par, vcg::CallBackPos *cb, QWidget *parent)
{
  // TODO Add error messages

  vcg::tri::UpdatePosition< CMeshO >::Scale
    ( m.cm,
      static_cast< CMeshO::ScalarType >( rasterization_scale ) );

  vcg::tri::UpdateBounding< CMeshO >::Box( m.cm );

  init_voxmap_size( m );

  QScopedArrayPointer< unsigned char > voxels( rasterize( this, m ) );

  QString nrrd;

  if( !voxels ||
      (nrrd = write_nrrd( voxels.data() )).isEmpty() ||
      !(voxels.reset( resample( nrrd )), voxels) ||
      !write_tiles( voxels.data(), fileName ) )
    return false;

  QFile header( fileName.endsWith( ".voxels" ) ?
                fileName.left( fileName.length() -
                               QString( ".voxels" ).length() ) :
                fileName + ".header" );
  if( !header.open( QIODevice::WriteOnly ) )
    return false;

  QTextStream str( &header );
  str <<
    ";;; -*- lisp -*-\n(size " <<
    voxmap_size.X() << " " << voxmap_size.Y() << " " << voxmap_size.Z() <<
    ")\n(voxels . \"" << fileName << "\")\n";

  return true;
}
Пример #4
0
bool
ImageOutput::write_image (TypeDesc format, const void *data,
                          stride_t xstride, stride_t ystride, stride_t zstride,
                          ProgressCallback progress_callback,
                          void *progress_callback_data)
{
    bool native = (format == TypeDesc::UNKNOWN);
    stride_t pixel_bytes = native ? (stride_t) m_spec.pixel_bytes (native)
                                  : format.size() * m_spec.nchannels;
    if (xstride == AutoStride)
        xstride = pixel_bytes;
    m_spec.auto_stride (xstride, ystride, zstride, format,
                        m_spec.nchannels, m_spec.width, m_spec.height);

    if (supports ("rectangles")) {
        // Use a rectangle if we can
        return write_rectangle (0, m_spec.width, 0, m_spec.height, 0, m_spec.depth,
                                format, data, xstride, ystride, zstride);
    }

    bool ok = true;
    if (progress_callback && progress_callback (progress_callback_data, 0.0f))
        return ok;
    if (m_spec.tile_width && supports ("tiles")) {
        // Tiled image
        for (int z = 0;  z < m_spec.depth;  z += m_spec.tile_depth) {
            int zend = std::min (z+m_spec.z+m_spec.tile_depth,
                                 m_spec.z+m_spec.depth);
            for (int y = 0;  y < m_spec.height;  y += m_spec.tile_height) {
                int yend = std::min (y+m_spec.y+m_spec.tile_height,
                                     m_spec.y+m_spec.height);
                const char *d = (const char *)data + z*zstride + y*ystride;
                ok &= write_tiles (m_spec.x, m_spec.x+m_spec.width,
                                   y+m_spec.y, yend, z+m_spec.z, zend,
                                   format, d, xstride, ystride, zstride);
                if (progress_callback &&
                    progress_callback (progress_callback_data,
                                       (float)(z*m_spec.height+y)/(m_spec.height*m_spec.depth)))
                    return ok;
            }
        }
    } else {
        // Scanline image
        const int chunk = 256;
        for (int z = 0;  z < m_spec.depth;  ++z)
            for (int y = 0;  y < m_spec.height && ok;  y += chunk) {
                int yend = std::min (y+m_spec.y+chunk, m_spec.y+m_spec.height);
                const char *d = (const char *)data + z*zstride + y*ystride;
                ok &= write_scanlines (y+m_spec.y, yend, z+m_spec.z,
                                       format, d, xstride, ystride);
                if (progress_callback &&
                    progress_callback (progress_callback_data,
                                       (float)(z*m_spec.height+y)/(m_spec.height*m_spec.depth)))
                    return ok;
            }
    }
    if (progress_callback)
        progress_callback (progress_callback_data, 1.0f);

    return ok;
}
Пример #5
0
/**
 * Program entrypoint.
 */
int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    QWidget window;

    unsigned char *raw_data;
    unsigned char *buf;
    int *color_freqs;
    int *unique_pals;
    int unique_pals_count;
    int *pal_indexes;
    unsigned char *pal_data;
    int *pal_sizes;
    unsigned char *tile_data;
    int tile_data_sz;
    unsigned char *attrib_data;
    int attrib_data_sz;
    const char *input_filename = 0;
    const char *chr_output_filename = 0;
    const char *pal_output_filename = 0;
    const char *attrib_output_filename = 0;
    int width = -1;
    int height = -1;

    /* Process arguments. */
    if (!process_args(argv, &input_filename, &chr_output_filename, &pal_output_filename,
                      &attrib_output_filename, &width, &height)) {
        return(-1);
    }

    /* check arguments */
    if (!input_filename) {
        fprintf(stderr, "img2nes: no filename given\n");
        return(-1);
    }
#if 0
    if (width == -1 || height == -1) {
        fprintf(stderr, "img2nes: please specify width and height of image\n");
        return(-1);
    }
    if (width % 16 || height % 16) {
        fprintf(stderr, "img2nes: width and height must be multiples of 16\n");
        return(-1);
    }
#endif

    QImage originalImage = QImage(input_filename).convertToFormat(QImage::Format_RGB32);
    if (originalImage.isNull()) {
        fprintf(stderr, "img2nes: unable to read image '%s'\n", input_filename);
        return(-1);
    }
    width = originalImage.width();
    height = originalImage.height();

    /* allocate some buffers */
    raw_data = (unsigned char *)malloc(width * height * 3);
    buf = (unsigned char *)malloc(width * height);
    tile_data_sz = (height / 8) * (width / 8) * 16 * sizeof(unsigned char);
    tile_data = (unsigned char *)malloc(tile_data_sz);
    if (!raw_data || !buf || !tile_data) {
        fprintf(stderr, "img2nes: failed to allocate memory for image data\n");
        return(0);
    }

#if 0
    /* read input image */
    if (!read_image(input_filename, width, height, /*has_alpha=*/0, raw_data))
        return(-1);
#endif

    /* convert raw RGB to nes palette indices */
    convert_to_nes_colors(originalImage.bits(), width, height, /*has_alpha=*/1, buf);

    QImage originalNesImage = to_qimage(buf, width, height);

    QImage reducedColorsImage;
    QImage reducedPalettesImage;

    /* that was the easy part */
    {
        int i, j;
        int cw = width / 16;
        int ch = height / 16;
        color_freqs = (int*)calloc(cw * ch,  64 * sizeof(int));
        pal_data = (unsigned char *)malloc(cw * ch * 4 * sizeof(unsigned char));
        pal_sizes = (int*)malloc(cw * ch * sizeof(int));
        /* process all 16x16 blocks */
        for (i = 0; i < ch; ++i) {
            for (j = 0; j < cw; ++j) {
                int num_colors;
                unsigned char pal[64];
                int *f = &color_freqs[(i*cw+j)*64];
                /* count frequency of colors */
                count_nes_color_frequencies(&buf[i*16*width+(j*16)], 16, 16, width, f);
                f[0x0F] = INT_MAX;

                /* record the colors that are actually used */
                nes_palette_from_color_frequencies(f, pal, &num_colors);

#if 0
                {
                    printf("palette: ");
                    for (int k = 0; k < num_colors; ++k) {
                        printf("%.2X ", pal[k]);
                    }
                    printf("\n");
                }
#endif

                /* reduce number of colors if necessary */
                reduce_colors(&buf[i*16*width+(j*16)], 16, 16, width, f, pal, &num_colors);

                /* sort the palette so that different palettes can be easily compared */
                qsort(pal, num_colors, sizeof(unsigned char), compare_nes_colors);
#if 0
                {
                    printf("sorted palette: ");
                    for (int k = 0; k < num_colors; ++k) {
                        printf("%.2X ", pal[k]);
                    }
                    printf("\n");
                }
#endif

                /* store the final palette for this 16x16 block */
                assert(num_colors <= 4);
                memcpy(&pal_data[(i*cw+j)*4], pal, num_colors * sizeof(unsigned char));
                pal_sizes[i*cw+j] = num_colors;
            }
        }

        reducedColorsImage = to_qimage(buf, width, height);

        /* now each 16x16 block uses max 4 unique colors
           the next step is to reduce the number of 4-color palettes, if necessary */
        unique_pals = (int*)malloc(cw * ch * sizeof(int));
        unique_pals_count = 0;
        pal_indexes = (int*)malloc(cw * ch * sizeof(int));
        /* find unique palettes and record their usage */
        find_unique_palettes(pal_data, cw * ch, pal_sizes, unique_pals, &unique_pals_count, pal_indexes);

        /*	    printf("unique palettes: %d\n", unique_pals_count); */
        /* reduce number of palettes used if necessary */
        reduce_palettes(buf, width, height, pal_data, pal_sizes, unique_pals, &unique_pals_count, pal_indexes);

        reducedPalettesImage = to_qimage(buf, width, height);

        /* encode tiles */
        encode_nes_tiles(buf, width, height, pal_data, pal_sizes, unique_pals, pal_indexes, tile_data);

        /* write tiles */
        write_tiles(chr_output_filename, tile_data, tile_data_sz);

        /* write palette data */
        write_palettes(pal_output_filename, pal_data, pal_sizes, unique_pals, unique_pals_count);

        /* encode attribute data */
        attrib_data_sz = (cw/2)*(ch/2);
        attrib_data = (unsigned char *)malloc(attrib_data_sz);
        encode_nes_attributes(cw, ch, pal_indexes, attrib_data);

        /* write attribute data */
        write_attributes(attrib_output_filename, attrib_data, attrib_data_sz);
    }

    QHBoxLayout *box = new QHBoxLayout(&window);
    box->addWidget(create_label(originalImage));
    box->addWidget(create_label(originalNesImage));
    box->addWidget(create_label(reducedColorsImage));
    box->addWidget(create_label(reducedPalettesImage));
    window.show();
    app.exec();

    /* Cleanup */
    free(raw_data);
    free(buf);
    free(tile_data);
    free(pal_data);
    free(pal_sizes);
    free(unique_pals);
    free(pal_indexes);
    free(color_freqs);
    free(attrib_data);

    /* All done. */
    return 0;
}