Example #1
0
int _tmain(int argc, _TCHAR* argv[]) {
#else
int main(int argc, char **argv) {
#endif

  if(argc != 2 && argc != 3) {
    fprintf(stderr, "Usage: sc <img1>\n");
    return 1;
  }

  int spSize = 5;
  if(argc == 3) {
    sscanf(argv[2], "%d", &spSize);
  }

  ImageFile imgFile (argv[1]);
  if(!imgFile.Load()) {
    fprintf(stderr, "Error loading file: %s\n", argv[1]);
    return 1;
  }

  FasTC::Image<> *img = imgFile.GetImage();

  const int kWidth = img->GetWidth();
  const int kHeight = img->GetHeight();
  const int nPixels = kWidth * kHeight;
  const uint32 pixelBufSz = nPixels * sizeof(FasTC::Pixel);

  FasTC::Pixel *pixels = new FasTC::Pixel[pixelBufSz];
  memcpy(pixels, img->GetPixels(), pixelBufSz);

  uint32 *rawPixels = new uint32[kWidth * kHeight];

  for(int i = 0; i < nPixels; i++) {
    // Pixels are stored as little endian ARGB, so we want ABGR
    pixels[i].Shuffle(0x6C); // 01 10 11 00
    rawPixels[i] = pixels[i].Pack();
  }

  int *labels = new int[nPixels];
  int numLabels;

  SLIC slic;
  slic.PerformSLICO_ForGivenStepSize(
    rawPixels,
	kWidth,
    kHeight,
    labels,
    numLabels,
	spSize, 1.0);

  std::unordered_map<uint32, Region> regions;
  CollectPixels(kWidth, kHeight, pixels, labels, regions);
  std::cout << "Num regions: " << regions.size() << std::endl;

  for(auto &r : regions) {
    r.second.Compress();
    r.second.Reconstruct();
  }

  for(int i = 0; i < nPixels; i++) {
    pixels[i] = regions[labels[i]].GetNextPixel();
    pixels[i].Shuffle(0x6C);
  }

  std::vector<Partition<4, 4> > partitions;
  EnumerateBPTC(partitions);
  std::cout << partitions.size() << " 4x4 BPTC partitions" << std::endl;

  VpTree<Partition<4, 4>, Partition<4, 4>::Distance> vptree;
  vptree.create(partitions);

  // Just to test, find the partition close to half 0 half 1..
  Partition<4, 4> test;
  for(uint32 i = 0; i < 16; i++) {
    if(i < 8) {
      test[i] = 0;
    } else {
      test[i] = 1;
    }
  }

  vector<Partition<4, 4> > closest;
  vptree.search(test, 1, &closest, NULL);
  std::cout << closest[0].GetIndex() << std::endl;

  BPTCC::CompressionSettings settings;
  settings.m_NumSimulatedAnnealingSteps = 0;
  settings.m_ShapeSelectionFn = ChosePresegmentedShape<4, 4>;

  SelectionInfo info(vptree, labels, kWidth, kHeight);
  settings.m_ShapeSelectionUserData = &info;

  uint8 *outBuf = new uint8[kWidth * kHeight];
  FasTC::CompressionJob cj(
     FasTC::eCompressionFormat_BPTC,
     reinterpret_cast<const uint8 *>(pixels),
     outBuf,
     static_cast<uint32>(kWidth),
     static_cast<uint32>(kHeight));

  StopWatch sw;
  sw.Start();
  BPTCC::Compress(cj, settings);
  sw.Stop();
  std::cout << "Compression time: " << sw.TimeInMilliseconds() << "ms" << std::endl;

  CompressedImage ci(kWidth, kHeight, FasTC::eCompressionFormat_BPTC, outBuf);
  FasTC::Image<> outImg(kWidth, kHeight, pixels);

  std::cout << "PSNR: " << outImg.ComputePSNR(&ci) << "db" << std::endl;

  ImageFile outImgFile("out.png", eFileFormat_PNG, outImg);
  outImgFile.Write();

  delete [] labels;
  delete [] rawPixels;
  delete [] pixels;
  return 0;
}
Example #2
0
int main(int argc, char **argv) {

  int fileArg = 1;
  if(fileArg == argc) {
    PrintUsage();
    exit(1);
  }

  char decompressedOutput[256]; decompressedOutput[0] = '\0';
  bool bNoDecompress = false;
  int numJobs = 0;
  int quality = 50;
  int numThreads = 1;
  int numCompressions = 1;
  bool bUseSIMD = false;
  bool bSaveLog = false;
  bool bUseAtomics = false;
  bool bUsePVRTexLib = false;
  bool bUseNVTT = false;
  bool bVerbose = false;
  FasTC::ECompressionFormat format = FasTC::eCompressionFormat_BPTC;

  bool knowArg = false;
  do {
    knowArg = false;

    if(strcmp(argv[fileArg], "-n") == 0) {
      fileArg++;

      if(fileArg == argc || (numCompressions = atoi(argv[fileArg])) < 0) {
        PrintUsage();
        exit(1);
      }

      fileArg++;
      knowArg = true;
      continue;
    }

    if(strcmp(argv[fileArg], "-f") == 0) {
      fileArg++;

      if(fileArg == argc) {
        PrintUsage();
        exit(1);
      } else {
        if(!strcmp(argv[fileArg], "PVRTC")) {
          format = FasTC::eCompressionFormat_PVRTC4;
        } else if(!strcmp(argv[fileArg], "PVRTCLib")) {
          format = FasTC::eCompressionFormat_PVRTC4;
          bUsePVRTexLib = true;
        } else if(!strcmp(argv[fileArg], "BPTCLib")) {
          format = FasTC::eCompressionFormat_BPTC;
          bUseNVTT = true;
        } else if(!strcmp(argv[fileArg], "ETC1")) {
          format = FasTC::eCompressionFormat_ETC1;
        } else if(!strcmp(argv[fileArg], "DXT1")) {
          format = FasTC::eCompressionFormat_DXT1;
        } else if(!strcmp(argv[fileArg], "DXT5")) {
          format = FasTC::eCompressionFormat_DXT5;
        }
      }

      fileArg++;
      knowArg = true;
      continue;
    }

    if(strcmp(argv[fileArg], "-d") == 0) {
      fileArg++;
      
      if(fileArg == argc) {
        PrintUsage();
        exit(1);
      } else {
        size_t sz = 255;
        sz = ::std::min(sz, static_cast<size_t>(strlen(argv[fileArg])));
        memcpy(decompressedOutput, argv[fileArg], sz + 1);
      }

      fileArg++;
      knowArg = true;
      continue;
    }

    if(strcmp(argv[fileArg], "-nd") == 0) {
      fileArg++;
      bNoDecompress = true;
      knowArg = true;
      continue;
    }

    if(strcmp(argv[fileArg], "-l") == 0) {
      fileArg++;
      bSaveLog = true;
      knowArg = true;
      continue;
    }
    
    if(strcmp(argv[fileArg], "-v") == 0) {
      fileArg++;
      bVerbose = true;
      knowArg = true;
      continue;
    }
    
    if(strcmp(argv[fileArg], "-simd") == 0) {
      fileArg++;
      bUseSIMD = true;
      knowArg = true;
      continue;
    }

    if(strcmp(argv[fileArg], "-t") == 0) {
      fileArg++;
      
      if(fileArg == argc || (numThreads = atoi(argv[fileArg])) < 1) {
        PrintUsage();
        exit(1);
      }

      fileArg++;
      knowArg = true;
      continue;
    }

    if(strcmp(argv[fileArg], "-q") == 0) {
      fileArg++;
      
      if(fileArg == argc || (quality = atoi(argv[fileArg])) < 0) {
        PrintUsage();
        exit(1);
      }

      fileArg++;
      knowArg = true;
      continue;
    }

    if(strcmp(argv[fileArg], "-j") == 0) {
      fileArg++;
      
      if(fileArg == argc || (numJobs = atoi(argv[fileArg])) < 0) {
        PrintUsage();
        exit(1);
      }

      fileArg++;
      knowArg = true;
      continue;
    }

    if(strcmp(argv[fileArg], "-a") == 0) {
      fileArg++;
      bUseAtomics = true;
      knowArg = true;
      continue;
    }

  } while(knowArg && fileArg < argc);

  if(fileArg == argc) {
    PrintUsage();
    exit(1);
  }

  char basename[256];
  ExtractBasename(argv[fileArg], basename, 256);

  ImageFile file (argv[fileArg]);
  if(!file.Load()) {
    fprintf(stderr, "Error loading file: %s\n", argv[fileArg]);
    return 1;
  }

  FasTC::Image<> img(*file.GetImage());

  if(bVerbose) {
    fprintf(stdout, "Entropy: %.5f\n", img.ComputeEntropy());
    fprintf(stdout, "Mean Local Entropy: %.5f\n", img.ComputeMeanLocalEntropy());
  }

  std::ofstream logFile;
  ThreadSafeStreambuf streamBuf(logFile);
  std::ostream logStream(&streamBuf);
  if(bSaveLog) {
    char logname[256];
    sprintf(logname, "%s.log", basename);
    logFile.open(logname);
  }
  
  SCompressionSettings settings;
  settings.format = format;
  settings.bUseSIMD = bUseSIMD;
  settings.bUseAtomics = bUseAtomics;
  settings.iNumThreads = numThreads;
  settings.iQuality = quality;
  settings.iNumCompressions = numCompressions;
  settings.iJobSize = numJobs;
  settings.bUsePVRTexLib = bUsePVRTexLib;
  settings.bUseNVTT = bUseNVTT;
  if(bSaveLog) {
    settings.logStream = &logStream;
  } else {
    settings.logStream = NULL;
  }

  CompressedImage *ci = CompressImage(&img, settings);
  if(NULL == ci) {
    fprintf(stderr, "Error compressing image!\n");
    return 1;
  }

  double PSNR = img.ComputePSNR(ci);
  if(PSNR > 0.0) {
    fprintf(stdout, "PSNR: %.3f\n", PSNR);
  }
  else {
    fprintf(stderr, "Error computing PSNR\n");
  }

  if(bVerbose) {
    double SSIM = img.ComputeSSIM(ci);
    if(SSIM > 0.0) {
      fprintf(stdout, "SSIM: %.9f\n", SSIM);
    } else {
      fprintf(stderr, "Error computing SSIM\n");
    }
  }

  if(!bNoDecompress) {
    if(decompressedOutput[0] != '\0') {
      memcpy(basename, decompressedOutput, 256);
    } else if(format == FasTC::eCompressionFormat_BPTC) {
      strcat(basename, "-bptc.png");
    } else if(format == FasTC::eCompressionFormat_PVRTC4) {
      strcat(basename, "-pvrtc-4bpp.png");
    } else if(format == FasTC::eCompressionFormat_DXT1) {
      strcat(basename, "-dxt1.png");
    } else if(format == FasTC::eCompressionFormat_ETC1) {
      strcat(basename, "-etc1.png");
    }

    EImageFileFormat fmt = ImageFile::DetectFileFormat(basename);
    ImageFile cImgFile (basename, fmt, *ci);
    cImgFile.Write();
  }

  // Cleanup 
  delete ci;
  if(bSaveLog) {
    logFile.close();
  }
  return 0;
}