AAPT2: improve some error messages

Test: manual
Change-Id: I11c96f8c825ffd43b7f68cb24f2c0746d75845f5
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 5adf04a..cc1cd5c 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -145,7 +145,7 @@
   const std::string& root_dir = options.res_dir.value();
   std::unique_ptr<DIR, decltype(closedir)*> d(opendir(root_dir.data()), closedir);
   if (!d) {
-    context->GetDiagnostics()->Error(DiagMessage()
+    context->GetDiagnostics()->Error(DiagMessage(root_dir) << "failed to open directory: "
                                      << android::base::SystemErrorCodeToString(errno));
     return false;
   }
@@ -164,7 +164,7 @@
 
     std::unique_ptr<DIR, decltype(closedir)*> subdir(opendir(prefix_path.data()), closedir);
     if (!subdir) {
-      context->GetDiagnostics()->Error(DiagMessage()
+      context->GetDiagnostics()->Error(DiagMessage(prefix_path) << "failed to open directory: "
                                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
@@ -180,7 +180,7 @@
       std::string err_str;
       Maybe<ResourcePathData> path_data = ExtractResourcePathData(full_path, &err_str);
       if (!path_data) {
-        context->GetDiagnostics()->Error(DiagMessage() << err_str);
+        context->GetDiagnostics()->Error(DiagMessage(full_path) << err_str);
         return false;
       }
 
@@ -198,6 +198,7 @@
     std::ifstream fin(path_data.source.path, std::ifstream::binary);
     if (!fin) {
       context->GetDiagnostics()->Error(DiagMessage(path_data.source)
+                                       << "failed to open file: "
                                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
@@ -395,6 +396,7 @@
     std::ifstream fin(path_data.source.path, std::ifstream::binary);
     if (!fin) {
       context->GetDiagnostics()->Error(DiagMessage(path_data.source)
+                                       << "failed to open file: "
                                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
@@ -480,6 +482,7 @@
     std::string content;
     if (!android::base::ReadFileToString(path_data.source.path, &content)) {
       context->GetDiagnostics()->Error(DiagMessage(path_data.source)
+                                       << "failed to open file: "
                                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
diff --git a/tools/aapt2/compile/PngChunkFilter.cpp b/tools/aapt2/compile/PngChunkFilter.cpp
index 7073c13..5af91fd 100644
--- a/tools/aapt2/compile/PngChunkFilter.cpp
+++ b/tools/aapt2/compile/PngChunkFilter.cpp
@@ -75,7 +75,7 @@
     window_start_ = 0;
     window_end_ = kPngSignatureSize;
   } else {
-    error_msg_ = "PNG does not start with PNG signature";
+    error_msg_ = "file does not start with PNG signature";
   }
 }
 
diff --git a/tools/aapt2/compile/PngCrunch.cpp b/tools/aapt2/compile/PngCrunch.cpp
index 42443d8..0346a19 100644
--- a/tools/aapt2/compile/PngCrunch.cpp
+++ b/tools/aapt2/compile/PngCrunch.cpp
@@ -142,19 +142,24 @@
 }
 
 std::unique_ptr<Image> ReadPng(IAaptContext* context, const Source& source, io::InputStream* in) {
+  // Create a diagnostics that has the source information encoded.
+  SourcePathDiagnostics source_diag(source, context->GetDiagnostics());
+
   // Read the first 8 bytes of the file looking for the PNG signature.
   // Bail early if it does not match.
   const png_byte* signature;
   size_t buffer_size;
   if (!in->Next((const void**)&signature, &buffer_size)) {
-    context->GetDiagnostics()->Error(DiagMessage()
-                                     << android::base::SystemErrorCodeToString(errno));
+    if (in->HadError()) {
+      source_diag.Error(DiagMessage() << "failed to read PNG signature: " << in->GetError());
+    } else {
+      source_diag.Error(DiagMessage() << "not enough data for PNG signature");
+    }
     return {};
   }
 
   if (buffer_size < kPngSignatureSize || png_sig_cmp(signature, 0, kPngSignatureSize) != 0) {
-    context->GetDiagnostics()->Error(DiagMessage()
-                                     << "file signature does not match PNG signature");
+    source_diag.Error(DiagMessage() << "file signature does not match PNG signature");
     return {};
   }
 
@@ -166,21 +171,18 @@
   // version of libpng.
   png_structp read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
   if (read_ptr == nullptr) {
-    context->GetDiagnostics()->Error(DiagMessage() << "failed to create libpng read png_struct");
+    source_diag.Error(DiagMessage() << "failed to create libpng read png_struct");
     return {};
   }
 
   // Create and initialize the memory for image header and data.
   png_infop info_ptr = png_create_info_struct(read_ptr);
   if (info_ptr == nullptr) {
-    context->GetDiagnostics()->Error(DiagMessage() << "failed to create libpng read png_info");
+    source_diag.Error(DiagMessage() << "failed to create libpng read png_info");
     png_destroy_read_struct(&read_ptr, nullptr, nullptr);
     return {};
   }
 
-  // Create a diagnostics that has the source information encoded.
-  SourcePathDiagnostics source_diag(source, context->GetDiagnostics());
-
   // Automatically release PNG resources at end of scope.
   PngReadStructDeleter png_read_deleter(read_ptr, info_ptr);