17f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett/*
27f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett * Copyright 2015 Google Inc.
37f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett *
47f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett * Use of this source code is governed by a BSD-style license that can be
57f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett * found in the LICENSE file.
67f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett */
77f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett
884a80652752976c9abe42d28e467c362baff3e39msarett#ifndef SkBitmapRegionDecoderPriv_DEFINED
984a80652752976c9abe42d28e467c362baff3e39msarett#define SkBitmapRegionDecoderPriv_DEFINED
107f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett
1126ad17b8f872fc8bc18df7f49067edbd8b9799e8msarettenum SubsetType {
1226ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    kFullyInside_SubsetType,
1326ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    kPartiallyInside_SubsetType,
1426ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    kOutside_SubsetType,
1526ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett};
1626ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett
1726ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett/*
1826ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett * Corrects image subset offsets and dimensions in order to perform a valid decode.
1926ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett * Also indicates if the image subset should be placed at an offset within the
2026ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett * output bitmap.
2126ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett *
2226ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett * Values of output variables are undefined if the SubsetType is kInvalid.
2326ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett *
2426ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett * @param imageDims Original image dimensions.
2526ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett * @param subset    As input, the subset that the client requested.
2626ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett *                  As output, the image subset that we will decode.
2726ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett * @param outX      The left offset of the image subset within the output bitmap.
2826ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett * @param outY      The top offset of the image subset within the output bitmap.
2926ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett *
3026ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett * @return An indication of how the subset is contained in the image.
3126ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett *         If the return value is kInvalid, values of output variables are undefined.
3226ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett */
3326ad17b8f872fc8bc18df7f49067edbd8b9799e8msarettinline SubsetType adjust_subset_rect(const SkISize& imageDims, SkIRect* subset, int* outX,
3426ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett        int* outY) {
3526ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    // These must be at least zero, we can't start decoding the image at a negative coordinate.
3626ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    int left = SkTMax(0, subset->fLeft);
3726ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    int top = SkTMax(0, subset->fTop);
3826ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett
3926ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    // If input offsets are less than zero, we decode to an offset location in the output bitmap.
4026ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    *outX = left - subset->fLeft;
4126ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    *outY = top - subset->fTop;
4226ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett
4326ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    // Make sure we don't decode pixels past the edge of the image or past the edge of the subset.
4426ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    int width = SkTMin(imageDims.width() - left, subset->width() - *outX);
4526ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    int height = SkTMin(imageDims.height() - top, subset->height() - *outY);
4626ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    if (width <= 0 || height <= 0) {
4726ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett        return SubsetType::kOutside_SubsetType;
4826ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    }
4926ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett
5026ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    subset->setXYWH(left, top, width, height);
5126ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    if ((*outX != 0) || (*outY != 0) || (width != subset->width()) ||
5226ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett            (height != subset->height())) {
5326ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett        return SubsetType::kPartiallyInside_SubsetType;
5426ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    }
5526ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett
5626ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett    return SubsetType::kFullyInside_SubsetType;
5726ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett}
5826ad17b8f872fc8bc18df7f49067edbd8b9799e8msarett
5984a80652752976c9abe42d28e467c362baff3e39msarett#endif // SkBitmapRegionDecoderPriv_DEFINED
60