Beispiel #1
0
s32 b2r2_get_img_size(struct b2r2_blt_img *img)
{
    if (b2r2_is_single_plane_fmt(img->fmt)) {
        return (s32)b2r2_get_img_pitch(img) * img->height;
    } else if (b2r2_is_ycbcrsp_fmt(img->fmt) ||
               b2r2_is_ycbcrp_fmt(img->fmt)) {
        s32 y_plane_size;

        y_plane_size = (s32)b2r2_get_img_pitch(img) * img->height;

        if (b2r2_is_ycbcr420_fmt(img->fmt)) {
            return y_plane_size + y_plane_size / 2;
        } else if (b2r2_is_ycbcr422_fmt(img->fmt)) {
            return y_plane_size * 2;
        } else if (b2r2_is_ycbcr444_fmt(img->fmt)) {
            return y_plane_size * 3;
        } else {
            b2r2_log_err("%s: Internal error! "
                         "Format %#x not recognized.\n",
                         __func__, img->fmt);
            return 0;
        }
    } else if (b2r2_is_mb_fmt(img->fmt)) {
        return (img->width * img->height *
                b2r2_get_fmt_bpp(img->fmt)) / 8;
    } else {
        b2r2_log_err("%s: Internal error! "
                     "Format %#x not recognized.\n",
                     __func__, img->fmt);
        return 0;
    }
}
static bool validate_img(struct device *dev,
		struct b2r2_blt_img *img)
{
	/*
	 * So that we always can do width * height * bpp without overflowing a
	 * 32 bit signed integer. isqrt(s32_max / max_bpp) was used to
	 * calculate the value.
	 */
	static const s32 max_img_width_height = 8191;

	s32 img_size;

	if (!is_valid_format(img->fmt)) {
		b2r2_log_info(dev, "Validation Error: "
				"!is_valid_format(img->fmt)\n");
		return false;
	}

	if (img->width < 0 || img->width > max_img_width_height ||
		img->height < 0 || img->height > max_img_width_height) {
		b2r2_log_info(dev, "Validation Error: "
				"img->width < 0 || "
				"img->width > max_img_width_height || "
				"img->height < 0 || "
				"img->height > max_img_width_height\n");
		return false;
	}

	if (b2r2_is_mb_fmt(img->fmt)) {
		if (!is_complete_width_for_fmt(img->width, img->fmt)) {
			b2r2_log_info(dev, "Validation Error: "
					"!is_complete_width_for_fmt(img->width,"
					" img->fmt)\n");
			return false;
		}
	} else {
		if (0 == img->pitch &&
			(!is_aligned_width_for_fmt(img->width, img->fmt) ||
			!is_complete_width_for_fmt(img->width, img->fmt))) {
			b2r2_log_info(dev,
					"Validation Error: "
					"0 == img->pitch && "
					"(!is_aligned_width_for_fmt(img->width,"
					" img->fmt) || "
					"!is_complete_width_for_fmt(img->width,"
					" img->fmt))\n");
			return false;
		}

		if (img->pitch != 0 &&
			!is_valid_pitch_for_fmt(dev, img->pitch, img->width,
				img->fmt)) {
			b2r2_log_info(dev,
				"Validation Error: "
				"img->pitch != 0 && "
				"!is_valid_pitch_for_fmt(dev, "
				"img->pitch, img->width, img->fmt)\n");
			return false;
		}
	}

	if (!is_valid_height_for_fmt(img->width, img->fmt)) {
		b2r2_log_info(dev, "Validation Error: "
				"!is_valid_height_for_fmt(img->width, img->fmt)\n");
		return false;
	}

	img_size = b2r2_get_img_size(dev, img);

	/*
	 * To keep the entire image inside s32 range.
	 */
	if ((B2R2_BLT_PTR_HWMEM_BUF_NAME_OFFSET == img->buf.type ||
				B2R2_BLT_PTR_FD_OFFSET == img->buf.type) &&
			img->buf.offset > (u32)b2r2_s32_max - (u32)img_size) {
		b2r2_log_info(dev, "Validation Error: "
				"(B2R2_BLT_PTR_HWMEM_BUF_NAME_OFFSET == "
				"img->buf.type || B2R2_BLT_PTR_FD_OFFSET == "
				"img->buf.type) && img->buf.offset > "
				"(u32)B2R2_MAX_S32 - (u32)img_size\n");
		return false;
	}

	return true;
}