コード例 #1
0
int main(int argc, char *argv[])
{
    //MyAssertHandler assertHandler;
    MyMessageHandler messageHandler;

    float gamma = 2.2f;
    nv::Path input;
    nv::Path output;
    uint size = 128;

    // Parse arguments.
    for (int i = 1; i < argc; i++)
    {
        // Input options.
        if (strcmp("-s", argv[i]) == 0)
        {
            if (i+1 < argc && argv[i+1][0] != '-') {
                size = (uint)atoi(argv[i+1]);
                i++;
            }
        }
        else if (argv[i][0] != '-')
        {
            input = argv[i];

            if (i+1 < argc && argv[i+1][0] != '-') {
                output = argv[i+1];
            }
            else {
                fprintf(stderr, "No output filename.\n");
                return 1;
            }

	    break;
	}
    }

    if (input.isNull() || output.isNull())
    {
        printf("NVIDIA Texture Tools - Copyright NVIDIA Corporation 2007\n\n");

        printf("usage: nv-gnome-thumbnailer [options] input output\n\n");

        printf("Options:\n");
        printf("  -s size\tThumbnail size (default = 128)\n");

        return 1;
    }

    nv::Image image;
    if (!loadImage(image, input.str())) return 1;

    nv::StringBuilder widthString;
    widthString.number(image.width());
    nv::StringBuilder heightString;
    heightString.number(image.height());

    nv::Array<const char *> metaData;
    metaData.append("Thumb::Image::Width");
    metaData.append(widthString.str());
    metaData.append("Thumb::Image::Height");
    metaData.append(heightString.str());
    metaData.append(NULL);
    metaData.append(NULL);

    if ((image.width() > size) || (image.height() > size))
    {
        nv::FloatImage fimage(&image);
        fimage.toLinear(0, 3, gamma);

	uint thumbW, thumbH;
	if (image.width() > image.height())
	{
	    thumbW = size;
	    thumbH = uint ((float (image.height()) / float (image.width())) * size);
	}
	else
	{
	    thumbW = uint ((float (image.width()) / float (image.height())) * size);
	    thumbH = size;
	}
	nv::AutoPtr<nv::FloatImage> fresult(fimage.resize(nv::BoxFilter(), thumbW, thumbH, nv::FloatImage::WrapMode_Clamp));

	nv::AutoPtr<nv::Image> result(fresult->createImageGammaCorrect(gamma));
	result->setFormat(nv::Image::Format_ARGB);

        nv::StdOutputStream stream(output.str());
        nv::ImageIO::save(output.str(), stream, result.ptr(), metaData.buffer());
    }
    else
    {
        nv::StdOutputStream stream(output.str());
        nv::ImageIO::save(output.str(), stream, &image, metaData.buffer());
    }
	
    return 0;
}
コード例 #2
0
ファイル: resize.cpp プロジェクト: 2asoft/xray-16
int main(int argc, char *argv[])
{
	//MyAssertHandler assertHandler;
	MyMessageHandler messageHandler;

	float scale = 0.5f;
	float gamma = 2.2f;
	nv::AutoPtr<nv::Filter> filter;
	nv::Path input;
	nv::Path output;
	
	nv::FloatImage::WrapMode wrapMode = nv::FloatImage::WrapMode_Mirror;

	// Parse arguments.
	for (int i = 1; i < argc; i++)
	{
		// Input options.
		if (strcmp("-s", argv[i]) == 0)
		{
			if (i+1 < argc && argv[i+1][0] != '-') {
				scale = (float)atof(argv[i+1]);
				i++;
			}
		}
		else if (strcmp("-g", argv[i]) == 0)
		{
			if (i+1 < argc && argv[i+1][0] != '-') {
				gamma = (float)atof(argv[i+1]);
				i++;
			}
		}
		else if (strcmp("-f", argv[i]) == 0)
		{
			if (i+1 == argc) break;
			i++;
			
			if (strcmp("box", argv[i]) == 0) filter = new nv::BoxFilter();
			else if (strcmp("triangle", argv[i]) == 0) filter = new nv::TriangleFilter();
			else if (strcmp("quadratic", argv[i]) == 0) filter = new nv::QuadraticFilter();
			else if (strcmp("bspline", argv[i]) == 0) filter = new nv::BSplineFilter();
			else if (strcmp("mitchell", argv[i]) == 0) filter = new nv::MitchellFilter();
			else if (strcmp("lanczos", argv[i]) == 0) filter = new nv::LanczosFilter();
			else if (strcmp("kaiser", argv[i]) == 0) {
				filter = new nv::KaiserFilter(3);
				((nv::KaiserFilter *)filter.ptr())->setParameters(4.0f, 1.0f);
			}
		}
		else if (strcmp("-w", argv[i]) == 0)
		{
			if (i+1 == argc) break;
			i++;

			if (strcmp("mirror", argv[i]) == 0) wrapMode = nv::FloatImage::WrapMode_Mirror;
			else if (strcmp("repeat", argv[i]) == 0) wrapMode = nv::FloatImage::WrapMode_Repeat;
			else if (strcmp("clamp", argv[i]) == 0) wrapMode = nv::FloatImage::WrapMode_Clamp;
		}
		else if (argv[i][0] != '-')
		{
			input = argv[i];

			if (i+1 < argc && argv[i+1][0] != '-') {
				output = argv[i+1];
			}

			break;
		}
	}

	if (input.isNull() || output.isNull())
	{
		printf("NVIDIA Texture Tools - Copyright NVIDIA Corporation 2007\n\n");	
		
		printf("usage: nvzoom [options] input [output]\n\n");
		
		printf("Options:\n");
		printf("  -s scale     Scale factor (default = 0.5)\n");
		printf("  -g gamma     Gamma correction (default = 2.2)\n");
		printf("  -f filter    One of the following: (default = 'box')\n");
		printf("                * box\n");
		printf("                * triangle\n");
		printf("                * quadratic\n");
		printf("                * bspline\n");
		printf("                * mitchell\n");
		printf("                * lanczos\n");
		printf("                * kaiser\n");
		printf("  -w mode      One of the following: (default = 'mirror')\n");
		printf("                * mirror\n");
		printf("                * repeat\n");
		printf("                * clamp\n");

		return 1;
	}
	
	if (filter == NULL)
	{
		filter = new nv::BoxFilter();
	}

	nv::Image image;
	if (!loadImage(image, input)) return 0;

	nv::FloatImage fimage(&image);
	fimage.toLinear(0, 3, gamma);
	
	nv::AutoPtr<nv::FloatImage> fresult(fimage.resize(*filter, uint(image.width() * scale), uint(image.height() * scale), wrapMode));
	
	nv::AutoPtr<nv::Image> result(fresult->createImageGammaCorrect(gamma));
	result->setFormat(nv::Image::Format_ARGB);

	nv::StdOutputStream stream(output);
	nv::ImageIO::saveTGA(stream, result.ptr());	// @@ Add generic save function. Add support for png too.
	
	return 0;
}
コード例 #3
0
int main(int argc, char *argv[])
{
    MyAssertHandler assertHandler;
    MyMessageHandler messageHandler;

    bool alpha = false;
    bool normal = false;
    bool color2normal = false;
    bool linear = false;
    bool wrapRepeat = false;
    bool noMipmaps = false;
    bool fast = false;
    bool nocuda = false;
    bool bc1n = false;
    bool luminance = false;
    nvtt::Format format = nvtt::Format_BC1;
    bool fillHoles = false;
    bool countEmptyRows = false;
    bool outProvided = false;
    bool premultiplyAlpha = false;
    nvtt::MipmapFilter mipmapFilter = nvtt::MipmapFilter_Box;
    bool loadAsFloat = false;
    bool rgbm = false;
    bool rangescale = false;

    const char * externalCompressor = NULL;

    bool silent = false;
    bool dds10 = false;

    nv::Path input;
    nv::Path output;


    // Parse arguments.
    for (int i = 1; i < argc; i++)
    {
        // Input options.
        if (strcmp("-color", argv[i]) == 0)
        {
        }
        else if (strcmp("-alpha", argv[i]) == 0)
        {
            alpha = true;
        }
        else if (strcmp("-normal", argv[i]) == 0)
        {
            normal = true;
        }
        else if (strcmp("-tonormal", argv[i]) == 0)
        {
            color2normal = true;
        }
		else if (strcmp("-linear", argv[i]) == 0)
		{
			linear = true;
		}
        else if (strcmp("-clamp", argv[i]) == 0)
        {
        }
        else if (strcmp("-repeat", argv[i]) == 0)
        {
            wrapRepeat = true;
        }
        else if (strcmp("-nomips", argv[i]) == 0)
        {
            noMipmaps = true;
        }
        else if (strcmp("-fillholes", argv[i]) == 0)
        {
            fillHoles = true;
        }
        else if (strcmp("-countempty", argv[i]) == 0)
        {
            countEmptyRows = true;
        }
        else if (strcmp("-premula", argv[i]) == 0)
        {
            premultiplyAlpha = true;
        }
        else if (strcmp("-mipfilter", argv[i]) == 0)
        {
            if (i+1 == argc) break;
            i++;

            if (strcmp("box", argv[i]) == 0) mipmapFilter = nvtt::MipmapFilter_Box;
            else if (strcmp("triangle", argv[i]) == 0) mipmapFilter = nvtt::MipmapFilter_Triangle;
            else if (strcmp("kaiser", argv[i]) == 0) mipmapFilter = nvtt::MipmapFilter_Kaiser;
        }
        else if (strcmp("-float", argv[i]) == 0)
        {
            loadAsFloat = true;
        }
        else if (strcmp("-rgbm", argv[i]) == 0)
        {
            rgbm = true;
        }
        else if (strcmp("-rangescale", argv[i]) == 0)
        {
            rangescale = true;
        }


        // Compression options.
        else if (strcmp("-fast", argv[i]) == 0)
        {
            fast = true;
        }
        else if (strcmp("-nocuda", argv[i]) == 0)
        {
            nocuda = true;
        }
        else if (strcmp("-rgb", argv[i]) == 0)
        {
            format = nvtt::Format_RGB;
        }
        else if (strcmp("-lumi", argv[i]) == 0)
        {
            luminance = true;
            format = nvtt::Format_RGB;
        }
        else if (strcmp("-bc1", argv[i]) == 0)
        {
            format = nvtt::Format_BC1;
        }
        else if (strcmp("-bc1n", argv[i]) == 0)
        {
            format = nvtt::Format_BC1;
            bc1n = true;
        }
        else if (strcmp("-bc1a", argv[i]) == 0)
        {
            format = nvtt::Format_BC1a;
        }
        else if (strcmp("-bc2", argv[i]) == 0)
        {
            format = nvtt::Format_BC2;
        }
        else if (strcmp("-bc3", argv[i]) == 0)
        {
            format = nvtt::Format_BC3;
        }
        else if (strcmp("-bc3n", argv[i]) == 0)
        {
            format = nvtt::Format_BC3n;
        }
        else if (strcmp("-bc4", argv[i]) == 0)
        {
            format = nvtt::Format_BC4;
        }
        else if (strcmp("-bc5", argv[i]) == 0)
        {
            format = nvtt::Format_BC5;
        }
        else if (strcmp("-bc6", argv[i]) == 0)
        {
            format = nvtt::Format_BC6;
        }
        else if (strcmp("-bc7", argv[i]) == 0)
        {
            format = nvtt::Format_BC7;
        }
        else if (strcmp("-bc3_rgbm", argv[i]) == 0)
        {
            format = nvtt::Format_BC3_RGBM;
            rgbm = true;
        }

        // Undocumented option. Mainly used for testing.
        else if (strcmp("-ext", argv[i]) == 0)
        {
            if (i+1 < argc && argv[i+1][0] != '-') {
                externalCompressor = argv[i+1];
                i++;
            }
        }
        else if (strcmp("-pause", argv[i]) == 0)
        {
            printf("Press ENTER\n"); fflush(stdout);
            getchar();
        }

        // Output options
        else if (strcmp("-silent", argv[i]) == 0)
        {
            silent = true;
        }
        else if (strcmp("-dds10", argv[i]) == 0)
        {
            dds10 = true;
        }

        else if (argv[i][0] != '-')
        {
            input = argv[i];

            if (i+1 < argc && argv[i+1][0] != '-') {
                output = argv[i+1];
                if(output.endsWith("\\") || output.endsWith("/")) {
                    //only path specified
                    output.append(input.fileName());
				    output.stripExtension();
				    output.append(".dds");
               }
               else
                   outProvided = true;
            }
            else
            {
                output.copy(input.str());
                output.stripExtension();
                output.append(".dds");
            }

            break;
        }
		else
		{
			printf("Warning: unrecognized option \"%s\"\n", argv[i]);
		}
    }

    const uint version = nvtt::version();
    const uint major = version / 100 / 100;
    const uint minor = (version / 100) % 100;
    const uint rev = version % 100;


    if (!silent)
    {
        printf("NVIDIA Texture Tools %u.%u.%u - Copyright NVIDIA Corporation 2007\n\n", major, minor, rev);
    }

    if (input.isNull())
    {
        printf("usage: nvcompress [options] infile [outfile.dds]\n\n");

        printf("Input options:\n");
        printf("  -color        The input image is a color map (default).\n");
        printf("  -alpha        The input image has an alpha channel used for transparency.\n");
        printf("  -normal       The input image is a normal map.\n");
        printf("  -linear       The input is in linear color space.\n");
        printf("  -tonormal     Convert input to normal map.\n");
        printf("  -clamp        Clamp wrapping mode (default).\n");
        printf("  -repeat       Repeat wrapping mode.\n");
        printf("  -nomips       Disable mipmap generation.\n");
        printf("  -premula      Premultiply alpha into color channel.\n");
        printf("  -mipfilter    Mipmap filter. One of the following: box, triangle, kaiser.\n");
        printf("  -float        Load as floating point image.\n\n");
        printf("  -rgbm         Transform input to RGBM.\n\n");
        printf("  -rangescale   Scale image to use entire color range.\n\n");
        printf("  -fillholes    Fill transparent areas with nearby color. Note: adds transparent upper height into output file name in case the outfile was not specified, and infile was in form #.####.xxx.ext\n\n");

        printf("Compression options:\n");
        printf("  -fast         Fast compression.\n");
        printf("  -nocuda       Do not use cuda compressor.\n");
        printf("  -rgb          RGBA format\n");
        printf("  -lumi         LUMINANCE format\n");
        printf("  -bc1          BC1 format (DXT1)\n");
        printf("  -bc1n         BC1 normal map format (DXT1nm)\n");
        printf("  -bc1a         BC1 format with binary alpha (DXT1a)\n");
        printf("  -bc2          BC2 format (DXT3)\n");
        printf("  -bc3          BC3 format (DXT5)\n");
        printf("  -bc3n         BC3 normal map format (DXT5nm)\n");
        printf("  -bc4          BC4 format (ATI1)\n");
        printf("  -bc5          BC5 format (3Dc/ATI2)\n");
        printf("  -bc6          BC6 format\n");
        printf("  -bc7          BC7 format\n\n");
        printf("  -bc3_rgbm     BC3-rgbm format\n\n");

        printf("Output options:\n");
        printf("  -silent  \tDo not output progress messages\n");
        printf("  -dds10   \tUse DirectX 10 DDS format (enabled by default for BC6/7)\n\n");

        return EXIT_FAILURE;
    }

    // Make sure input file exists.
    if (!nv::FileSystem::exists(input.str()))
    {
        fprintf(stderr, "The file '%s' does not exist.\n", input.str());
        return 1;
    }

    // Set input options.
    nvtt::InputOptions inputOptions;

    bool useSurface = false;    // @@ use Surface API in all cases!
    nvtt::Surface image;

    if (format == nvtt::Format_Unknown && nv::strCaseDiff(input.extension(), ".dds") == 0)
    {
        // Load surface.
        nv::DirectDrawSurface dds(input.str());
        if (!dds.isValid())
        {
            fprintf(stderr, "The file '%s' is not a valid DDS file.\n", input.str());
            return EXIT_FAILURE;
        }

        if (!dds.isSupported())
        {
            fprintf(stderr, "The file '%s' is not a supported DDS file.\n", input.str());
            return EXIT_FAILURE;
        }

        //if format not specified, get from dds
        if (dds.isRGB())
            format = nvtt::Format_RGB;
        else if (dds.isLuminance()) {
            luminance = true;
            format = nvtt::Format_RGB;
        }
        else {
            uint cc = dds.fourcc();
            switch(cc) {
            case nv::FOURCC_DXT1:   format = nvtt::Format_DXT1; break;
            case nv::FOURCC_DXT3:   format = nvtt::Format_DXT3; break;
            case nv::FOURCC_DXT5:   format = nvtt::Format_DXT5; break;
            case nv::FOURCC_RXGB:   format = nvtt::Format_BC3n; break;
            case nv::FOURCC_ATI1:   format = nvtt::Format_BC4; break;
            case nv::FOURCC_ATI2:   format = nvtt::Format_BC5; break;
            }
        }

        alpha = dds.hasAlpha();
    }


    if (format == nvtt::Format_BC3_RGBM || rgbm) {
        useSurface = true;

        if (!image.load(input.str())) {
            fprintf(stderr, "Error opening input file '%s'.\n", input.str());
            return EXIT_FAILURE;
        }

        if (rangescale) {
            // get color range
            float min_color[3], max_color[3];
            image.range(0, &min_color[0], &max_color[0]);
            image.range(1, &min_color[1], &max_color[1]);
            image.range(2, &min_color[2], &max_color[2]);

            //printf("Color range = %.2f %.2f %.2f\n", max_color[0], max_color[1], max_color[2]);

            float color_range = nv::max3(max_color[0], max_color[1], max_color[2]);
            const float max_color_range = 16.0f;

            if (color_range > max_color_range) {
                //Log::print("Clamping color range %f to %f\n", color_range, max_color_range);
                color_range = max_color_range;
            }
            //color_range = max_color_range;  // Use a fixed color range for now.

            for (int i = 0; i < 3; i++) {
                image.scaleBias(i, 1.0f / color_range, 0.0f);
            }
            image.toneMap(nvtt::ToneMapper_Linear, /*parameters=*/NULL); // Clamp without changing the hue.

            // Clamp alpha.
            image.clamp(3);
        }

        if (alpha) {
            image.setAlphaMode(nvtt::AlphaMode_Transparency);
        }

        // To gamma.
        image.toGamma(2);

        if (format != nvtt::Format_BC3_RGBM) {
            image.setAlphaMode(nvtt::AlphaMode_None);
            image.toRGBM(1, 0.15f);
        }
    }
    else if (format == nvtt::Format_BC6) {
        //format = nvtt::Format_BC1;
        //fprintf(stderr, "BLABLABLA.\n");
        useSurface = true;

        if (!image.load(input.str())) {
            fprintf(stderr, "Error opening input file '%s'.\n", input.str());
            return EXIT_FAILURE;
        }

        image.setAlphaMode(nvtt::AlphaMode_Transparency);
    }
    else {
        if (nv::strCaseDiff(input.extension(), ".dds") == 0)
        {
            // Load surface.
            nv::DirectDrawSurface dds(input.str());
            if (!dds.isValid())
            {
                fprintf(stderr, "The file '%s' is not a valid DDS file.\n", input.str());
                return EXIT_FAILURE;
            }

            if (!dds.isSupported())
            {
                fprintf(stderr, "The file '%s' is not a supported DDS file.\n", input.str());
                return EXIT_FAILURE;
            }

            uint faceCount;
            if (dds.isTexture2D())
            {
                inputOptions.setTextureLayout(nvtt::TextureType_2D, dds.width(), dds.height());
                faceCount = 1;
            }
            else if (dds.isTexture3D())
            {
                inputOptions.setTextureLayout(nvtt::TextureType_3D, dds.width(), dds.height(), dds.depth());
                faceCount = 1;

                nvDebugBreak();
            }
            else if (dds.isTextureCube()) {
                inputOptions.setTextureLayout(nvtt::TextureType_Cube, dds.width(), dds.height());
                faceCount = 6;
            } else {
                nvDebugCheck(dds.isTextureArray());
                inputOptions.setTextureLayout(nvtt::TextureType_Array, dds.width(), dds.height(), 1, dds.arraySize());
                faceCount = dds.arraySize();
                dds10 = true;
            }

            uint mipmapCount = dds.mipmapCount();

            nv::Image mipmap;

            for (uint f = 0; f < faceCount; f++)
            {
                for (uint m = 0; m < mipmapCount; m++)
                {
                    dds.mipmap(&mipmap, f, m); // @@ Load as float.

                    inputOptions.setMipmapData(mipmap.pixels(), mipmap.width(), mipmap.height(), mipmap.depth(), f, m);
                }
            }
        }
        else
        {
            if (nv::strCaseDiff(input.extension(), ".exr") == 0 || nv::strCaseDiff(input.extension(), ".hdr") == 0)
            {
                loadAsFloat = true;
            }

            if (loadAsFloat)
            {
                nv::AutoPtr<nv::FloatImage> image(nv::ImageIO::loadFloat(input.str()));

                if (image == NULL)
                {
                    fprintf(stderr, "The file '%s' is not a supported image type.\n", input.str());
                    return EXIT_FAILURE;
                }

                inputOptions.setFormat(nvtt::InputFormat_RGBA_32F);
                inputOptions.setTextureLayout(nvtt::TextureType_2D, image->width(), image->height());

                /*for (uint i = 0; i < image->componentNum(); i++)
                {
                    inputOptions.setMipmapChannelData(image->channel(i), i, image->width(), image->height());
                }*/
            }
            else
            {
                // Regular image.
                nv::Image image;
                if (!image.load(input.str()))
                {
                    fprintf(stderr, "The file '%s' is not a supported image type.\n", input.str());
                    return 1;
                }

                if(countEmptyRows)
                {
                    //count empty rows & append to the file name
                    const int w = image.width();
                    const int h = image.height();
                    int ytr = 0;   //height of the transparent part

                    if(image.format() == image.Format_ARGB) {
                        for(int y=0; y<h; ++y) {
                            for(int x=0; x<w; ++x) {
                                if(image.pixel(x,y).a >= 128) {
                                    ytr = y;
                                    y = h;
                                    break;
                                }
                            }
                        }
                    }

                    //change outfile
                    output.stripExtension();
                    output.appendFormat(".%04i.dds", ytr);
                }

                if(fillHoles) {
                    nv::FloatImage fimage(&image);

                    // create feature mask
                    nv::BitMap bmp(image.width(),image.height());
                    bmp.clearAll();
                    const int w=image.width();
                    const int h=image.height();
                    int ytr = h;   //height of the transparent part
                    for(int y=0; y<h; ++y)
                        for(int x=0; x<w; ++x) 
                            if(fimage.pixel(3,x,y,0) >= 0.5f) {
                                bmp.setBitAt(x,y);
                                if(y < ytr) ytr = y;
                            }


                    // fill holes
                    nv::fillVoronoi(&fimage,&bmp);

                    // do blur passes
                    for(int i=0; i<8; ++i)
                        nv::fillBlur(&fimage,&bmp);

                    nv::AutoPtr<nv::Image> img(fimage.createImage(0));

                    inputOptions.setTextureLayout(nvtt::TextureType_2D, img->width(), img->height());
                    inputOptions.setMipmapData(img->pixels(), img->width(), img->height());
                }
                else {
                    inputOptions.setTextureLayout(nvtt::TextureType_2D, image.width(), image.height());
                    inputOptions.setMipmapData(image.pixels(), image.width(), image.height());
                }
            }

        }


        if (format == nvtt::Format_Unknown)
            format = nvtt::Format_BC1;


        if (wrapRepeat)
        {
            inputOptions.setWrapMode(nvtt::WrapMode_Repeat);
        }
        else
        {
            inputOptions.setWrapMode(nvtt::WrapMode_Clamp);
        }

        if (alpha)
        {
            inputOptions.setAlphaMode(nvtt::AlphaMode_Transparency);
        }
        else
        {
            inputOptions.setAlphaMode(nvtt::AlphaMode_None);
        }

        // Block compressed textures with mipmaps must be powers of two.
        if (!noMipmaps && format != nvtt::Format_RGB)
        {
            //inputOptions.setRoundMode(nvtt::RoundMode_ToPreviousPowerOfTwo);
        }

        if (linear)
        {
            setLinearMap(inputOptions);
        }
        else if (normal)
        {
            setNormalMap(inputOptions);
        }
        else if (color2normal)
        {
            setColorToNormalMap(inputOptions);
        }
        else
        {
            setColorMap(inputOptions);
        }

        if (noMipmaps)
        {
            inputOptions.setMipmapGeneration(false);
        }

        /*if (premultiplyAlpha)
        {
            inputOptions.setPremultiplyAlpha(true);
            inputOptions.setAlphaMode(nvtt::AlphaMode_Premultiplied);
        }*/

        inputOptions.setMipmapFilter(mipmapFilter);
    }



    nvtt::CompressionOptions compressionOptions;
    compressionOptions.setFormat(format);

    //compressionOptions.setQuantization(/*color dithering*/true, /*alpha dithering*/false, /*binary alpha*/false);

    if (format == nvtt::Format_BC2) {
        // Dither alpha when using BC2.
        compressionOptions.setQuantization(/*color dithering*/false, /*alpha dithering*/true, /*binary alpha*/false);
    }
    else if (format == nvtt::Format_BC1a) {
        // Binary alpha when using BC1a.
        compressionOptions.setQuantization(/*color dithering*/false, /*alpha dithering*/true, /*binary alpha*/true, 127);
    }
    else if (format == nvtt::Format_RGBA)
    {
        if (luminance)
        {
            compressionOptions.setPixelFormat(8, 0xff, 0, 0, 0);
        }
        else {
            // @@ Edit this to choose the desired pixel format:
            // compressionOptions.setPixelType(nvtt::PixelType_Float);
            // compressionOptions.setPixelFormat(16, 16, 16, 16);
            // compressionOptions.setPixelType(nvtt::PixelType_UnsignedNorm);
            // compressionOptions.setPixelFormat(16, 0, 0, 0);

            //compressionOptions.setQuantization(/*color dithering*/true, /*alpha dithering*/false, /*binary alpha*/false);
            //compressionOptions.setPixelType(nvtt::PixelType_UnsignedNorm);
            //compressionOptions.setPixelFormat(5, 6, 5, 0);
            //compressionOptions.setPixelFormat(8, 8, 8, 8);

            // A4R4G4B4
            //compressionOptions.setPixelFormat(16, 0xF00, 0xF0, 0xF, 0xF000);

            //compressionOptions.setPixelFormat(32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000);

            // R10B20G10A2
            //compressionOptions.setPixelFormat(10, 10, 10, 2);

            // DXGI_FORMAT_R11G11B10_FLOAT
            //compressionOptions.setPixelType(nvtt::PixelType_Float);
            //compressionOptions.setPixelFormat(11, 11, 10, 0);
        }
    }
    else if (format == nvtt::Format_BC6)
    {
        compressionOptions.setPixelType(nvtt::PixelType_UnsignedFloat);
    }

    if (fast)
    {
        compressionOptions.setQuality(nvtt::Quality_Fastest);
    }
    else
    {
        compressionOptions.setQuality(nvtt::Quality_Normal);
        //compressionOptions.setQuality(nvtt::Quality_Production);
        //compressionOptions.setQuality(nvtt::Quality_Highest);
    }

    if (bc1n)
    {
        compressionOptions.setColorWeights(1, 1, 0);
    }

    
    //compressionOptions.setColorWeights(0.2126, 0.7152, 0.0722);
    //compressionOptions.setColorWeights(0.299, 0.587, 0.114);
    //compressionOptions.setColorWeights(3, 4, 2);

    if (externalCompressor != NULL)
    {
        compressionOptions.setExternalCompressor(externalCompressor);
    }


    MyErrorHandler errorHandler;
    MyOutputHandler outputHandler(output.str());
    if (outputHandler.stream->isError())
    {
        fprintf(stderr, "Error opening '%s' for writting\n", output.str());
        return EXIT_FAILURE;
    }

    nvtt::Context context;
    context.enableCudaAcceleration(!nocuda);

    if (!silent) 
    {
        printf("CUDA acceleration ");
        if (context.isCudaAccelerationEnabled())
        {
            printf("ENABLED\n\n");
        }
        else
        {
            printf("DISABLED\n\n");
        }
    }

    int outputSize = 0;
    if (useSurface) {
        outputSize = context.estimateSize(image, 1, compressionOptions);
    }
    else {
        outputSize = context.estimateSize(inputOptions, compressionOptions);
    }

    outputHandler.setTotal(outputSize);
    outputHandler.setDisplayProgress(!silent);

    nvtt::OutputOptions outputOptions;
    //outputOptions.setFileName(output);
    outputOptions.setOutputHandler(&outputHandler);
    outputOptions.setErrorHandler(&errorHandler);

	// Automatically use dds10 if compressing to BC6 or BC7
	if (format == nvtt::Format_BC6 || format == nvtt::Format_BC7)
	{
		dds10 = true;
	}

    if (dds10)
    {
        outputOptions.setContainer(nvtt::Container_DDS10);
    }

    // printf("Press ENTER.\n");
    // fflush(stdout);
    // getchar();

    nv::Timer timer;
    timer.start();

    if (useSurface) {
        if (!context.outputHeader(image, 1, compressionOptions, outputOptions)) {
            fprintf(stderr, "Error writing file header.\n");
            return EXIT_FAILURE;
        }
        if (!context.compress(image, 0, 0, compressionOptions, outputOptions)) {
            fprintf(stderr, "Error compressing file.\n");
            return EXIT_FAILURE;
        } 
    }
    else {
        if (!context.process(inputOptions, compressionOptions, outputOptions)) {
            return EXIT_FAILURE;
        }
    }

    timer.stop();

    if (!silent) {
        printf("\rtime taken: %.3f seconds\n", timer.elapsed());
    }

    return EXIT_SUCCESS;
}
コード例 #4
0
ファイル: main.cpp プロジェクト: jstraub/Pangolin
void VideoViewer(const std::string& input_uri, const std::string& output_uri)
{
    pangolin::Var<int>  record_timelapse_frame_skip("viewer.record_timelapse_frame_skip", 1 );
    pangolin::Var<int>  end_frame("viewer.end_frame", std::numeric_limits<int>::max() );
    pangolin::Var<bool> video_wait("video.wait", true);
    pangolin::Var<bool> video_newest("video.newest", false);

    // Open Video by URI
    pangolin::VideoRecordRepeat video(input_uri, output_uri);
    const size_t num_streams = video.Streams().size();

    if(num_streams == 0) {
        pango_print_error("No video streams from device.\n");
        return;
    }

    // Output details of video stream
    for(size_t s = 0; s < num_streams; ++s) {
        const pangolin::StreamInfo& si = video.Streams()[s];
        std::cout << "Stream " << s << ": " << si.Width() << " x " << si.Height()
                  << " " << si.PixFormat().format << " (pitch: " << si.Pitch() << " bytes)" << std::endl;
    }

    // Check if video supports VideoPlaybackInterface
    pangolin::VideoPlaybackInterface* video_playback = pangolin::FindFirstMatchingVideoInterface<pangolin::VideoPlaybackInterface>(video);
    const int total_frames = video_playback ? video_playback->GetTotalFrames() : std::numeric_limits<int>::max();
    const int slider_size = (total_frames < std::numeric_limits<int>::max() ? 20 : 0);

    if( video_playback ) {
        if(total_frames < std::numeric_limits<int>::max() ) {
            std::cout << "Video length: " << total_frames << " frames" << std::endl;
        }
        end_frame = 0;
    }

    std::vector<unsigned char> buffer;
    buffer.resize(video.SizeBytes()+1);

    // Create OpenGL window - guess sensible dimensions
    pangolin::CreateWindowAndBind( "VideoViewer",
        (int)(video.Width() * num_streams),
        (int)(video.Height() + slider_size)
    );

    // Assume packed OpenGL data unless otherwise specified
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // Setup resizable views for video streams
    std::vector<pangolin::GlPixFormat> glfmt;
    std::vector<std::pair<float,float> > gloffsetscale;
    std::vector<size_t> strides;
    std::vector<pangolin::ImageViewHandler> handlers;
    handlers.reserve(num_streams);

    size_t scratch_buffer_bytes = 0;

    pangolin::View& container = pangolin::Display("streams");
    container.SetLayout(pangolin::LayoutEqual)
             .SetBounds(pangolin::Attach::Pix(slider_size), 1.0, 0.0, 1.0);
    for(unsigned int d=0; d < num_streams; ++d) {
        const pangolin::StreamInfo& si = video.Streams()[d];
        pangolin::View& view = pangolin::CreateDisplay().SetAspect(si.Aspect());
        container.AddDisplay(view);
        glfmt.push_back(pangolin::GlPixFormat(si.PixFormat()));
        gloffsetscale.push_back(std::pair<float,float>(0.0f, 1.0f) );
        if( si.PixFormat().bpp % 8 ) {
            pango_print_warn("Stream %i: Unable to display formats that are not a multiple of 8 bits.", d);
        }
        if( (8*si.Pitch()) % si.PixFormat().bpp ) {
            pango_print_warn("Stream %i: Unable to display formats whose pitch is not a whole number of pixels.", d);
        }
        if(glfmt.back().gltype == GL_DOUBLE) {
            scratch_buffer_bytes = std::max(scratch_buffer_bytes, sizeof(float)*si.Width() * si.Height());
        }
        strides.push_back( (8*si.Pitch()) / si.PixFormat().bpp );
        handlers.push_back( pangolin::ImageViewHandler(si.Width(), si.Height()) );
        view.SetHandler(&handlers.back());
    }

    // current frame in memory buffer and displaying.
    pangolin::Var<int> frame("ui.frame", -1, 0, total_frames-1 );
    pangolin::Slider frame_slider("frame", frame.Ref() );
    if(video_playback && total_frames < std::numeric_limits<int>::max())
    {
        frame_slider.SetBounds(0.0, pangolin::Attach::Pix(slider_size), 0.0, 1.0);
        pangolin::DisplayBase().AddDisplay(frame_slider);
    }

    std::vector<unsigned char> scratch_buffer;
    scratch_buffer.resize(scratch_buffer_bytes);

    std::vector<pangolin::Image<unsigned char> > images;

#ifdef CALLEE_HAS_CPP11
    const int FRAME_SKIP = 30;
    const char show_hide_keys[]  = {'1','2','3','4','5','6','7','8','9'};
    const char screenshot_keys[] = {'!','"','#','$','%','^','&','*','('};

    // Show/hide streams
    for(size_t v=0; v < container.NumChildren() && v < 9; v++) {
        pangolin::RegisterKeyPressCallback(show_hide_keys[v], [v,&container](){
            container[v].ToggleShow();
        } );
        pangolin::RegisterKeyPressCallback(screenshot_keys[v], [v,&images,&video](){
            if(v < images.size() && images[v].ptr) {
                try{
                    pangolin::SaveImage(
                        images[v], video.Streams()[v].PixFormat(),
                        pangolin::MakeUniqueFilename("capture.png")
                    );
                }catch(std::exception e){
                    pango_print_error("Unable to save frame: %s\n", e.what());
                }
            }
        } );
    }

    pangolin::RegisterKeyPressCallback('r', [&](){
        if(!video.IsRecording()) {
            video.SetTimelapse( static_cast<size_t>(record_timelapse_frame_skip) );
            video.Record();
            pango_print_info("Started Recording.\n");
        }else{
            video.Stop();
            pango_print_info("Finished recording.\n");
        }
        fflush(stdout);
    });
    pangolin::RegisterKeyPressCallback('p', [&](){
        video.Play();
        end_frame = std::numeric_limits<int>::max();
        pango_print_info("Playing from file log.\n");
        fflush(stdout);
    });
    pangolin::RegisterKeyPressCallback('s', [&](){
        video.Source();
        end_frame = std::numeric_limits<int>::max();
        pango_print_info("Playing from source input.\n");
        fflush(stdout);
    });
    pangolin::RegisterKeyPressCallback(' ', [&](){
        end_frame = (frame < end_frame) ? frame : std::numeric_limits<int>::max();
    });
    pangolin::RegisterKeyPressCallback('w', [&](){
        video_wait = !video_wait;
        if(video_wait) {
            pango_print_info("Gui wait's for video frame.\n");
        }else{
            pango_print_info("Gui doesn't wait for video frame.\n");
        }
    });
    pangolin::RegisterKeyPressCallback('d', [&](){
        video_newest = !video_newest;
        if(video_newest) {
            pango_print_info("Discarding old frames.\n");
        }else{
            pango_print_info("Not discarding old frames.\n");
        }
    });
    pangolin::RegisterKeyPressCallback('<', [&](){
        if(video_playback) {
            frame = video_playback->Seek(frame - FRAME_SKIP) -1;
            end_frame = frame + 1;
        }else{
            pango_print_warn("Unable to skip backward.");
        }
    });
    pangolin::RegisterKeyPressCallback('>', [&](){
        if(video_playback) {
            frame = video_playback->Seek(frame + FRAME_SKIP) -1;
            end_frame = frame + 1;
        }else{
            end_frame = frame + FRAME_SKIP;
        }
    });
    pangolin::RegisterKeyPressCallback(',', [&](){
        if(video_playback) {
            frame = video_playback->Seek(frame - 1) -1;
            end_frame = frame+1;
        }else{
            pango_print_warn("Unable to skip backward.");
        }
    });
    pangolin::RegisterKeyPressCallback('.', [&](){
        // Pause at next frame
        end_frame = frame+1;
    });
    pangolin::RegisterKeyPressCallback('0', [&](){
        video.RecordOneFrame();
    });
    pangolin::RegisterKeyPressCallback('a', [&](){
        // Adapt scale
        for(unsigned int i=0; i<images.size(); ++i) {
            if(container[i].HasFocus()) {
                pangolin::Image<unsigned char>& img = images[i];
                pangolin::ImageViewHandler& ivh = handlers[i];

                const bool have_selection = std::isfinite(ivh.GetSelection().Area()) && std::abs(ivh.GetSelection().Area()) >= 4;
                pangolin::XYRangef froi = have_selection ? ivh.GetSelection() : ivh.GetViewToRender();
                gloffsetscale[i] = pangolin::GetOffsetScale(img, froi.Cast<int>(), glfmt[i]);
            }
        }
    });
    pangolin::RegisterKeyPressCallback('g', [&](){
        std::pair<float,float> os_default(0.0f, 1.0f);

        // Get the scale and offset from the container that has focus.
        for(unsigned int i=0; i<images.size(); ++i) {
            if(container[i].HasFocus()) {
                pangolin::Image<unsigned char>& img = images[i];
                pangolin::ImageViewHandler& ivh = handlers[i];

                const bool have_selection = std::isfinite(ivh.GetSelection().Area()) && std::abs(ivh.GetSelection().Area()) >= 4;
                pangolin::XYRangef froi = have_selection ? ivh.GetSelection() : ivh.GetViewToRender();
                os_default = pangolin::GetOffsetScale(img, froi.Cast<int>(), glfmt[i]);
                break;
            }
        }

        // Adapt scale for all images equally
        // TODO : we're assuming the type of all the containers images' are the same.
        for(unsigned int i=0; i<images.size(); ++i) {
            gloffsetscale[i] = os_default;
        }

    });
#endif // CALLEE_HAS_CPP11

#ifdef DEBUGVIDEOVIEWER
    unsigned int delayms = 0;
    pangolin::RegisterKeyPressCallback('z', [&](){
      // Adapt delay
      delayms += 1;
      std::cout << "                  Fake delay " << delayms << "ms" << std::endl;
    });

    pangolin::RegisterKeyPressCallback('x', [&](){
      // Adapt delay
      delayms = (delayms > 1) ? delayms-1 : 0;
    });

    pangolin::basetime start,now;
#endif // DEBUGVIDEOVIEWER

    // Stream and display video
    while(!pangolin::ShouldQuit())
    {
        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
        glColor3f(1.0f, 1.0f, 1.0f);

        if(frame.GuiChanged()) {
            if(video_playback) {
                frame = video_playback->Seek(frame) -1;
            }
            end_frame = frame + 1;
        }

#ifdef DEBUGVIDEOVIEWER
        boostd::this_thread::sleep_for(boostd::chrono::milliseconds(delayms));
        std::cout << "-------------------------------------------------------" << std::endl;
        now = pangolin::TimeNow();
        std::cout << "      FPS: " << 1.0/pangolin::TimeDiff_s(start, now) << " artificial delay: " << delayms <<"ms"<< std::endl;
        std::cout << "-------------------------------------------------------" << std::endl;
        start = now;
#endif
        if ( frame < end_frame ) {
            if( video.Grab(&buffer[0], images, video_wait, video_newest) ) {
                frame = frame +1;
            }
        }
#ifdef DEBUGVIDEOVIEWER
        const pangolin::basetime end = pangolin::TimeNow();
        std::cout << "Total grab time: " << 1000*pangolin::TimeDiff_s(start, end) << "ms" << std::endl;
#endif

        glLineWidth(1.5f);
        glDisable(GL_DEPTH_TEST);

        for(unsigned int i=0; i<images.size(); ++i)
        {
            if(container[i].IsShown()) {
                container[i].Activate();
                pangolin::Image<unsigned char>& image = images[i];

                // Get texture of correct dimension / format
                const pangolin::GlPixFormat& fmt = glfmt[i];
                pangolin::GlTexture& tex = pangolin::TextureCache::I().GlTex((GLsizei)image.w, (GLsizei)image.h, fmt.scalable_internal_format, fmt.glformat, GL_FLOAT);

                // Upload image data to texture
                tex.Bind();
                if(fmt.gltype == GL_DOUBLE) {
                    // Convert to float first, using scrath_buffer for storage
                    pangolin::Image<float> fimage(image.w, image.h, image.w*sizeof(float), (float*)scratch_buffer.data());
                    ConvertPixels<float,double>( fimage, image.Reinterpret<double>() );
                    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
                    tex.Upload(fimage.ptr,0,0, (GLsizei)fimage.w, (GLsizei)fimage.h, fmt.glformat, GL_FLOAT);
                }else{
                    glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)strides[i]);
                    tex.Upload(image.ptr,0,0, (GLsizei)image.w, (GLsizei)image.h, fmt.glformat, fmt.gltype);
                }

                // Render
                handlers[i].UpdateView();
                handlers[i].glSetViewOrtho();
                const std::pair<float,float> os = gloffsetscale[i];
                pangolin::GlSlUtilities::OffsetAndScale(os.first, os.second);
                handlers[i].glRenderTexture(tex);
                pangolin::GlSlUtilities::UseNone();
                handlers[i].glRenderOverlay();
            }
        }
        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);

        // leave in pixel orthographic for slider to render.
        pangolin::DisplayBase().ActivatePixelOrthographic();
        if(video.IsRecording()) {
            pangolin::glRecordGraphic(pangolin::DisplayBase().v.w-14.0f, pangolin::DisplayBase().v.h-14.0f, 7.0f);
        }
        pangolin::FinishFrame();
    }
}