1 /* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkTypes.h" 9 10 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 11 12 #include "SkCGUtils.h" 13 #include "SkMalloc.h" 14 #include "SkStream.h" 15 16 // These are used by CGDataProviderCreateWithData 17 18 static void unref_proc(void* info, const void* addr, size_t size) { 19 SkASSERT(info); 20 ((SkRefCnt*)info)->unref(); 21 } 22 23 static void delete_stream_proc(void* info, const void* addr, size_t size) { 24 SkASSERT(info); 25 SkStream* stream = (SkStream*)info; 26 SkASSERT(stream->getMemoryBase() == addr); 27 SkASSERT(stream->getLength() == size); 28 delete stream; 29 } 30 31 // These are used by CGDataProviderSequentialCallbacks 32 33 static size_t get_bytes_proc(void* info, void* buffer, size_t bytes) { 34 SkASSERT(info); 35 return ((SkStream*)info)->read(buffer, bytes); 36 } 37 38 static off_t skip_forward_proc(void* info, off_t bytes) { 39 return ((SkStream*)info)->skip((size_t) bytes); 40 } 41 42 static void rewind_proc(void* info) { 43 SkASSERT(info); 44 ((SkStream*)info)->rewind(); 45 } 46 47 // Used when info is an SkStream. 48 static void release_info_proc(void* info) { 49 SkASSERT(info); 50 delete (SkStream*)info; 51 } 52 53 CGDataProviderRef SkCreateDataProviderFromStream(std::unique_ptr<SkStreamRewindable> stream) { 54 // TODO: Replace with SkStream::getData() when that is added. Then we only 55 // have one version of CGDataProviderCreateWithData (i.e. same release proc) 56 const void* addr = stream->getMemoryBase(); 57 if (addr) { 58 // special-case when the stream is just a block of ram 59 size_t size = stream->getLength(); 60 return CGDataProviderCreateWithData(stream.release(), addr, size, delete_stream_proc); 61 } 62 63 CGDataProviderSequentialCallbacks rec; 64 sk_bzero(&rec, sizeof(rec)); 65 rec.version = 0; 66 rec.getBytes = get_bytes_proc; 67 rec.skipForward = skip_forward_proc; 68 rec.rewind = rewind_proc; 69 rec.releaseInfo = release_info_proc; 70 return CGDataProviderCreateSequential(stream.release(), &rec); 71 } 72 73 /////////////////////////////////////////////////////////////////////////////// 74 75 #include "SkData.h" 76 77 CGDataProviderRef SkCreateDataProviderFromData(sk_sp<SkData> data) { 78 const void* addr = data->data(); 79 size_t size = data->size(); 80 return CGDataProviderCreateWithData(data.release(), addr, size, unref_proc); 81 } 82 83 #endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 84