Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: tests/CodexTest.cpp

Issue 1040453002: Add SkPngChunkReader. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Update SkImageDecoder_empty Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ports/SkImageDecoder_empty.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "Resources.h" 8 #include "Resources.h"
9 #include "SkAndroidCodec.h" 9 #include "SkAndroidCodec.h"
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
11 #include "SkCodec.h" 11 #include "SkCodec.h"
12 #include "SkData.h" 12 #include "SkData.h"
13 #include "SkMD5.h" 13 #include "SkMD5.h"
14 #include "SkRandom.h" 14 #include "SkRandom.h"
15 #include "SkStream.h"
16 #include "SkPngChunkReader.h"
15 #include "Test.h" 17 #include "Test.h"
16 18
19 #include "png.h"
20
17 static SkStreamAsset* resource(const char path[]) { 21 static SkStreamAsset* resource(const char path[]) {
18 SkString fullPath = GetResourcePath(path); 22 SkString fullPath = GetResourcePath(path);
19 return SkStream::NewFromFile(fullPath.c_str()); 23 return SkStream::NewFromFile(fullPath.c_str());
20 } 24 }
21 25
22 static void md5(const SkBitmap& bm, SkMD5::Digest* digest) { 26 static void md5(const SkBitmap& bm, SkMD5::Digest* digest) {
23 SkAutoLockPixels autoLockPixels(bm); 27 SkAutoLockPixels autoLockPixels(bm);
24 SkASSERT(bm.getPixels()); 28 SkASSERT(bm.getPixels());
25 SkMD5 md5; 29 SkMD5 md5;
26 size_t rowLen = bm.info().bytesPerPixel() * bm.width(); 30 size_t rowLen = bm.info().bytesPerPixel() * bm.width();
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); 682 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
679 result = decoder->startScanlineDecode( 683 result = decoder->startScanlineDecode(
680 decoder->getInfo().makeColorType(kIndex_8_SkColorType)); 684 decoder->getInfo().makeColorType(kIndex_8_SkColorType));
681 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); 685 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
682 } 686 }
683 687
684 DEF_TEST(Codec_Params, r) { 688 DEF_TEST(Codec_Params, r) {
685 test_invalid_parameters(r, "index8.png"); 689 test_invalid_parameters(r, "index8.png");
686 test_invalid_parameters(r, "mandrill.wbmp"); 690 test_invalid_parameters(r, "mandrill.wbmp");
687 } 691 }
692
693 static void codex_test_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) {
694 SkWStream* sk_stream = (SkWStream*)png_get_io_ptr(png_ptr);
695 if (!sk_stream->write(data, len)) {
696 png_error(png_ptr, "sk_write_fn Error!");
697 }
698 }
699
700 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
701 DEF_TEST(Codec_pngChunkReader, r) {
702 // Create a dummy bitmap. Use unpremul RGBA for libpng.
703 SkBitmap bm;
704 const int w = 1;
705 const int h = 1;
706 const SkImageInfo bmInfo = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType,
707 kUnpremul_SkAlphaType);
708 bm.setInfo(bmInfo);
709 bm.allocPixels();
710 bm.eraseColor(SK_ColorBLUE);
711 SkMD5::Digest goodDigest;
712 md5(bm, &goodDigest);
713
714 // Write to a png file.
715 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nu llptr, nullptr);
716 REPORTER_ASSERT(r, png);
717 if (!png) {
718 return;
719 }
720
721 png_infop info = png_create_info_struct(png);
722 REPORTER_ASSERT(r, info);
723 if (!info) {
724 png_destroy_write_struct(&png, nullptr);
725 return;
726 }
727
728 if (setjmp(png_jmpbuf(png))) {
729 ERRORF(r, "failed writing png");
730 png_destroy_write_struct(&png, &info);
731 return;
732 }
733
734 SkDynamicMemoryWStream wStream;
735 png_set_write_fn(png, (void*) (&wStream), codex_test_write_fn, nullptr);
736
737 png_set_IHDR(png, info, (png_uint_32)w, (png_uint_32)h, 8,
738 PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
739 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
740
741 // Create some chunks that match the Android framework's use.
742 static png_unknown_chunk gUnknowns[] = {
743 { "npOl", (png_byte*)"outline", sizeof("outline"), PNG_HAVE_PLTE },
744 { "npLb", (png_byte*)"layoutBounds", sizeof("layoutBounds"), PNG_HAVE_PL TE },
745 { "npTc", (png_byte*)"ninePatchData", sizeof("ninePatchData"), PNG_HAVE_ PLTE },
746 };
747
748 png_set_keep_unknown_chunks(png, PNG_HANDLE_CHUNK_ALWAYS, (png_byte*)"npOl\0 npLb\0npTc\0", 3);
749 png_set_unknown_chunks(png, info, gUnknowns, SK_ARRAY_COUNT(gUnknowns));
750 #if PNG_LIBPNG_VER < 10600
751 /* Deal with unknown chunk location bug in 1.5.x and earlier */
752 png_set_unknown_chunk_location(png, info, 0, PNG_HAVE_PLTE);
753 png_set_unknown_chunk_location(png, info, 1, PNG_HAVE_PLTE);
754 #endif
755
756 png_write_info(png, info);
757
758 for (int j = 0; j < h; j++) {
759 png_bytep row = (png_bytep)(bm.getAddr(0, j));
760 png_write_rows(png, &row, 1);
761 }
762 png_write_end(png, info);
763 png_destroy_write_struct(&png, &info);
764
765 class ChunkReader : public SkPngChunkReader {
766 public:
767 ChunkReader(skiatest::Reporter* r)
768 : fReporter(r)
769 {
770 this->reset();
771 }
772
773 bool readChunk(const char tag[], const void* data, size_t length) overri de {
774 for (size_t i = 0; i < SK_ARRAY_COUNT(gUnknowns); ++i) {
775 if (!strcmp(tag, (const char*) gUnknowns[i].name)) {
776 // Tag matches. This should have been the first time we see it.
777 REPORTER_ASSERT(fReporter, !fSeen[i]);
778 fSeen[i] = true;
779
780 // Data and length should match
781 REPORTER_ASSERT(fReporter, length == gUnknowns[i].size);
782 REPORTER_ASSERT(fReporter, !strcmp((const char*) data,
783 (const char*) gUnknowns[i ].data));
784 return true;
785 }
786 }
787 ERRORF(fReporter, "Saw an unexpected unknown chunk.");
788 return true;
789 }
790
791 bool allHaveBeenSeen() {
792 bool ret = true;
793 for (auto seen : fSeen) {
794 ret &= seen;
795 }
796 return ret;
797 }
798
799 void reset() {
800 sk_bzero(fSeen, sizeof(fSeen));
801 }
802
803 private:
804 skiatest::Reporter* fReporter; // Unowned
805 bool fSeen[3];
806 };
807
808 ChunkReader chunkReader(r);
809
810 // Now read the file with SkCodec.
811 SkAutoTUnref<SkData> data(wStream.copyToData());
812 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data, &chunkReader));
813 REPORTER_ASSERT(r, codec);
814 if (!codec) {
815 return;
816 }
817
818 // Now compare to the original.
819 SkBitmap decodedBm;
820 decodedBm.setInfo(codec->getInfo());
821 decodedBm.allocPixels();
822 SkCodec::Result result = codec->getPixels(codec->getInfo(), decodedBm.getPix els(),
823 decodedBm.rowBytes());
824 REPORTER_ASSERT(r, SkCodec::kSuccess == result);
825
826 if (decodedBm.colorType() != bm.colorType()) {
827 SkBitmap tmp;
828 bool success = decodedBm.copyTo(&tmp, bm.colorType());
829 REPORTER_ASSERT(r, success);
830 if (!success) {
831 return;
832 }
833
834 tmp.swap(decodedBm);
835 }
836
837 compare_to_good_digest(r, goodDigest, decodedBm);
838 REPORTER_ASSERT(r, chunkReader.allHaveBeenSeen());
839
840 // Decoding again will read the chunks again.
841 chunkReader.reset();
842 REPORTER_ASSERT(r, !chunkReader.allHaveBeenSeen());
843 result = codec->getPixels(codec->getInfo(), decodedBm.getPixels(), decodedBm .rowBytes());
844 REPORTER_ASSERT(r, SkCodec::kSuccess == result);
845 REPORTER_ASSERT(r, chunkReader.allHaveBeenSeen());
846 }
847 #endif // PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
OLDNEW
« no previous file with comments | « src/ports/SkImageDecoder_empty.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698