/* * Copyright 2015 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include "SkForceLinking.h" __SK_FORCE_IMAGE_DECODER_LINKING; #include "fiddle_main.h" // Globals externed in fiddle_main.h SkBitmap source; sk_sp image; static void encode_to_base64(const void* data, size_t size, FILE* out) { const uint8_t* input = reinterpret_cast(data); const uint8_t* end = &input[size]; static const char codes[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz0123456789+/"; while (input != end) { uint8_t b = (*input & 0xFC) >> 2; fputc(codes[b], out); b = (*input & 0x03) << 4; ++input; if (input == end) { fputc(codes[b], out); fputs("==", out); return; } b |= (*input & 0xF0) >> 4; fputc(codes[b], out); b = (*input & 0x0F) << 2; ++input; if (input == end) { fputc(codes[b], out); fputc('=', out); return; } b |= (*input & 0xC0) >> 6; fputc(codes[b], out); b = *input & 0x3F; fputc(codes[b], out); ++input; } } static void dump_output(const sk_sp& data, const char* name, bool last = true) { if (data) { printf("\t\"%s\": \"", name); encode_to_base64(data->data(), data->size(), stdout); fputs(last ? "\"\n" : "\",\n", stdout); } } static SkData* encode_snapshot(const sk_sp& surface) { sk_sp img(surface->makeImageSnapshot()); return img ? img->encode() : nullptr; } #if defined(__linux) && !defined(__ANDROID__) #include static sk_sp create_grcontext() { // We just leak the OSMesaContext... the process will die soon anyway. if (OSMesaContext osMesaContext = OSMesaCreateContextExt(OSMESA_BGRA, 0, 0, 0, nullptr)) { static uint32_t buffer[16 * 16]; OSMesaMakeCurrent(osMesaContext, &buffer, GL_UNSIGNED_BYTE, 16, 16); } auto osmesa_get = [](void* ctx, const char name[]) { SkASSERT(nullptr == ctx); SkASSERT(OSMesaGetCurrentContext()); return OSMesaGetProcAddress(name); }; sk_sp mesa(GrGLAssembleInterface(nullptr, osmesa_get)); if (!mesa) { return nullptr; } return sk_sp(GrContext::Create( kOpenGL_GrBackend, reinterpret_cast(mesa.get()))); } #else static sk_sp create_grcontext() { return nullptr; } #endif int main() { const DrawOptions options = GetDrawOptions(); if (options.source) { sk_sp data(SkData::MakeFromFileName(options.source)); if (!data) { perror(options.source); return 1; } else { image = SkImage::MakeFromEncoded(std::move(data)); if (!image) { perror("Unable to decode the source image."); return 1; } SkAssertResult(image->asLegacyBitmap( &source, SkImage::kRO_LegacyBitmapMode)); } } sk_sp rasterData, gpuData, pdfData, skpData; if (options.raster) { auto rasterSurface = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(options.size)); srand(0); draw(rasterSurface->getCanvas()); rasterData.reset(encode_snapshot(rasterSurface)); } if (options.gpu) { auto grContext = create_grcontext(); if (!grContext) { fputs("Unable to get GrContext.\n", stderr); } else { auto surface = SkSurface::MakeRenderTarget( grContext.get(), SkBudgeted::kNo, SkImageInfo::MakeN32Premul(options.size)); if (!surface) { fputs("Unable to get render surface.\n", stderr); exit(1); } srand(0); draw(surface->getCanvas()); gpuData.reset(encode_snapshot(surface)); } } if (options.pdf) { SkDynamicMemoryWStream pdfStream; sk_sp document(SkDocument::MakePDF(&pdfStream)); srand(0); draw(document->beginPage(options.size.width(), options.size.height())); document->close(); pdfData.reset(pdfStream.copyToData()); } if (options.skp) { SkSize size; size = options.size; SkPictureRecorder recorder; srand(0); draw(recorder.beginRecording(size.width(), size.height())); auto picture = recorder.finishRecordingAsPicture(); SkDynamicMemoryWStream skpStream; picture->serialize(&skpStream); skpData.reset(skpStream.copyToData()); } printf("{\n"); dump_output(rasterData, "Raster", !gpuData && !pdfData && !skpData); dump_output(gpuData, "Gpu", !pdfData && !skpData); dump_output(pdfData, "Pdf", !skpData); dump_output(skpData, "Skp"); printf("}\n"); return 0; }