DEF_TEST(JpegIdentification, r) { static struct { const char* path; bool isJfif; SkJFIFInfo::Type type; } kTests[] = {{"CMYK.jpg", false, SkJFIFInfo::kGrayscale}, {"color_wheel.jpg", true, SkJFIFInfo::kYCbCr}, {"grayscale.jpg", true, SkJFIFInfo::kGrayscale}, {"mandrill_512_q075.jpg", true, SkJFIFInfo::kYCbCr}, {"randPixels.jpg", true, SkJFIFInfo::kYCbCr}}; for (size_t i = 0; i < SK_ARRAY_COUNT(kTests); ++i) { SkAutoTUnref<SkData> data( load_resource(r, "JpegIdentification", kTests[i].path)); if (!data) { continue; } SkJFIFInfo info; bool isJfif = SkIsJFIF(data, &info); if (isJfif != kTests[i].isJfif) { ERRORF(r, "%s failed isJfif test", kTests[i].path); continue; } if (!isJfif) { continue; // not applicable } if (kTests[i].type != info.fType) { ERRORF(r, "%s failed jfif type test", kTests[i].path); continue; } if (r->verbose()) { SkDebugf("\nJpegIdentification: %s [%d x %d]\n", kTests[i].path, info.fSize.width(), info.fSize.height()); } } }
sk_sp<SkPDFObject> SkPDFCreateBitmapObject(sk_sp<SkImage> image, SkPixelSerializer* pixelSerializer) { SkASSERT(image); sk_sp<SkData> data(image->refEncoded()); SkJFIFInfo info; if (data && SkIsJFIF(data.get(), &info) && (!pixelSerializer || pixelSerializer->useEncodedData(data->data(), data->size()))) { // If there is a SkPixelSerializer, give it a chance to // re-encode the JPEG with more compression by returning false // from useEncodedData. bool yuv = info.fType == SkJFIFInfo::kYCbCr; if (info.fSize == image->dimensions()) { // Sanity check. // hold on to data, not image. #ifdef SK_PDF_IMAGE_STATS gJpegImageObjects.fetch_add(1); #endif return sk_make_sp<PDFJpegBitmap>(info.fSize, data.get(), yuv); } } if (pixelSerializer) { SkBitmap bm; SkAutoPixmapUnlock apu; if (as_IB(image.get())->getROPixels(&bm) && bm.requestLock(&apu)) { data.reset(pixelSerializer->encode(apu.pixmap())); if (data && SkIsJFIF(data.get(), &info)) { bool yuv = info.fType == SkJFIFInfo::kYCbCr; if (info.fSize == image->dimensions()) { // Sanity check. return sk_make_sp<PDFJpegBitmap>(info.fSize, data.get(), yuv); } } } } sk_sp<SkPDFObject> smask; if (!image_compute_is_opaque(image.get())) { smask = sk_make_sp<PDFAlphaBitmap>(image); } #ifdef SK_PDF_IMAGE_STATS gRegularImageObjects.fetch_add(1); #endif return sk_make_sp<PDFDefaultBitmap>(std::move(image), std::move(smask)); }
SkPDFBitmap* SkPDFBitmap::Create(SkPDFCanon* canon, const SkBitmap& bitmap) { SkASSERT(canon); if (!SkColorTypeIsValid(bitmap.colorType()) || kUnknown_SkColorType == bitmap.colorType()) { return NULL; } SkBitmap copy; const SkBitmap& bm = immutable_bitmap(bitmap, ©); if (bm.drawsNothing()) { return NULL; } if (SkPDFBitmap* canonBitmap = canon->findBitmap(bm)) { return SkRef(canonBitmap); } if (bm.pixelRef() && bm.pixelRefOrigin().isZero() && bm.dimensions() == bm.pixelRef()->info().dimensions()) { // Requires the bitmap to be backed by lazy pixels. SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); SkJFIFInfo info; if (data && SkIsJFIF(data, &info)) { bool yuv = info.fType == SkJFIFInfo::kYCbCr; SkPDFBitmap* pdfBitmap = new PDFJpegBitmap(bm, data, yuv); canon->addBitmap(pdfBitmap); return pdfBitmap; } } SkPDFObject* smask = NULL; if (!bm.isOpaque() && !SkBitmap::ComputeIsOpaque(bm)) { smask = new PDFAlphaBitmap(bm); } SkPDFBitmap* pdfBitmap = new PDFDefaultBitmap(bm, smask); canon->addBitmap(pdfBitmap); return pdfBitmap; }