15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/image_data.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>  // Needed for memset.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/instance_handle.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module_impl.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace pp {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> const char* interface_name<PPB_ImageData_1_0>() {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PPB_IMAGEDATA_INTERFACE_1_0;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageData::ImageData() : data_(NULL) {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&desc_, 0, sizeof(PP_ImageDataDesc));
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageData::ImageData(const ImageData& other)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Resource(other),
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      desc_(other.desc_),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_(other.data_) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageData::ImageData(PassRef, PP_Resource resource)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Resource(PASS_REF, resource),
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_(NULL) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&desc_, 0, sizeof(PP_ImageDataDesc));
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitData();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageData::ImageData(const InstanceHandle& instance,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     PP_ImageDataFormat format,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const Size& size,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     bool init_to_zero)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : data_(NULL) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&desc_, 0, sizeof(PP_ImageDataDesc));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_ImageData_1_0>())
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PassRefFromConstructor(get_interface<PPB_ImageData_1_0>()->Create(
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance.pp_instance(), format, &size.pp_size(),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PP_FromBool(init_to_zero)));
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitData();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageData& ImageData::operator=(const ImageData& other) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Resource::operator=(other);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  desc_ = other.desc_;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_ = other.data_;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *this;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const uint32_t* ImageData::GetAddr32(const Point& coord) const {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prefer evil const casts rather than evil code duplication.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return const_cast<ImageData*>(this)->GetAddr32(coord);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t* ImageData::GetAddr32(const Point& coord) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we add more image format types that aren't 32-bit, we'd want to check
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // here and fail.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return reinterpret_cast<uint32_t*>(
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &static_cast<char*>(data())[coord.y() * stride() + coord.x() * 4]);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ImageData::IsImageDataFormatSupported(PP_ImageDataFormat format) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_ImageData_1_0>())
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_ToBool(get_interface<PPB_ImageData_1_0>()->
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IsImageDataFormatSupported(format));
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_ImageDataFormat ImageData::GetNativeImageDataFormat() {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_ImageData_1_0>())
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_IMAGEDATAFORMAT_BGRA_PREMUL;  // Default to something on failure.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return get_interface<PPB_ImageData_1_0>()->GetNativeImageDataFormat();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ImageData::InitData() {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_ImageData_1_0>())
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (get_interface<PPB_ImageData_1_0>()->Describe(pp_resource(), &desc_)) {
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    data_ = get_interface<PPB_ImageData_1_0>()->Map(pp_resource());
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (data_)
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  *this = ImageData();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace pp
104