From ca22bad4c45e41af302d76ca9bcfe3dcd50e02cd Mon Sep 17 00:00:00 2001 From: zhoulisheng <635547767@qq.com> Date: Fri, 15 Jul 2022 01:02:57 -0700 Subject: [PATCH] 1.delete crc32.js delete png-metadata.js Signed-off-by: zhoulisheng <635547767@qq.com> --- OAT.xml | 6 +- entry/src/main/ets/pages/pngjTestCasePage.ets | 42 -- imageknife/index.ets | 3 - .../ets/components/imageknife/pngj/crc32.js | 109 ----- .../imageknife/pngj/png-metadata.js | 423 ------------------ 5 files changed, 2 insertions(+), 581 deletions(-) delete mode 100644 imageknife/src/main/ets/components/imageknife/pngj/crc32.js delete mode 100644 imageknife/src/main/ets/components/imageknife/pngj/png-metadata.js diff --git a/OAT.xml b/OAT.xml index a41a126..77d2187 100644 --- a/OAT.xml +++ b/OAT.xml @@ -6,15 +6,13 @@ - - + - - + diff --git a/entry/src/main/ets/pages/pngjTestCasePage.ets b/entry/src/main/ets/pages/pngjTestCasePage.ets index 1b7ba28..3114fff 100644 --- a/entry/src/main/ets/pages/pngjTestCasePage.ets +++ b/entry/src/main/ets/pages/pngjTestCasePage.ets @@ -14,16 +14,6 @@ */ import router from '@system.router'; import { Pngj } from '@ohos/imageknife' -import { - RESOLUTION_UNITS, - insertMetadata, - readMetadata, - writeMetadata, - textEncode, - textDecode, - extractChunks, - encodeChunks -} from '@ohos/imageknife' import resourceManager from '@ohos.resourceManager'; import { FileUtils } from '@ohos/imageknife' import featureability from '@ohos.ability.featureAbility' @@ -165,38 +155,6 @@ struct PngjTestCasePage { }.width('100%') .height(60).backgroundColor(Color.Pink) - Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Button('测试readMetadata') - .onClick(() => { - globalThis.ImageKnife.getImageKnifeContext() - .resourceManagergetMedia($r('app.media.pngSample').id) - .then(data => { - let arrayBuffer = this.typedArrayToBuffer(data); - let metadata = readMetadata(arrayBuffer); - console.log("readMetadata metadata=" + JSON.stringify(metadata)) - this.hint5 = JSON.stringify(metadata); - }) - .catch(err => { - console.log('测试readMetadata err=' + err) - }) - }).margin({ top: 5, left: 10 }) - Button('测试writeMetadata') - .onClick(() => { - globalThis.ImageKnife.getImageKnifeContext() - .resourceManagergetMedia($r('app.media.pngSample').id) - .then(data => { - let arrayBuffer = this.typedArrayToBuffer(data); - // let pngBuffer = writeMetadata(arrayBuffer); - // console.log("writeMetadata metadata="+JSON.stringify(metadata)) - // this.hint5 = JSON.stringify(metadata); - }) - .catch(err => { - console.log('测试writeMetadata err=' + err) - }) - }).margin({ top: 5, left: 10 }) - }.width('100%') - .height(60).backgroundColor(Color.Pink) - Text(this.hint1) .width('100%') .height(120) diff --git a/imageknife/index.ets b/imageknife/index.ets index baf014d..7dcb522 100644 --- a/imageknife/index.ets +++ b/imageknife/index.ets @@ -83,9 +83,6 @@ export * from './src/main/ets/components/imageknife/pngj/Pngj' export {handler} from './src/main/ets/components/imageknife/pngj/PngWork' export * from './src/main/ets/components/imageknife/pngj/UPNG' -export { - RESOLUTION_UNITS, insertMetadata, readMetadata, writeMetadata, textEncode, textDecode, extractChunks, encodeChunks -} from './src/main/ets/components/imageknife/pngj/png-metadata' /** diff --git a/imageknife/src/main/ets/components/imageknife/pngj/crc32.js b/imageknife/src/main/ets/components/imageknife/pngj/crc32.js deleted file mode 100644 index da6d658..0000000 --- a/imageknife/src/main/ets/components/imageknife/pngj/crc32.js +++ /dev/null @@ -1,109 +0,0 @@ -/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ -/* vim: set ts=2: */ -/*exported CRC32 */ -export var Crc32; -(function(factory){ - /*jshint ignore:start */ - /*eslint-disable */ - - factory(Crc32 = {}); - - /*eslint-enable */ - /*jshint ignore:end */ -}(function (CRC32) { - CRC32.version = '1.2.0'; - /* see perf/crc32table.js */ - /*global Int32Array */ - function signed_crc_table() { - var c = 0, table = new Array(256); - - for (var n = 0; n != 256; ++n) { - c = n; - c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); - c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); - c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); - c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); - c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); - c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); - c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); - c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); - table[n] = c; - } - - return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; - } - - var T = signed_crc_table(); - - function crc32_bstr(bstr, seed) { - var C = seed ^ -1, L = bstr.length - 1; - for (var i = 0; i < L; ) { - C = (C >>> 8) ^ T[(C ^ bstr.charCodeAt(i++))&0xFF]; - C = (C >>> 8) ^ T[(C ^ bstr.charCodeAt(i++))&0xFF]; - } - if (i === L) C = (C >>> 8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; - return C ^ -1; - } - - function crc32_buf(buf, seed) { - if (buf.length > 10000) return crc32_buf_8(buf, seed); - var C = seed ^ -1, L = buf.length - 3; - for (var i = 0; i < L; ) { - C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - } - while (i < L + 3) C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - return C ^ -1; - } - - function crc32_buf_8(buf, seed) { - var C = seed ^ -1, L = buf.length - 7; - for (var i = 0; i < L; ) { - C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - } - while (i < L + 7) C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF]; - return C ^ -1; - } - - function crc32_str(str, seed) { - var C = seed ^ -1; - for (var i = 0, L = str.length, c, d; i < L; ) { - c = str.charCodeAt(i++); - if (c < 0x80) { - C = (C >>> 8) ^ T[(C ^ c)&0xFF]; - } else if (c < 0x800) { - C = (C >>> 8) ^ T[(C ^ (192 | ((c >> 6) & 31)))&0xFF]; - C = (C >>> 8) ^ T[(C ^ (128 | (c & 63)))&0xFF]; - } else if (c >= 0xD800 && c < 0xE000) { - c = (c & 1023) + 64; - d = str.charCodeAt(i++) & 1023; - C = (C >>> 8) ^ T[(C ^ (240 | ((c >> 8) & 7)))&0xFF]; - C = (C >>> 8) ^ T[(C ^ (128 | ((c >> 2) & 63)))&0xFF]; - C = (C >>> 8) ^ T[(C ^ (128 | ((d >> 6) & 15) | ((c & 3) << 4)))&0xFF]; - C = (C >>> 8) ^ T[(C ^ (128 | (d & 63)))&0xFF]; - } else { - C = (C >>> 8) ^ T[(C ^ (224 | ((c >> 12) & 15)))&0xFF]; - C = (C >>> 8) ^ T[(C ^ (128 | ((c >> 6) & 63)))&0xFF]; - C = (C >>> 8) ^ T[(C ^ (128 | (c & 63)))&0xFF]; - } - } - return C ^ -1; - } - - CRC32.table = T; - // $FlowIgnore - CRC32.bstr = crc32_bstr; - // $FlowIgnore - CRC32.buf = crc32_buf; - // $FlowIgnore - CRC32.str = crc32_str; -})); diff --git a/imageknife/src/main/ets/components/imageknife/pngj/png-metadata.js b/imageknife/src/main/ets/components/imageknife/pngj/png-metadata.js deleted file mode 100644 index fbad121..0000000 --- a/imageknife/src/main/ets/components/imageknife/pngj/png-metadata.js +++ /dev/null @@ -1,423 +0,0 @@ -/** - * library to read and write PNG Metadata - * - * References: - * w3 PNG Chunks specification: https://www.w3.org/TR/PNG-Chunks.html - * The Metadata in PNG files: https://dev.exiv2.org/projects/exiv2/wiki/The_Metadata_in_PNG_files - */ - -import { Crc32 } from './crc32' - - -// Used for fast-ish conversion between uint8s and uint32s/int32s. -// Also required in order to remain agnostic for both Node Buffers and -// Uint8Arrays. -let uint8 = new Uint8Array(4) -let int32 = new Int32Array(uint8.buffer) -let uint32 = new Uint32Array(uint8.buffer) - -export const RESOLUTION_UNITS = { UNDEFINED: 0, METERS: 1, INCHES: 2 }; - -/** - * https://github.com/aheckmann/sliced - * An Array.prototype.slice.call(arguments) alternative - * @param {Object} args something with a length - * @param {Number} slice - * @param {Number} sliceEnd - * @api public - */ -function sliced(args, slice, sliceEnd) { - var ret = []; - var len = args.length; - - if (0 === len) return ret; - - var start = slice < 0 - ? Math.max(0, slice + len) - : slice || 0; - - if (sliceEnd !== undefined) { - len = sliceEnd < 0 - ? sliceEnd + len - : sliceEnd - } - - while (len-- > start) { - ret[len - start] = args[len]; - } - - return ret; -} - -/** - * https://github.com/hughsk/png-chunk-text - * Returns a chunk object containing the metadata for a given key and value: - * @param keyword - * @param content - * @param chunkName - * @returns {{data: Uint8Array, name: 'tEXt'}} - */ -export function textEncode(keyword, content, chunkName = 'tEXt') { - keyword = String(keyword) - content = String(content) - - if (content.length && (!/^[\x00-\xFF]+$/.test(keyword) || !/^[\x00-\xFF]+$/.test(content))) { - throw new Error('Only Latin-1 characters are permitted in PNG tEXt chunks. You might want to consider base64 encoding and/or zEXt compression') - } - - if (keyword.length >= 80) { - throw new Error('Keyword "' + keyword + '" is longer than the 79-character limit imposed by the PNG specification') - } - - let totalSize = keyword.length + content.length + 1 - let output = new Uint8Array(totalSize) - let idx = 0 - let code - - for (let i = 0; i < keyword.length; i++) { - if (!(code = keyword.charCodeAt(i))) { - throw new Error('0x00 character is not permitted in tEXt keywords') - } - - output[idx++] = code - } - - output[idx++] = 0 - - for (let j = 0; j < content.length; j++) { - if (!(code = content.charCodeAt(j))) { - throw new Error('0x00 character is not permitted in tEXt content') - } - - output[idx++] = code - } - - return { - name: chunkName, - data: output - } -} - -/** - * https://github.com/hughsk/png-chunk-text - * Reads a Uint8Array or Node.js Buffer instance containing a tEXt PNG chunk's data and returns its keyword/text: - * @param data - * @returns {{text: string, keyword: string}} - */ -export function textDecode(data) { - if (data.data && data.name) { - data = data.data - } - - let naming = true - let text = '' - let name = '' - - for (let i = 0; i < data.length; i++) { - let code = data[i] - - if (naming) { - if (code) { - name += String.fromCharCode(code) - } else { - naming = false - } - } else { - if (code) { - text += String.fromCharCode(code) - } else { - throw new Error('Invalid NULL character found. 0x00 character is not permitted in tEXt content') - } - } - } - - return { - keyword: name, - text: text - } -} - -/** - * https://github.com/hughsk/png-chunks-extract - * Extract the data chunks from a PNG file. - * Useful for reading the metadata of a PNG image, or as the base of a more complete PNG parser. - * Takes the raw image file data as a Uint8Array or Node.js Buffer, and returns an array of chunks. Each chunk has a name and data buffer: - * @param data {Uint8Array} - * @returns {[{name: String, data: Uint8Array}]} - */ -export function extractChunks(data) { - if (data[0] !== 0x89) throw new Error('Invalid .png file header') - if (data[1] !== 0x50) throw new Error('Invalid .png file header') - if (data[2] !== 0x4E) throw new Error('Invalid .png file header') - if (data[3] !== 0x47) throw new Error('Invalid .png file header') - if (data[4] !== 0x0D) throw new Error('Invalid .png file header: possibly caused by DOS-Unix line ending conversion?') - if (data[5] !== 0x0A) throw new Error('Invalid .png file header: possibly caused by DOS-Unix line ending conversion?') - if (data[6] !== 0x1A) throw new Error('Invalid .png file header') - if (data[7] !== 0x0A) throw new Error('Invalid .png file header: possibly caused by DOS-Unix line ending conversion?') - - let ended = false - let chunks = [] - let idx = 8 - - while (idx < data.length) { - // Read the length of the current chunk, - // which is stored as a Uint32. - uint8[3] = data[idx++] - uint8[2] = data[idx++] - uint8[1] = data[idx++] - uint8[0] = data[idx++] - - // Chunk includes name/type for CRC check (see below). - let length = uint32[0] + 4 - let chunk = new Uint8Array(length) - chunk[0] = data[idx++] - chunk[1] = data[idx++] - chunk[2] = data[idx++] - chunk[3] = data[idx++] - - // Get the name in ASCII for identification. - let name = ( - String.fromCharCode(chunk[0]) + - String.fromCharCode(chunk[1]) + - String.fromCharCode(chunk[2]) + - String.fromCharCode(chunk[3]) - ) - - // The IHDR header MUST come first. - if (!chunks.length && name !== 'IHDR') { - throw new Error('IHDR header missing') - } - - // The IEND header marks the end of the file, - // so on discovering it break out of the loop. - if (name === 'IEND') { - ended = true - chunks.push({ - name: name, - data: new Uint8Array(0) - }) - - break - } - - // Read the contents of the chunk out of the main buffer. - for (let i = 4; i < length; i++) { - chunk[i] = data[idx++] - } - - // Read out the CRC value for comparison. - // It's stored as an Int32. - uint8[3] = data[idx++] - uint8[2] = data[idx++] - uint8[1] = data[idx++] - uint8[0] = data[idx++] - - let crcActual = int32[0] - let crcExpect = Crc32.buf(chunk) - if (crcExpect !== crcActual) { - throw new Error( - 'CRC values for ' + name + ' header do not match, PNG file is likely corrupted' - ) - } - - // The chunk data is now copied to remove the 4 preceding - // bytes used for the chunk name/type. - let chunkData = new Uint8Array(chunk.buffer.slice(4)) - - chunks.push({ - name: name, - data: chunkData - }) - } - - if (!ended) { - throw new Error('.png file ended prematurely: no IEND header was found') - } - - return chunks -} - -/** - * https://github.com/hughsk/png-chunks-encode - * Return a fresh PNG buffer given a set of PNG chunks. Useful in combination with png-chunks-encode to easily modify or add to the data of a PNG file. - * Takes an array of chunks, each with a name and data: - * @param chunks {[{name: String, data: Uint8Array}]} - * @returns {Uint8Array} - */ -export function encodeChunks(chunks) { - let totalSize = 8 - let idx = totalSize - let i - - for (i = 0; i < chunks.length; i++) { - totalSize += chunks[i].data.length - totalSize += 12 - } - - let output = new Uint8Array(totalSize) - - output[0] = 0x89 - output[1] = 0x50 - output[2] = 0x4E - output[3] = 0x47 - output[4] = 0x0D - output[5] = 0x0A - output[6] = 0x1A - output[7] = 0x0A - - for (i = 0; i < chunks.length; i++) { - let chunk = chunks[i] - let name = chunk.name - let data = chunk.data - let size = data.length - let nameChars = [ - name.charCodeAt(0), - name.charCodeAt(1), - name.charCodeAt(2), - name.charCodeAt(3) - ] - - uint32[0] = size - output[idx++] = uint8[3] - output[idx++] = uint8[2] - output[idx++] = uint8[1] - output[idx++] = uint8[0] - - output[idx++] = nameChars[0] - output[idx++] = nameChars[1] - output[idx++] = nameChars[2] - output[idx++] = nameChars[3] - - for (let j = 0; j < size; ) { - output[idx++] = data[j++] - } - - let crcCheck = nameChars.concat(sliced(data, undefined, undefined)); - int32[0] = Crc32.buf(crcCheck) - output[idx++] = uint8[3] - output[idx++] = uint8[2] - output[idx++] = uint8[1] - output[idx++] = uint8[0] - } - - return output -} - -/** - * read 4 bytes number from UInt8Array. - * @param uint8array - * @param offset - * @returns {number} - */ -function readUint32(uint8array, offset) { - let byte1, byte2, byte3, byte4; - byte1 = uint8array[offset++]; - byte2 = uint8array[offset++]; - byte3 = uint8array[offset++]; - byte4 = uint8array[offset]; - return 0 | (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4; -} - -/** - * write 4 bytes number to UInt8Array. - * @param uint8array - * @param num - * @param offset - */ -function writeUInt32(uint8array, num, offset) { - uint8array[offset] = (num & 0xff000000) >> 24; - uint8array[offset + 1] = (num & 0x00ff0000) >> 16; - uint8array[offset + 2] = (num & 0x0000ff00) >> 8; - uint8array[offset + 3] = (num & 0x000000ff); -} - -/** - * Get object with PNG metadata. only tEXt and pHYs chunks are parsed - * @param buffer {Buffer} - * @returns {{tEXt: {keyword: value}, pHYs: {x: number, y: number, units: RESOLUTION_UNITS}, [string]: true}} - */ -export function readMetadata(buffer) { - let result = {}; - const chunks = extractChunks(buffer); - chunks.forEach(chunk => { - switch (chunk.name) { - case 'tEXt': - if (!result['tEXt']) { - result['tEXt'] = {}; - } - let textChunk = textDecode(chunk.data); - result['tEXt'][textChunk.keyword] = textChunk.text; - break - case 'pHYs': - result['pHYs'] = { - // Pixels per unit, X axis: 4 bytes (unsigned integer) - "x": readUint32(chunk.data, 0), - // Pixels per unit, Y axis: 4 bytes (unsigned integer) - "y": readUint32(chunk.data, 4), - "unit": chunk.data[8], - } - break - case 'gAMA': - case 'cHRM': - case 'sRGB': - case 'IHDR': - case 'iCCP': - default: - result[chunk.name] = true; - } - }) - return result; -} - -/** - * create new Buffer with metadata. only tEXt and pHYs chunks are supported. - * @param buffer {Buffer} - * @param metadata {{tEXt: {keyword: value}, pHYs: {x: number, y: number, units: RESOLUTION_UNITS}}} - * @returns {Buffer} - */ -export function writeMetadata(buffer, metadata) { - const chunks = extractChunks(buffer); - insertMetadata(chunks, metadata); - ArrayBuffer - let out = encodeChunks(chunks).buffer; - return out; -} - - -export function insertMetadata(chunks, metadata) { - if (metadata.clear) { - for (let i = chunks.length - 1; i--; ) { - switch (chunks[i].name) { - case 'IHDR': - case 'IDAT': - case 'IEND': - break; - default: - chunks.splice(i, 1); - } - } - } - if (metadata.tEXt) { - for (var keyword in metadata.tEXt) { - chunks.splice(-1, 0, textEncode(keyword, metadata.tEXt[keyword])) - } - } - - if (metadata.pHYs) { - const data = new Uint8Array(9); - writeUInt32(data, metadata.pHYs.x, 0) - writeUInt32(data, metadata.pHYs.y, 4) - data[8] = metadata.pHYs.units; // inches - - let pHYs = chunks.find(chunk => chunk.name === "pHYs"); - if (pHYs) { - pHYs.data = data; - } - else { - chunks.splice(1, 0, { name: "pHYs", data: data }) - } - } -} - - -