Wrap SkStreams in IStreams instead of copying data around.
http://codereview.appspot.com/4630062/ git-svn-id: http://skia.googlecode.com/svn/trunk@1694 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
8fd48b8bd8
commit
9df621da50
@ -6,6 +6,9 @@
|
|||||||
{
|
{
|
||||||
'target_name': 'images',
|
'target_name': 'images',
|
||||||
'type': 'static_library',
|
'type': 'static_library',
|
||||||
|
'dependencies': [
|
||||||
|
'utils.gyp:utils',
|
||||||
|
],
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
'../include/config',
|
'../include/config',
|
||||||
'../include/core',
|
'../include/core',
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
'../include/utils',
|
'../include/utils',
|
||||||
'../include/utils/mac',
|
'../include/utils/mac',
|
||||||
'../include/utils/unix',
|
'../include/utils/unix',
|
||||||
|
'../include/utils/win',
|
||||||
'../include/views',
|
'../include/views',
|
||||||
'../include/effects',
|
'../include/effects',
|
||||||
'../include/xml',
|
'../include/xml',
|
||||||
@ -59,22 +60,32 @@
|
|||||||
'../src/utils/SkSfntUtils.cpp',
|
'../src/utils/SkSfntUtils.cpp',
|
||||||
'../src/utils/SkUnitMappers.cpp',
|
'../src/utils/SkUnitMappers.cpp',
|
||||||
|
|
||||||
|
#mac
|
||||||
'../include/utils/mac/SkCGUtils.h',
|
'../include/utils/mac/SkCGUtils.h',
|
||||||
'../src/utils/mac/SkCreateCGImageRef.cpp',
|
'../src/utils/mac/SkCreateCGImageRef.cpp',
|
||||||
'../src/utils/mac/SkEGLContext_mac.cpp',
|
'../src/utils/mac/SkEGLContext_mac.cpp',
|
||||||
'../src/utils/mac/skia_mac.cpp',
|
'../src/utils/mac/skia_mac.cpp',
|
||||||
'../src/utils/mac/SkOSWindow_Mac.cpp',
|
'../src/utils/mac/SkOSWindow_Mac.cpp',
|
||||||
|
|
||||||
|
#mesa
|
||||||
'../src/utils/mesa/SkEGLContext_Mesa.cpp',
|
'../src/utils/mesa/SkEGLContext_Mesa.cpp',
|
||||||
|
|
||||||
|
#sdl
|
||||||
'../src/utils/SDL/SkOSWindow_SDL.cpp',
|
'../src/utils/SDL/SkOSWindow_SDL.cpp',
|
||||||
|
|
||||||
|
#*nix
|
||||||
'../src/utils/unix/keysym2ucs.c',
|
'../src/utils/unix/keysym2ucs.c',
|
||||||
'../src/utils/unix/SkEGLContext_Unix.cpp',
|
'../src/utils/unix/SkEGLContext_Unix.cpp',
|
||||||
'../src/utils/unix/SkOSWindow_Unix.cpp',
|
'../src/utils/unix/SkOSWindow_Unix.cpp',
|
||||||
|
|
||||||
|
#windows
|
||||||
|
'../include/utils/win/SkAutoCoInitialize.h',
|
||||||
|
'../include/utils/win/SkIStream.h',
|
||||||
|
'../include/utils/win/SkTScopedComPtr.h',
|
||||||
|
'../src/utils/win/SkAutoCoInitialize.cpp',
|
||||||
'../src/utils/win/skia_win.cpp',
|
'../src/utils/win/skia_win.cpp',
|
||||||
'../src/utils/win/SkEGLContext_Win.cpp',
|
'../src/utils/win/SkEGLContext_Win.cpp',
|
||||||
|
'../src/utils/win/SkIStream.cpp',
|
||||||
'../src/utils/win/SkOSWindow_Win.cpp',
|
'../src/utils/win/SkOSWindow_Win.cpp',
|
||||||
],
|
],
|
||||||
'sources!': [
|
'sources!': [
|
||||||
@ -82,18 +93,6 @@
|
|||||||
'../src/utils/SDL/SkOSWindow_SDL.cpp',
|
'../src/utils/SDL/SkOSWindow_SDL.cpp',
|
||||||
],
|
],
|
||||||
'conditions': [
|
'conditions': [
|
||||||
[ 'OS != "mac"', {
|
|
||||||
'sources!': [
|
|
||||||
'../include/utils/mac/SkCGUtils.h',
|
|
||||||
'../src/utils/mac/SkCreateCGImageRef.cpp',
|
|
||||||
'../src/utils/mac/SkEGLContext_mac.cpp',
|
|
||||||
'../src/utils/mac/skia_mac.cpp',
|
|
||||||
'../src/utils/mac/SkOSWindow_Mac.cpp',
|
|
||||||
],
|
|
||||||
'include_dirs!': [
|
|
||||||
'../include/utils/mac',
|
|
||||||
],
|
|
||||||
}],
|
|
||||||
[ 'OS == "mac"', {
|
[ 'OS == "mac"', {
|
||||||
'sources!': [
|
'sources!': [
|
||||||
'../src/utils/SkEGLContext_none.cpp',
|
'../src/utils/SkEGLContext_none.cpp',
|
||||||
@ -103,18 +102,19 @@
|
|||||||
'$(SDKROOT)/System/Library/Frameworks/AGL.framework',
|
'$(SDKROOT)/System/Library/Frameworks/AGL.framework',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
}],
|
},{ #else if 'OS != "mac"'
|
||||||
[ 'OS != "linux" and OS != "freebsd" and OS != "openbsd" and OS != "solaris"', {
|
|
||||||
'sources!': [
|
|
||||||
'../src/utils/unix/keysym2ucs.c',
|
|
||||||
'../src/utils/unix/SkEGLContext_Unix.cpp',
|
|
||||||
'../src/utils/unix/SkOSWindow_Unix.cpp',
|
|
||||||
],
|
|
||||||
'include_dirs!': [
|
'include_dirs!': [
|
||||||
'../include/utils/unix',
|
'../include/utils/mac',
|
||||||
|
],
|
||||||
|
'sources!': [
|
||||||
|
'../include/utils/mac/SkCGUtils.h',
|
||||||
|
'../src/utils/mac/SkCreateCGImageRef.cpp',
|
||||||
|
'../src/utils/mac/SkEGLContext_mac.cpp',
|
||||||
|
'../src/utils/mac/skia_mac.cpp',
|
||||||
|
'../src/utils/mac/SkOSWindow_Mac.cpp',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
[ 'OS == "linux" or OS == "freebsd" or OS == "openbsd" or OS == "solaris"', {
|
[ 'OS in ["linux", "freebsd", "openbsd", "solaris"]', {
|
||||||
'sources!': [
|
'sources!': [
|
||||||
'../src/utils/SkEGLContext_none.cpp',
|
'../src/utils/SkEGLContext_none.cpp',
|
||||||
],
|
],
|
||||||
@ -124,18 +124,39 @@
|
|||||||
'-lGLU',
|
'-lGLU',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
}],
|
},{ #else if 'OS not in ["linux", "freebsd", "openbsd", "solaris"]'
|
||||||
[ 'OS != "win"', {
|
'include_dirs!': [
|
||||||
|
'../include/utils/unix',
|
||||||
|
],
|
||||||
'sources!': [
|
'sources!': [
|
||||||
'../src/utils/win/skia_win.cpp',
|
'../src/utils/unix/keysym2ucs.c',
|
||||||
'../src/utils/win/SkEGLContext_Win.cpp',
|
'../src/utils/unix/SkEGLContext_Unix.cpp',
|
||||||
'../src/utils/win/SkOSWindow_Win.cpp',
|
'../src/utils/unix/SkOSWindow_Unix.cpp',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
[ 'OS == "win"', {
|
[ 'OS == "win"', {
|
||||||
'sources!': [
|
'sources!': [
|
||||||
'../src/utils/SkEGLContext_none.cpp',
|
'../src/utils/SkEGLContext_none.cpp',
|
||||||
],
|
],
|
||||||
|
'direct_dependent_settings': {
|
||||||
|
'include_dirs': [
|
||||||
|
'../include/utils/win',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},{ #else if 'OS != "win"'
|
||||||
|
'include_dirs!': [
|
||||||
|
'../include/utils/win',
|
||||||
|
],
|
||||||
|
'sources!': [
|
||||||
|
'../include/utils/win/SkAutoCoInitialize.h',
|
||||||
|
'../include/utils/win/SkIStream.h',
|
||||||
|
'../include/utils/win/SkTScopedComPtr.h',
|
||||||
|
'../src/utils/win/SkAutoCoInitialize.cpp',
|
||||||
|
'../src/utils/win/skia_win.cpp',
|
||||||
|
'../src/utils/win/SkEGLContext_Win.cpp',
|
||||||
|
'../src/utils/win/SkIStream.cpp',
|
||||||
|
'../src/utils/win/SkOSWindow_Win.cpp',
|
||||||
|
],
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
'direct_dependent_settings': {
|
'direct_dependent_settings': {
|
||||||
|
37
include/utils/win/SkAutoCoInitialize.h
Normal file
37
include/utils/win/SkAutoCoInitialize.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2011 Google Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SkAutoCo_DEFINED
|
||||||
|
#define SkAutoCo_DEFINED
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
#include "SkTemplates.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An instance of this class initializes COM on creation
|
||||||
|
* and closes the COM library on destruction.
|
||||||
|
*/
|
||||||
|
class AutoCoInitialize : SkNoncopyable {
|
||||||
|
private:
|
||||||
|
HRESULT fHR;
|
||||||
|
public:
|
||||||
|
AutoCoInitialize();
|
||||||
|
~AutoCoInitialize();
|
||||||
|
HRESULT getHR();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
135
include/utils/win/SkIStream.h
Normal file
135
include/utils/win/SkIStream.h
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2011 Google Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SkIStream_DEFINED
|
||||||
|
#define SkIStream_DEFINED
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <ole2.h>
|
||||||
|
|
||||||
|
class SkStream;
|
||||||
|
class SkWStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bare IStream implementation which properly reference counts
|
||||||
|
* but returns E_NOTIMPL for all ISequentialStream and IStream methods.
|
||||||
|
*/
|
||||||
|
class SkBaseIStream : public IStream {
|
||||||
|
private:
|
||||||
|
LONG _refcount;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit SkBaseIStream();
|
||||||
|
virtual ~SkBaseIStream();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid
|
||||||
|
, void ** ppvObject);
|
||||||
|
virtual ULONG STDMETHODCALLTYPE AddRef(void);
|
||||||
|
virtual ULONG STDMETHODCALLTYPE Release(void);
|
||||||
|
|
||||||
|
// ISequentialStream Interface
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Read(void* pv, ULONG cb, ULONG* pcbRead);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Write(void const* pv
|
||||||
|
, ULONG cb
|
||||||
|
, ULONG* pcbWritten);
|
||||||
|
|
||||||
|
// IStream Interface
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream*
|
||||||
|
, ULARGE_INTEGER
|
||||||
|
, ULARGE_INTEGER*
|
||||||
|
, ULARGE_INTEGER*);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Commit(DWORD);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Revert(void);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER
|
||||||
|
, ULARGE_INTEGER
|
||||||
|
, DWORD);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER
|
||||||
|
, ULARGE_INTEGER
|
||||||
|
, DWORD);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Clone(IStream **);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove
|
||||||
|
, DWORD dwOrigin
|
||||||
|
, ULARGE_INTEGER* lpNewFilePointer);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg
|
||||||
|
, DWORD grfStatFlag);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A minimal read-only IStream implementation which wraps an SkIStream.
|
||||||
|
*/
|
||||||
|
class SkIStream : public SkBaseIStream {
|
||||||
|
private:
|
||||||
|
SkStream *fSkStream;
|
||||||
|
bool fUnrefOnRelease;
|
||||||
|
|
||||||
|
SkIStream(SkStream* stream, bool unrefOnRelease);
|
||||||
|
virtual ~SkIStream();
|
||||||
|
|
||||||
|
public:
|
||||||
|
HRESULT static CreateFromSkStream(SkStream* stream
|
||||||
|
, bool unrefOnRelease
|
||||||
|
, IStream ** ppStream);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Read(void* pv, ULONG cb, ULONG* pcbRead);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Write(void const* pv
|
||||||
|
, ULONG cb
|
||||||
|
, ULONG* pcbWritten);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove
|
||||||
|
, DWORD dwOrigin
|
||||||
|
, ULARGE_INTEGER* lpNewFilePointer);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg
|
||||||
|
, DWORD grfStatFlag);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A minimal write-only IStream implementation which wraps an SkWIStream.
|
||||||
|
*/
|
||||||
|
class SkWIStream : public SkBaseIStream {
|
||||||
|
private:
|
||||||
|
SkWStream *fSkWStream;
|
||||||
|
|
||||||
|
SkWIStream(SkWStream* stream);
|
||||||
|
virtual ~SkWIStream();
|
||||||
|
|
||||||
|
public:
|
||||||
|
HRESULT static CreateFromSkWStream(SkWStream* stream, IStream ** ppStream);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Write(void const* pv
|
||||||
|
, ULONG cb
|
||||||
|
, ULONG* pcbWritten);
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg
|
||||||
|
, DWORD grfStatFlag);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
47
include/utils/win/SkTScopedComPtr.h
Normal file
47
include/utils/win/SkTScopedComPtr.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2011 Google Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SkSkTScopedPtr_DEFINED
|
||||||
|
#define SkSkTScopedPtr_DEFINED
|
||||||
|
|
||||||
|
#include "SkTemplates.h"
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class SkTScopedComPtr : SkNoncopyable {
|
||||||
|
private:
|
||||||
|
T *fPtr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SkTScopedComPtr(T *ptr = NULL) : fPtr(ptr) { }
|
||||||
|
~SkTScopedComPtr() {
|
||||||
|
if (NULL != fPtr) {
|
||||||
|
fPtr->Release();
|
||||||
|
fPtr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
T &operator*() const { return *fPtr; }
|
||||||
|
T *operator->() const { return fPtr; }
|
||||||
|
/**
|
||||||
|
* Returns the address of the underlying pointer.
|
||||||
|
* This is dangerous -- it breaks encapsulation and the reference escapes.
|
||||||
|
* Must only be used on instances currently pointing to NULL,
|
||||||
|
* and only to initialize the instance.
|
||||||
|
*/
|
||||||
|
T **operator&() { SkASSERT(fPtr == NULL); return &fPtr; }
|
||||||
|
T *get() const { return fPtr; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Google Inc.
|
Copyright 2011 Google Inc.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -17,137 +17,26 @@
|
|||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <wincodec.h>
|
#include <wincodec.h>
|
||||||
|
#include "SkAutoCoInitialize.h"
|
||||||
#include "SkImageDecoder.h"
|
#include "SkImageDecoder.h"
|
||||||
#include "SkImageEncoder.h"
|
#include "SkImageEncoder.h"
|
||||||
|
#include "SkIStream.h"
|
||||||
#include "SkMovie.h"
|
#include "SkMovie.h"
|
||||||
#include "SkStream.h"
|
#include "SkStream.h"
|
||||||
#include "SkTemplates.h"
|
#include "SkTScopedComPtr.h"
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class scoped_com_ptr {
|
|
||||||
private:
|
|
||||||
T *fPtr;
|
|
||||||
|
|
||||||
scoped_com_ptr(scoped_com_ptr const &);
|
|
||||||
scoped_com_ptr & operator=(scoped_com_ptr const &);
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit scoped_com_ptr(T *ptr = NULL) : fPtr(ptr) { }
|
|
||||||
~scoped_com_ptr() {
|
|
||||||
if (NULL != fPtr) {
|
|
||||||
fPtr->Release();
|
|
||||||
fPtr = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
T &operator*() const { return *fPtr; }
|
|
||||||
T *operator->() const { return fPtr; }
|
|
||||||
/**
|
|
||||||
* Returns the address of the underlying pointer.
|
|
||||||
* This is dangerous -- it breaks encapsulation and the reference escapes.
|
|
||||||
* Must only be used on instances currently pointing to NULL,
|
|
||||||
* and only to initialize the instance.
|
|
||||||
*/
|
|
||||||
T **operator&() { SkASSERT(fPtr == NULL); return &fPtr; }
|
|
||||||
T *get() const { return fPtr; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An instance of this class initializes COM on creation
|
|
||||||
* and closes the COM library on destruction.
|
|
||||||
*/
|
|
||||||
class AutoCoInitialize : SkNoncopyable {
|
|
||||||
private:
|
|
||||||
HRESULT hr;
|
|
||||||
public:
|
|
||||||
AutoCoInitialize() :
|
|
||||||
hr(
|
|
||||||
CoInitializeEx(
|
|
||||||
NULL
|
|
||||||
, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{ }
|
|
||||||
~AutoCoInitialize() {
|
|
||||||
if (SUCCEEDED(this->hr)) {
|
|
||||||
CoUninitialize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HRESULT getHR() { return this->hr; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class SkImageDecoder_WIC : public SkImageDecoder {
|
class SkImageDecoder_WIC : public SkImageDecoder {
|
||||||
protected:
|
protected:
|
||||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
|
virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a SkStream to an IStream.
|
|
||||||
* The caller must call Release() on the returned IStream.
|
|
||||||
*/
|
|
||||||
static HRESULT SkStreamToIStream(SkStream* stream, IStream** ppStream) {
|
|
||||||
//TODO(bungeman): use a real IStream wrapper
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
|
|
||||||
size_t len = stream->getLength();
|
|
||||||
|
|
||||||
//Reserve memory for content of IStream.
|
|
||||||
HGLOBAL hdata = NULL;
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
hdata = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, len);
|
|
||||||
if (NULL == hdata) {
|
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Lock memory.
|
|
||||||
void* data = NULL;
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
data = GlobalLock(hdata);
|
|
||||||
if (NULL == data) {
|
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Write SkStream data to memory.
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
size_t read = stream->read(data, len);
|
|
||||||
if (read != len) {
|
|
||||||
hr = E_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Unlock memory.
|
|
||||||
if (NULL != data) {
|
|
||||||
data = NULL;
|
|
||||||
SetLastError(NO_ERROR);
|
|
||||||
GlobalUnlock(hdata);
|
|
||||||
DWORD lastError = GetLastError();
|
|
||||||
if (SUCCEEDED(hr) && NO_ERROR != lastError) {
|
|
||||||
hr = HRESULT_FROM_WIN32(lastError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Create IStream from memory.
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
hr = CreateStreamOnHGlobal(hdata, TRUE, ppStream);
|
|
||||||
}
|
|
||||||
//If we failed for any reason, free the memory.
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
if (NULL != hdata) {
|
|
||||||
GlobalFree(hdata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
||||||
//Initialize COM.
|
//Initialize COM.
|
||||||
AutoCoInitialize scopedCo;
|
AutoCoInitialize scopedCo;
|
||||||
HRESULT hr = scopedCo.getHR();
|
HRESULT hr = scopedCo.getHR();
|
||||||
|
|
||||||
//Create Windows Imaging Component ImagingFactory.
|
//Create Windows Imaging Component ImagingFactory.
|
||||||
scoped_com_ptr<IWICImagingFactory> piImagingFactory;
|
SkTScopedComPtr<IWICImagingFactory> piImagingFactory;
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = CoCreateInstance(
|
hr = CoCreateInstance(
|
||||||
CLSID_WICImagingFactory
|
CLSID_WICImagingFactory
|
||||||
@ -158,9 +47,9 @@ bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Convert SkStream to IStream.
|
//Convert SkStream to IStream.
|
||||||
scoped_com_ptr<IStream> piStream;
|
SkTScopedComPtr<IStream> piStream;
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = SkStreamToIStream(stream, &piStream);
|
hr = SkIStream::CreateFromSkStream(stream, false, &piStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Make sure we're at the beginning of the stream.
|
//Make sure we're at the beginning of the stream.
|
||||||
@ -170,7 +59,7 @@ bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Create the decoder from the stream content.
|
//Create the decoder from the stream content.
|
||||||
scoped_com_ptr<IWICBitmapDecoder> piBitmapDecoder;
|
SkTScopedComPtr<IWICBitmapDecoder> piBitmapDecoder;
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = piImagingFactory->CreateDecoderFromStream(
|
hr = piImagingFactory->CreateDecoderFromStream(
|
||||||
piStream.get() //Image to be decoded
|
piStream.get() //Image to be decoded
|
||||||
@ -181,13 +70,13 @@ bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Get the first frame from the decoder.
|
//Get the first frame from the decoder.
|
||||||
scoped_com_ptr<IWICBitmapFrameDecode> piBitmapFrameDecode;
|
SkTScopedComPtr<IWICBitmapFrameDecode> piBitmapFrameDecode;
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = piBitmapDecoder->GetFrame(0, &piBitmapFrameDecode);
|
hr = piBitmapDecoder->GetFrame(0, &piBitmapFrameDecode);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get the BitmapSource interface of the frame.
|
//Get the BitmapSource interface of the frame.
|
||||||
scoped_com_ptr<IWICBitmapSource> piBitmapSourceOriginal;
|
SkTScopedComPtr<IWICBitmapSource> piBitmapSourceOriginal;
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = piBitmapFrameDecode->QueryInterface(
|
hr = piBitmapFrameDecode->QueryInterface(
|
||||||
IID_PPV_ARGS(&piBitmapSourceOriginal)
|
IID_PPV_ARGS(&piBitmapSourceOriginal)
|
||||||
@ -213,7 +102,7 @@ bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Create a format converter.
|
//Create a format converter.
|
||||||
scoped_com_ptr<IWICFormatConverter> piFormatConverter;
|
SkTScopedComPtr<IWICFormatConverter> piFormatConverter;
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = piImagingFactory->CreateFormatConverter(&piFormatConverter);
|
hr = piImagingFactory->CreateFormatConverter(&piFormatConverter);
|
||||||
}
|
}
|
||||||
@ -230,7 +119,7 @@ bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Get the BitmapSource interface of the format converter.
|
//Get the BitmapSource interface of the format converter.
|
||||||
scoped_com_ptr<IWICBitmapSource> piBitmapSourceConverted;
|
SkTScopedComPtr<IWICBitmapSource> piBitmapSourceConverted;
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = piFormatConverter->QueryInterface(
|
hr = piFormatConverter->QueryInterface(
|
||||||
IID_PPV_ARGS(&piBitmapSourceConverted)
|
IID_PPV_ARGS(&piBitmapSourceConverted)
|
||||||
@ -300,7 +189,7 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream
|
|||||||
HRESULT hr = scopedCo.getHR();
|
HRESULT hr = scopedCo.getHR();
|
||||||
|
|
||||||
//Create Windows Imaging Component ImagingFactory.
|
//Create Windows Imaging Component ImagingFactory.
|
||||||
scoped_com_ptr<IWICImagingFactory> piImagingFactory;
|
SkTScopedComPtr<IWICImagingFactory> piImagingFactory;
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = CoCreateInstance(
|
hr = CoCreateInstance(
|
||||||
CLSID_WICImagingFactory
|
CLSID_WICImagingFactory
|
||||||
@ -310,14 +199,14 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create the stream to hold the output of the encoder.
|
//Convert the SkWStream to an IStream.
|
||||||
scoped_com_ptr<IStream> piStream;
|
SkTScopedComPtr<IStream> piStream;
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &piStream);
|
hr = SkWIStream::CreateFromSkWStream(stream, &piStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create an encode of the appropriate type.
|
//Create an encode of the appropriate type.
|
||||||
scoped_com_ptr<IWICBitmapEncoder> piEncoder;
|
SkTScopedComPtr<IWICBitmapEncoder> piEncoder;
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = piImagingFactory->CreateEncoder(type, NULL, &piEncoder);
|
hr = piImagingFactory->CreateEncoder(type, NULL, &piEncoder);
|
||||||
}
|
}
|
||||||
@ -327,8 +216,8 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Create a the frame.
|
//Create a the frame.
|
||||||
scoped_com_ptr<IWICBitmapFrameEncode> piBitmapFrameEncode;
|
SkTScopedComPtr<IWICBitmapFrameEncode> piBitmapFrameEncode;
|
||||||
scoped_com_ptr<IPropertyBag2> piPropertybag;
|
SkTScopedComPtr<IPropertyBag2> piPropertybag;
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = piEncoder->CreateNewFrame(&piBitmapFrameEncode, &piPropertybag);
|
hr = piEncoder->CreateNewFrame(&piBitmapFrameEncode, &piPropertybag);
|
||||||
}
|
}
|
||||||
@ -389,36 +278,6 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream
|
|||||||
hr = piEncoder->Commit();
|
hr = piEncoder->Commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Rewind the IStream with the output of the encoder.
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
LARGE_INTEGER liBeginning = { 0 };
|
|
||||||
hr = piStream->Seek(liBeginning, STREAM_SEEK_SET, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Write the content of the IStream to the SkWStream.
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
//TODO(bungeman): use a real IStream(SkWStream) wrapper
|
|
||||||
const unsigned int BUFFER_SIZE = 1024;
|
|
||||||
void* buffer = new BYTE[BUFFER_SIZE];
|
|
||||||
ULONG bytesRead = 0;
|
|
||||||
while (true) {
|
|
||||||
hr = piStream->Read(buffer, BUFFER_SIZE, &bytesRead);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bool wrote = stream->write(buffer, bytesRead);
|
|
||||||
if (!wrote) {
|
|
||||||
hr = E_FAIL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (BUFFER_SIZE != bytesRead) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stream->flush();
|
|
||||||
delete[] buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCEEDED(hr);
|
return SUCCEEDED(hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
src/utils/win/SkAutoCoInitialize.cpp
Normal file
34
src/utils/win/SkAutoCoInitialize.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2011 Google Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <ole2.h>
|
||||||
|
#include "SkAutoCoInitialize.h"
|
||||||
|
|
||||||
|
AutoCoInitialize::AutoCoInitialize() :
|
||||||
|
fHR(
|
||||||
|
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)
|
||||||
|
)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
AutoCoInitialize::~AutoCoInitialize() {
|
||||||
|
if (SUCCEEDED(this->fHR)) {
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT AutoCoInitialize::getHR() { return this->fHR; }
|
263
src/utils/win/SkIStream.cpp
Normal file
263
src/utils/win/SkIStream.cpp
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2011 Google Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <ole2.h>
|
||||||
|
#include "SkIStream.h"
|
||||||
|
#include "SkStream.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SkBaseIStream
|
||||||
|
*/
|
||||||
|
SkBaseIStream::SkBaseIStream() : _refcount(1) { }
|
||||||
|
SkBaseIStream::~SkBaseIStream() { }
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SkBaseIStream::QueryInterface(REFIID iid
|
||||||
|
, void ** ppvObject)
|
||||||
|
{
|
||||||
|
if (NULL == ppvObject) {
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
if (iid == __uuidof(IUnknown)
|
||||||
|
|| iid == __uuidof(IStream)
|
||||||
|
|| iid == __uuidof(ISequentialStream))
|
||||||
|
{
|
||||||
|
*ppvObject = static_cast<IStream*>(this);
|
||||||
|
AddRef();
|
||||||
|
return S_OK;
|
||||||
|
} else {
|
||||||
|
*ppvObject = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE SkBaseIStream::AddRef(void) {
|
||||||
|
return (ULONG)InterlockedIncrement(&_refcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE SkBaseIStream::Release(void) {
|
||||||
|
ULONG res = (ULONG) InterlockedDecrement(&_refcount);
|
||||||
|
if (0 == res) {
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ISequentialStream Interface
|
||||||
|
HRESULT STDMETHODCALLTYPE SkBaseIStream::Read(void* pv
|
||||||
|
, ULONG cb
|
||||||
|
, ULONG* pcbRead)
|
||||||
|
{ return E_NOTIMPL; }
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SkBaseIStream::Write(void const* pv
|
||||||
|
, ULONG cb
|
||||||
|
, ULONG* pcbWritten)
|
||||||
|
{ return E_NOTIMPL; }
|
||||||
|
|
||||||
|
// IStream Interface
|
||||||
|
HRESULT STDMETHODCALLTYPE SkBaseIStream::SetSize(ULARGE_INTEGER)
|
||||||
|
{ return E_NOTIMPL; }
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SkBaseIStream::CopyTo(IStream*
|
||||||
|
, ULARGE_INTEGER
|
||||||
|
, ULARGE_INTEGER*
|
||||||
|
, ULARGE_INTEGER*)
|
||||||
|
{ return E_NOTIMPL; }
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SkBaseIStream::Commit(DWORD)
|
||||||
|
{ return E_NOTIMPL; }
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SkBaseIStream::Revert(void)
|
||||||
|
{ return E_NOTIMPL; }
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SkBaseIStream::LockRegion(ULARGE_INTEGER
|
||||||
|
, ULARGE_INTEGER
|
||||||
|
, DWORD)
|
||||||
|
{ return E_NOTIMPL; }
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SkBaseIStream::UnlockRegion(ULARGE_INTEGER
|
||||||
|
, ULARGE_INTEGER
|
||||||
|
, DWORD)
|
||||||
|
{ return E_NOTIMPL; }
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SkBaseIStream::Clone(IStream **)
|
||||||
|
{ return E_NOTIMPL; }
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SkBaseIStream::Seek(LARGE_INTEGER liDistanceToMove
|
||||||
|
, DWORD dwOrigin
|
||||||
|
, ULARGE_INTEGER* lpNewFilePointer)
|
||||||
|
{ return E_NOTIMPL; }
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SkBaseIStream::Stat(STATSTG* pStatstg
|
||||||
|
, DWORD grfStatFlag)
|
||||||
|
{ return E_NOTIMPL; }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SkIStream
|
||||||
|
*/
|
||||||
|
SkIStream::SkIStream(SkStream* stream, bool unrefOnRelease)
|
||||||
|
: SkBaseIStream()
|
||||||
|
, fSkStream(stream)
|
||||||
|
, fUnrefOnRelease(unrefOnRelease)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
SkIStream::~SkIStream() {
|
||||||
|
if (NULL != this->fSkStream && fUnrefOnRelease) {
|
||||||
|
this->fSkStream->unref();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT SkIStream::CreateFromSkStream(SkStream* stream
|
||||||
|
, bool unrefOnRelease
|
||||||
|
, IStream ** ppStream)
|
||||||
|
{
|
||||||
|
*ppStream = new SkIStream(stream, unrefOnRelease);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ISequentialStream Interface
|
||||||
|
HRESULT STDMETHODCALLTYPE SkIStream::Read(void* pv, ULONG cb, ULONG* pcbRead) {
|
||||||
|
*pcbRead = this->fSkStream->read(pv, cb);
|
||||||
|
return (*pcbRead == cb) ? S_OK : S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SkIStream::Write(void const* pv
|
||||||
|
, ULONG cb
|
||||||
|
, ULONG* pcbWritten)
|
||||||
|
{
|
||||||
|
return STG_E_CANTSAVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IStream Interface
|
||||||
|
HRESULT STDMETHODCALLTYPE SkIStream::Seek(LARGE_INTEGER liDistanceToMove
|
||||||
|
, DWORD dwOrigin
|
||||||
|
, ULARGE_INTEGER* lpNewFilePointer)
|
||||||
|
{
|
||||||
|
if (lpNewFilePointer != NULL) {
|
||||||
|
(*lpNewFilePointer).QuadPart = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
switch(dwOrigin) {
|
||||||
|
case STREAM_SEEK_SET: {
|
||||||
|
if (!this->fSkStream->rewind()) {
|
||||||
|
hr = E_FAIL;
|
||||||
|
} else {
|
||||||
|
size_t skipped = this->fSkStream->skip(
|
||||||
|
liDistanceToMove.QuadPart
|
||||||
|
);
|
||||||
|
if (skipped != liDistanceToMove.QuadPart) {
|
||||||
|
hr = E_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STREAM_SEEK_CUR: {
|
||||||
|
size_t skipped = this->fSkStream->skip(liDistanceToMove.QuadPart);
|
||||||
|
if (skipped != liDistanceToMove.QuadPart) {
|
||||||
|
hr = E_FAIL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STREAM_SEEK_END: {
|
||||||
|
if (!this->fSkStream->rewind()) {
|
||||||
|
hr = E_FAIL;
|
||||||
|
} else {
|
||||||
|
size_t skipped = this->fSkStream->skip(
|
||||||
|
this->fSkStream->getLength() + liDistanceToMove.QuadPart
|
||||||
|
);
|
||||||
|
if (skipped != liDistanceToMove.QuadPart) {
|
||||||
|
hr = E_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
hr = STG_E_INVALIDFUNCTION;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SkIStream::Stat(STATSTG* pStatstg
|
||||||
|
, DWORD grfStatFlag)
|
||||||
|
{
|
||||||
|
if (0 == grfStatFlag & STATFLAG_NONAME) {
|
||||||
|
return STG_E_INVALIDFLAG;
|
||||||
|
}
|
||||||
|
pStatstg->pwcsName = NULL;
|
||||||
|
pStatstg->cbSize.QuadPart = this->fSkStream->getLength();
|
||||||
|
pStatstg->clsid = CLSID_NULL;
|
||||||
|
pStatstg->type = STGTY_STREAM;
|
||||||
|
pStatstg->grfMode = STGM_READ;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SkIWStream
|
||||||
|
*/
|
||||||
|
SkWIStream::SkWIStream(SkWStream* stream)
|
||||||
|
: SkBaseIStream()
|
||||||
|
, fSkWStream(stream)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
SkWIStream::~SkWIStream() {
|
||||||
|
if (NULL != this->fSkWStream) {
|
||||||
|
this->fSkWStream->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT SkWIStream::CreateFromSkWStream(SkWStream* stream
|
||||||
|
, IStream ** ppStream)
|
||||||
|
{
|
||||||
|
*ppStream = new SkWIStream(stream);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ISequentialStream Interface
|
||||||
|
HRESULT STDMETHODCALLTYPE SkWIStream::Write(void const* pv
|
||||||
|
, ULONG cb
|
||||||
|
, ULONG* pcbWritten)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
bool wrote = this->fSkWStream->write(pv, cb);
|
||||||
|
if (wrote) {
|
||||||
|
*pcbWritten = cb;
|
||||||
|
} else {
|
||||||
|
*pcbWritten = 0;
|
||||||
|
hr = S_FALSE;
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IStream Interface
|
||||||
|
HRESULT STDMETHODCALLTYPE SkWIStream::Stat(STATSTG* pStatstg
|
||||||
|
, DWORD grfStatFlag)
|
||||||
|
{
|
||||||
|
if (0 == grfStatFlag & STATFLAG_NONAME) {
|
||||||
|
return STG_E_INVALIDFLAG;
|
||||||
|
}
|
||||||
|
pStatstg->pwcsName = NULL;
|
||||||
|
pStatstg->cbSize.QuadPart = 0;
|
||||||
|
pStatstg->clsid = CLSID_NULL;
|
||||||
|
pStatstg->type = STGTY_STREAM;
|
||||||
|
pStatstg->grfMode = STGM_WRITE;
|
||||||
|
return S_OK;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user