1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2015 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBitmap.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCommandLineFlags.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkData.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkImage.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkStream.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEFINE_bool(header, false, "Print an extra row of the min-max values");
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEFINE_string2(label, l, "label", "Label printed as the first value");
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEFINE_string2(image, i, "", "Input image");
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEFINE_int32_2(row, r, -1, "Row to extract");
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEFINE_int32_2(column, c, -1, "Column to extract");
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEFINE_int32_2(min, n, 0, "Minimum row/column to extract - inclusive");
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEFINE_int32_2(max, m, 100, "Maximum row/column to extract - inclusive");
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEFINE_int32(rgb, 0, "Color channel to print (0->b, 1->g, 2->r, 3->a)");
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEFINE_bool2(quiet, q, false, "Quiet");
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEFINE_bool2(reverse, v, false, "Iterate from max to min");
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This tool just loads a single image and prints out a comma-separated row or column
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Return codes:
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const int kSuccess = 0;
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const int kError = 1;
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotint main(int argc, char** argv) {
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkCommandLineFlags::SetUsage("Print out a row or column of an image.");
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkCommandLineFlags::Parse(argc, argv);
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (FLAGS_rgb > 3 || FLAGS_rgb < 0) {
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!FLAGS_quiet) {
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("Channel (--rgb) must be between 0 and 3 (inclusive) - value is %d.\n",
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                     FLAGS_rgb);
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return kError;
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (FLAGS_row >= 0 && FLAGS_column >= 0) {
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!FLAGS_quiet) {
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("Only one of '-c' or '-r' can be specified at at time.\n");
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return kError;
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (FLAGS_row < 0 && FLAGS_column < 0) {
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!FLAGS_quiet) {
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("At least one of '-c' or '-r' need to be specified.\n");
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return kError;
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkData> data(SkData::MakeFromFileName(FLAGS_image[0]));
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (nullptr == data) {
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!FLAGS_quiet) {
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("Couldn't open file: %s\n", FLAGS_image[0]);
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return kError;
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkImage> image(SkImage::MakeFromEncoded(data));
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!image) {
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!FLAGS_quiet) {
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("Couldn't create image for: %s.\n", FLAGS_image[0]);
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return kError;
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkBitmap bitmap;
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!image->asLegacyBitmap(&bitmap, SkImage::kRW_LegacyBitmapMode)) {
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!FLAGS_quiet) {
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("Couldn't create bitmap for: %s.\n", FLAGS_image[0]);
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return kError;
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int top, bottom, left, right;
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (-1 != FLAGS_row) {
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(-1 == FLAGS_column);
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        top = bottom = SkTPin(FLAGS_row, 0, bitmap.height()-1);
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        FLAGS_min = left = SkTPin(FLAGS_min, 0, bitmap.width()-1);
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        FLAGS_max = right = SkTPin(FLAGS_max, left, bitmap.width()-1);
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(-1 != FLAGS_column);
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        left = right = SkTPin(FLAGS_column, 0, bitmap.width()-1);
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        FLAGS_min = top = SkTPin(FLAGS_min, 0, bitmap.height()-1);
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        FLAGS_max = bottom = SkTPin(FLAGS_max, top, bitmap.height()-1);
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (FLAGS_header) {
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkDebugf("header");
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (FLAGS_reverse) {
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int i = FLAGS_max; i >= FLAGS_min; --i) {
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkDebugf(", %d", i);
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int i = FLAGS_min; i <= FLAGS_max; ++i) {
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkDebugf(", %d", i);
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkDebugf("\n");
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDebugf("%s", FLAGS_label[0]);
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (FLAGS_reverse) {
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int y = bottom; y >= top; --y) {
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int x = right; x >= left; --x) {
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkColor c = bitmap.getColor(x, y);
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkDebugf(", %d", ((c) >> (FLAGS_rgb*8)) & 0xFF);
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int y = top; y <= bottom; ++y) {
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int x = left; x <= right; ++x) {
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkColor c = bitmap.getColor(x, y);
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkDebugf(", %d", ((c) >> (FLAGS_rgb*8)) & 0xFF);
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDebugf("\n");
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return kSuccess;
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
137