Exemple #1
0
bool EventRecorder::grabScreenAndComputeMD5(Graphics::Surface &screen, uint8 md5[16]) {
	if (!createScreenShot(screen)) {
		warning("Can't save screenshot");
		return false;
	}
	Common::MemoryReadStream bitmapStream((const byte*)screen.getPixels(), screen.w * screen.h * screen.format.bytesPerPixel);
	computeStreamMD5(bitmapStream, md5);
	return true;
}
int main(int argc, char** argv) {
    SkCommandLineFlags::SetUsage(
            "Usage: visualize_color_gamut --input <path to input image> "
                                         "--output <path to output image> "
                                         "--sRGB <draw canonical sRGB gamut> "
                                         "--adobeRGB <draw canonical Adobe RGB gamut> "
                                         "--uncorrected <path to reencoded, uncorrected "
                                         "               input image>\n"
            "Description: Writes a visualization of the color gamut to the output image  ."
                         "Also, if a path is provided, writes uncorrected bytes to an unmarked "
                         "png, for comparison with the input image.\n");
    SkCommandLineFlags::Parse(argc, argv);
    const char* input = FLAGS_input[0];
    const char* output = FLAGS_output[0];
    if (!input || !output) {
        SkCommandLineFlags::PrintUsage();
        return -1;
    }

    SkAutoTUnref<SkData> data(SkData::NewFromFileName(input));
    if (!data) {
        SkDebugf("Cannot find input image.\n");
        return -1;
    }
    SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data));
    if (!codec) {
        SkDebugf("Invalid input image.\n");
        return -1;
    }

    // Load a graph of the CIE XYZ color gamut.
    SkBitmap gamut;
    if (!GetResourceAsBitmap("gamut.png", &gamut)) {
        SkDebugf("Program failure.\n");
        return -1;
    }
    SkCanvas canvas(gamut);

    // Draw the sRGB gamut if requested.
    if (FLAGS_sRGB) {
        sk_sp<SkColorSpace> sRGBSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
        draw_gamut(&canvas, sRGBSpace->xyz(), "sRGB", 0xFFFF9394, false);
    }

    // Draw the Adobe RGB gamut if requested.
    if (FLAGS_adobeRGB) {
        sk_sp<SkColorSpace> adobeRGBSpace = SkColorSpace::NewNamed(SkColorSpace::kAdobeRGB_Named);
        draw_gamut(&canvas, adobeRGBSpace->xyz(), "Adobe RGB", 0xFF31a9e1, false);
    }

    // Draw gamut for the input image.
    sk_sp<SkColorSpace> colorSpace = sk_ref_sp(codec->getInfo().colorSpace());
    if (!colorSpace) {
        SkDebugf("Image had no embedded color space information.  Defaulting to sRGB.\n");
        colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
    }
    draw_gamut(&canvas, colorSpace->xyz(), input, 0xFF000000, true);

    // Finally, encode the result to the output file.
    SkAutoTUnref<SkData> out(SkImageEncoder::EncodeData(gamut, SkImageEncoder::kPNG_Type, 100));
    if (!out) {
        SkDebugf("Failed to encode gamut output.\n");
        return -1;
    }
    SkFILEWStream stream(output);
    bool result = stream.write(out->data(), out->size());
    if (!result) {
        SkDebugf("Failed to write gamut output.\n");
        return -1;
    }

    // Also, if requested, decode and reencode the uncorrected input image.
    if (!FLAGS_uncorrected.isEmpty()) {
        SkBitmap bitmap;
        int width = codec->getInfo().width();
        int height = codec->getInfo().height();
        SkAlphaType alphaType = codec->getInfo().alphaType();
        bitmap.allocN32Pixels(width, height, kOpaque_SkAlphaType == alphaType);
        SkImageInfo decodeInfo = SkImageInfo::MakeN32(width, height, alphaType);
        if (SkCodec::kSuccess != codec->getPixels(decodeInfo, bitmap.getPixels(),
                                                  bitmap.rowBytes())) {
            SkDebugf("Could not decode input image.\n");
            return -1;
        }
        out.reset(SkImageEncoder::EncodeData(bitmap, SkImageEncoder::kPNG_Type, 100));
        if (!out) {
            SkDebugf("Failed to encode uncorrected image.\n");
            return -1;
        }
        SkFILEWStream bitmapStream(FLAGS_uncorrected[0]);
        result = bitmapStream.write(out->data(), out->size());
        if (!result) {
            SkDebugf("Failed to write uncorrected image output.\n");
            return -1;
        }
    }

    return 0;
}
Exemple #3
0
void createBitmaps(std::string name)
{
   constexpr unsigned SCALE_FACTOR = 24;

   // After changing this function to allocate a lot more memory for objects with
   // automatic storage duration, some of that memory started to look kind of nonrandom.
   // Dynamic storage duration seems to result in subjectively much more random memory.
   std::unique_ptr<std::array<std::array<char, 24 * 24 / 8>, N>>
      xBitMapsPointer{new std::array<std::array<char, 24 * 24 / 8>, N>};

   std::array<std::array<char, 24 * 24 / 8>, N>& xBitMaps = *xBitMapsPointer;

   for (std::size_t bitmapNum = 0; bitmapNum < N; ++bitmapNum)
   {
      std::array<char, 24 * 24 / 8>& bits = xBitMaps[bitmapNum];
      for (std::size_t i = 0; i < bits.size(); ++i)
         bits[i] = ~bits[i];

      for (std::size_t i = 0 + 3 + 1; i < 24 - 3 + 1; i += 3)
         bits[i] = bits[i] ^ std::bitset<8>{"01111110"}.to_ulong();
      for (std::size_t i = 24 + 3 + 2; i < 48 - 3 + 2; i += 3)
         bits[i] = bits[i] ^ std::bitset<8>{"01111110"}.to_ulong();
      for (std::size_t i = 48 + 3; i < 72 - 3;) {
         bits[i] = bits[i] ^ std::bitset<8>{"01111110"}.to_ulong(); ++i;
         bits[i] = bits[i] ^ std::bitset<8>{"01111110"}.to_ulong(); ++i;
         bits[i] = bits[i] ^ std::bitset<8>{"01111110"}.to_ulong(); ++i;
      }

      std::stringstream sStream;
      sStream << std::setfill('0') << std::setw(2) << bitmapNum;

      // I was going to use std::int8_t in case there are more than 8 bits in a char, but
      // how can there be an int8_t then?
      #if (CHAR_BIT != 8)
        #error
      #endif

      #ifndef BOOST_LITTLE_ENDIAN
        #error
      #endif

      std::ofstream bitmapStream(name + sStream.str() + ".bmp", std::ios::binary);

      constexpr std::uint32_t dibHeaderSize = 40;

      char pixelArray[24 * SCALE_FACTOR * 24 * SCALE_FACTOR / 8];

      constexpr char colorTable[8] = {
         0x00, 0x00, 0x00, 0x00,
         0x20, 0x20, 0x20, 0x00
      };

      constexpr std::uint32_t fileSize = 14 + dibHeaderSize + sizeof(colorTable) +
         sizeof(pixelArray);
      constexpr std::uint32_t offset   = 14 + dibHeaderSize + sizeof(colorTable);

      const char bitmapFileHeader[14] = {
         0x42, 0x4d, // "BM"
         reinterpret_cast<const char*>(&fileSize)[0],
         reinterpret_cast<const char*>(&fileSize)[1],
         reinterpret_cast<const char*>(&fileSize)[2],
         reinterpret_cast<const char*>(&fileSize)[3],
         0, 0, 0, 0,
         reinterpret_cast<const char*>(&offset)[0],
         reinterpret_cast<const char*>(&offset)[1],
         reinterpret_cast<const char*>(&offset)[2],
         reinterpret_cast<const char*>(&offset)[3],
      };

      // This will be supported soonish!  Remember to change the color table to 3 byte per
      // entry.  See github.com/wxWidgets/wxWidgets/commit/371928415ab3cf79647153f96907838
      /*
      std::uint16_t bitmapWidth   = 24 * SCALE_FACTOR;
      std::uint16_t bitmapHeight  = 24 * SCALE_FACTOR;
      std::uint16_t one           = 1;

      const char bitmapCoreHeader[dibHeaderSize] = {
         reinterpret_cast<const char*>(&dibHeaderSize)[0],
         reinterpret_cast<const char*>(&dibHeaderSize)[1],
         reinterpret_cast<const char*>(&dibHeaderSize)[2],
         reinterpret_cast<const char*>(&dibHeaderSize)[3],
         reinterpret_cast<const char*>(&bitmapWidth)[0],
         reinterpret_cast<const char*>(&bitmapWidth)[1],
         reinterpret_cast<const char*>(&bitmapHeight)[0],
         reinterpret_cast<const char*>(&bitmapHeight)[1],
         reinterpret_cast<const char*>(&one)[0], // Number of color planes, must be 1
         reinterpret_cast<const char*>(&one)[1],
         reinterpret_cast<const char*>(&one)[0], // Number of bits per pixel
         reinterpret_cast<const char*>(&one)[1],
      };
      */

      std::int32_t  bitmapWidth  = 24 * SCALE_FACTOR;
      std::int32_t  bitmapHeight = 24 * SCALE_FACTOR;
      std::uint16_t one          = 1;
      std::uint32_t imageSize    = sizeof(pixelArray);

      const char bitmapInfoHeader[dibHeaderSize] = {
         reinterpret_cast<const char*>(&dibHeaderSize)[0],
         reinterpret_cast<const char*>(&dibHeaderSize)[1],
         reinterpret_cast<const char*>(&dibHeaderSize)[2],
         reinterpret_cast<const char*>(&dibHeaderSize)[3],
         reinterpret_cast<const char*>(&bitmapWidth)[0],
         reinterpret_cast<const char*>(&bitmapWidth)[1],
         reinterpret_cast<const char*>(&bitmapWidth)[2],
         reinterpret_cast<const char*>(&bitmapWidth)[3],
         reinterpret_cast<const char*>(&bitmapHeight)[0],
         reinterpret_cast<const char*>(&bitmapHeight)[1],
         reinterpret_cast<const char*>(&bitmapHeight)[2],
         reinterpret_cast<const char*>(&bitmapHeight)[3],
         reinterpret_cast<const char*>(&one)[0], // Number of color planes, must be 1
         reinterpret_cast<const char*>(&one)[1],
         reinterpret_cast<const char*>(&one)[0], // Number of bits per pixel
         reinterpret_cast<const char*>(&one)[1],
         0, 0, 0, 0,
         reinterpret_cast<const char*>(&imageSize)[0],
         reinterpret_cast<const char*>(&imageSize)[1],
         reinterpret_cast<const char*>(&imageSize)[2],
         reinterpret_cast<const char*>(&imageSize)[3],
         0, 0, 0, 0,
         0, 0, 0, 0,
         2, 0, 0, 0,
         2, 0, 0, 0
      };

      for (unsigned rowNum = 0; rowNum < 24; ++rowNum)
      {
         for (unsigned colNum = 0; colNum < 24; ++colNum)
         {
            unsigned byteNum = (24 * rowNum + colNum) / 8;
            unsigned bitNum  = (24 * rowNum + colNum) % 8;
            bool set = (bits[byteNum] >> bitNum) & 1;
            for (unsigned i = 0; i < SCALE_FACTOR; ++i)
            {
               for (unsigned j = 0; j < SCALE_FACTOR / 8; ++j)
               {
                  int pixelNum = (SCALE_FACTOR * SCALE_FACTOR * 24 * (23 - rowNum) +
                     SCALE_FACTOR * colNum + 24 * SCALE_FACTOR * i) / 8 + j;
                  pixelArray[pixelNum] = set ? 0x00 : 0xff;
               }
            }
         }
      }

      bitmapStream.write(bitmapFileHeader, sizeof(bitmapFileHeader));
      bitmapStream.write(bitmapInfoHeader, dibHeaderSize);
      bitmapStream.write(colorTable, sizeof(colorTable));
      bitmapStream.write(pixelArray, sizeof(pixelArray));
   }
}