cf2cfa174c
Review URL: https://codereview.chromium.org/23361009 git-svn-id: http://skia.googlecode.com/svn/trunk@10854 2bbb7eff-a529-9590-31e7-b0007b416f81
119 lines
3.4 KiB
C++
119 lines
3.4 KiB
C++
/*
|
|
* Copyright 2013 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "SkPdfNativeObject.h"
|
|
|
|
// TODO(edisonn): mac builder does not find the header ... but from headers is ok
|
|
//#include "SkPdfStreamCommonDictionary_autogen.h"
|
|
#include "SkPdfHeaders_autogen.h"
|
|
|
|
#include "SkFlate.h"
|
|
#include "SkStream.h"
|
|
#include "SkPdfNativeTokenizer.h"
|
|
|
|
#include "SkBitmap.h"
|
|
#include "SkPdfFont.h"
|
|
|
|
SkPdfNativeObject SkPdfNativeObject::kNull = SkPdfNativeObject::makeNull();
|
|
|
|
bool SkPdfNativeObject::applyFlateDecodeFilter() {
|
|
if (!SkFlate::HaveFlate()) {
|
|
// TODO(edisonn): warn, make callers handle it
|
|
return false;
|
|
}
|
|
|
|
const unsigned char* old = fStr.fBuffer;
|
|
bool deleteOld = isStreamOwned();
|
|
|
|
SkMemoryStream skstream(fStr.fBuffer, fStr.fBytes >> 2, false);
|
|
SkDynamicMemoryWStream uncompressedData;
|
|
|
|
if (SkFlate::Inflate(&skstream, &uncompressedData)) {
|
|
fStr.fBytes = (uncompressedData.bytesWritten() << 2) + kOwnedStreamBit + kUnfilteredStreamBit;
|
|
fStr.fBuffer = (const unsigned char*)new unsigned char[uncompressedData.bytesWritten()];
|
|
uncompressedData.copyTo((void*)fStr.fBuffer);
|
|
|
|
if (deleteOld) {
|
|
delete[] old;
|
|
}
|
|
|
|
return true;
|
|
} else {
|
|
// TODO(edisonn): warn, make callers handle it
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool SkPdfNativeObject::applyDCTDecodeFilter() {
|
|
// this would fail, and it won't allow any more filters.
|
|
// technically, it would be possible, but not a real world scenario
|
|
// TODO(edisonn): or get the image here and store it for fast retrieval?
|
|
return false;
|
|
}
|
|
|
|
bool SkPdfNativeObject::applyFilter(const char* name) {
|
|
if (strcmp(name, "FlateDecode") == 0) {
|
|
return applyFlateDecodeFilter();
|
|
} else if (strcmp(name, "DCTDecode") == 0) {
|
|
return applyDCTDecodeFilter();
|
|
}
|
|
// TODO(edisonn): allert, not supported, but should be implemented asap
|
|
return false;
|
|
}
|
|
|
|
bool SkPdfNativeObject::filterStream() {
|
|
if (!hasStream()) {
|
|
return false;
|
|
}
|
|
|
|
if (isStreamFiltered()) {
|
|
return true;
|
|
}
|
|
|
|
SkPdfStreamCommonDictionary* stream = (SkPdfStreamCommonDictionary*)this;
|
|
|
|
if (!stream->has_Filter()) {
|
|
fStr.fBytes = ((fStr.fBytes >> 1) << 1) + kFilteredStreamBit;
|
|
} else if (stream->isFilterAName(NULL)) {
|
|
SkString filterName = stream->getFilterAsName(NULL);
|
|
applyFilter(filterName.c_str());
|
|
} else if (stream->isFilterAArray(NULL)) {
|
|
const SkPdfArray* filters = stream->getFilterAsArray(NULL);
|
|
int cnt = filters->size();
|
|
for (int i = cnt - 1; i >= 0; i--) {
|
|
const SkPdfNativeObject* filterName = filters->objAtAIndex(i);
|
|
if (filterName != NULL && filterName->isName()) {
|
|
if (!applyFilter(filterName->nameValue())) {
|
|
break;
|
|
}
|
|
} else {
|
|
// TODO(edisonn): report warning
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void SkPdfNativeObject::releaseData() {
|
|
if (fData) {
|
|
switch (fDataType) {
|
|
case kFont_Data:
|
|
delete (SkPdfFont*)fData;
|
|
break;
|
|
case kBitmap_Data:
|
|
delete (SkBitmap*)fData;
|
|
break;
|
|
default:
|
|
SkASSERT(false);
|
|
break;
|
|
}
|
|
}
|
|
fData = NULL;
|
|
fDataType = kEmpty_Data;
|
|
}
|