mirror of
https://github.com/go-vgo/robotgo.git
synced 2025-05-31 06:13:55 +00:00
remove bitmap and hook code [ci skip]
This commit is contained in:
parent
6c249c12a3
commit
48f1adce7e
@ -1,96 +0,0 @@
|
||||
#include "MMBitmap.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
//MMBitmapRef createMMBitmap()
|
||||
MMBitmapRef createMMBitmap(
|
||||
uint8_t *buffer,
|
||||
size_t width,
|
||||
size_t height,
|
||||
size_t bytewidth,
|
||||
uint8_t bitsPerPixel,
|
||||
uint8_t bytesPerPixel
|
||||
){
|
||||
MMBitmapRef bitmap = malloc(sizeof(MMBitmap));
|
||||
if (bitmap == NULL) return NULL;
|
||||
|
||||
bitmap->imageBuffer = buffer;
|
||||
bitmap->width = width;
|
||||
bitmap->height = height;
|
||||
bitmap->bytewidth = bytewidth;
|
||||
bitmap->bitsPerPixel = bitsPerPixel;
|
||||
bitmap->bytesPerPixel = bytesPerPixel;
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
void destroyMMBitmap(MMBitmapRef bitmap)
|
||||
{
|
||||
assert(bitmap != NULL);
|
||||
|
||||
if (bitmap->imageBuffer != NULL) {
|
||||
free(bitmap->imageBuffer);
|
||||
bitmap->imageBuffer = NULL;
|
||||
}
|
||||
|
||||
free(bitmap);
|
||||
}
|
||||
|
||||
void destroyMMBitmapBuffer(char * bitmapBuffer, void * hint)
|
||||
{
|
||||
if (bitmapBuffer != NULL)
|
||||
{
|
||||
free(bitmapBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
MMBitmapRef copyMMBitmap(MMBitmapRef bitmap)
|
||||
{
|
||||
uint8_t *copiedBuf = NULL;
|
||||
|
||||
assert(bitmap != NULL);
|
||||
if (bitmap->imageBuffer != NULL) {
|
||||
const size_t bufsize = bitmap->height * bitmap->bytewidth;
|
||||
copiedBuf = malloc(bufsize);
|
||||
if (copiedBuf == NULL) return NULL;
|
||||
|
||||
memcpy(copiedBuf, bitmap->imageBuffer, bufsize);
|
||||
}
|
||||
|
||||
return createMMBitmap(copiedBuf,
|
||||
bitmap->width,
|
||||
bitmap->height,
|
||||
bitmap->bytewidth,
|
||||
bitmap->bitsPerPixel,
|
||||
bitmap->bytesPerPixel);
|
||||
}
|
||||
|
||||
MMBitmapRef copyMMBitmapFromPortion(MMBitmapRef source, MMRect rect)
|
||||
{
|
||||
assert(source != NULL);
|
||||
|
||||
if (source->imageBuffer == NULL || !MMBitmapRectInBounds(source, rect)) {
|
||||
return NULL;
|
||||
} else {
|
||||
uint8_t *copiedBuf = NULL;
|
||||
const size_t bufsize = rect.size.height * source->bytewidth;
|
||||
const size_t offset = (source->bytewidth * rect.origin.y) +
|
||||
(rect.origin.x * source->bytesPerPixel);
|
||||
|
||||
/* Don't go over the bounds, programmer! */
|
||||
assert((bufsize + offset) <= (source->bytewidth * source->height));
|
||||
|
||||
copiedBuf = malloc(bufsize);
|
||||
if (copiedBuf == NULL) return NULL;
|
||||
|
||||
memcpy(copiedBuf, source->imageBuffer + offset, bufsize);
|
||||
|
||||
return createMMBitmap(copiedBuf,
|
||||
rect.size.width,
|
||||
rect.size.height,
|
||||
source->bytewidth,
|
||||
source->bitsPerPixel,
|
||||
source->bytesPerPixel);
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef MMARRAY_H
|
||||
#define MMARRAY_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
struct _MMPointArray {
|
||||
MMPoint *array; /* Pointer to actual data. */
|
||||
size_t count; /* Number of elements in array. */
|
||||
size_t _allocedCount; /* Private; do not use outside of MMPointArray.c. */
|
||||
};
|
||||
|
||||
typedef struct _MMPointArray MMPointArray;
|
||||
typedef MMPointArray *MMPointArrayRef;
|
||||
|
||||
/* Creates array of an initial size (the maximum size is still limitless).
|
||||
* This follows the "Create" Rule; i.e., responsibility for "destroying" the
|
||||
* array is given to the caller. */
|
||||
MMPointArrayRef createMMPointArray(size_t initialCount);
|
||||
|
||||
/* Frees memory occupied by |pointArray|. Does not accept NULL. */
|
||||
void destroyMMPointArray(MMPointArrayRef pointArray);
|
||||
|
||||
/* Appends a point to an array, increasing the internal size if necessary. */
|
||||
void MMPointArrayAppendPoint(MMPointArrayRef pointArray, MMPoint point);
|
||||
|
||||
/* Retrieve point from array. */
|
||||
#define MMPointArrayGetItem(a, i) ((a)->array)[i]
|
||||
|
||||
/* Set point in array. */
|
||||
#define MMPointArraySetItem(a, i, item) ((a)->array[i] = item)
|
||||
|
||||
#endif /* MMARRAY_H */
|
@ -1,41 +0,0 @@
|
||||
#include "MMPointArray.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
MMPointArrayRef createMMPointArray(size_t initialCount)
|
||||
{
|
||||
MMPointArrayRef pointArray = calloc(1, sizeof(MMPointArray));
|
||||
|
||||
if (initialCount == 0) initialCount = 1;
|
||||
|
||||
pointArray->_allocedCount = initialCount;
|
||||
pointArray->array = malloc(pointArray->_allocedCount * sizeof(MMPoint));
|
||||
if (pointArray->array == NULL) return NULL;
|
||||
|
||||
return pointArray;
|
||||
}
|
||||
|
||||
void destroyMMPointArray(MMPointArrayRef pointArray)
|
||||
{
|
||||
if (pointArray->array != NULL) {
|
||||
free(pointArray->array);
|
||||
pointArray->array = NULL;
|
||||
}
|
||||
|
||||
free(pointArray);
|
||||
}
|
||||
|
||||
void MMPointArrayAppendPoint(MMPointArrayRef pointArray, MMPoint point)
|
||||
{
|
||||
const size_t newCount = ++(pointArray->count);
|
||||
if (pointArray->_allocedCount < newCount) {
|
||||
do {
|
||||
/* Double size each time to avoid calls to realloc(). */
|
||||
pointArray->_allocedCount <<= 1;
|
||||
} while (pointArray->_allocedCount < newCount);
|
||||
pointArray->array = realloc(pointArray->array,
|
||||
sizeof(point) *
|
||||
pointArray->_allocedCount);
|
||||
}
|
||||
|
||||
pointArray->array[pointArray->count - 1] = point;
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef UTHASHTABLE_H
|
||||
#define UTHASHTABLE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "uthash.h"
|
||||
|
||||
/* All node structs must begin with this (note that there is NO semicolon). */
|
||||
#define UTHashNode_HEAD UT_hash_handle hh;
|
||||
|
||||
/* This file contains convenience macros and a standard struct for working with
|
||||
* uthash hash tables.
|
||||
*
|
||||
* The main purpose of this is for convenience of creating/freeing nodes. */
|
||||
struct _UTHashTable {
|
||||
void *uttable; /* The uthash table -- must start out as NULL. */
|
||||
void *nodes; /* Contiguous array of nodes. */
|
||||
size_t allocedNodeCount; /* Node count currently allocated for. */
|
||||
size_t nodeCount; /* Current node count. */
|
||||
size_t nodeSize; /* Size of each node. */
|
||||
};
|
||||
|
||||
typedef struct _UTHashTable UTHashTable;
|
||||
|
||||
/* Initiates a hash table to the default values. |table| should point to an
|
||||
* already allocated UTHashTable struct.
|
||||
*
|
||||
* If the |initialCount| argument in initHashTable is given, |nodes| is
|
||||
* allocated immediately to the maximum size and new nodes are simply slices of
|
||||
* that array. This can save calls to malloc if many nodes are to be added, and
|
||||
* the a reasonable maximum number is known ahead of time.
|
||||
*
|
||||
* If the node count goes over this maximum, or if |initialCount| is 0, the
|
||||
* array is dynamically reallocated to fit the size.
|
||||
*/
|
||||
void initHashTable(UTHashTable *table, size_t initialCount, size_t nodeSize);
|
||||
|
||||
/* Frees memory occupied by a UTHashTable's members.
|
||||
*
|
||||
* Note that this does NOT free memory for the UTHashTable pointed to by
|
||||
* |table| itself; if that was allocated on the heap, you must free() it
|
||||
* yourself after calling this. */
|
||||
void destroyHashTable(UTHashTable *table);
|
||||
|
||||
/* Returns memory allocated for a new node. Responsibility for freeing this is
|
||||
* up to the destroyHashTable() macro; this should NOT be freed by the caller.
|
||||
*
|
||||
* This is intended to be used with a HASH_ADD() macro, e.g.:
|
||||
* {%
|
||||
* struct myNode *uttable = utHashTable->uttable;
|
||||
* struct myNode *node = getNewNode(utHashTable);
|
||||
* node->key = 42;
|
||||
* node->value = someValue;
|
||||
* HASH_ADD_INT(uttable, key, node);
|
||||
* utHashTable->uttable = uttable;
|
||||
* %}
|
||||
*
|
||||
* Or, use the UTHASHTABLE_ADD_INT or UTHASHTABLE_ADD_STR macros
|
||||
* for convenience (they are exactly equivalent):
|
||||
* {%
|
||||
* struct myNode *node = getNewNode(utHashTable);
|
||||
* node->key = 42;
|
||||
* node->value = someValue;
|
||||
* UTHASHTABLE_ADD_INT(utHashTable, key, node, struct myNode);
|
||||
* %}
|
||||
*/
|
||||
void *getNewNode(UTHashTable *table);
|
||||
|
||||
#define UTHASHTABLE_ADD_INT(tablePtr, keyName, node, nodeType) \
|
||||
do { \
|
||||
nodeType *uttable = (tablePtr)->uttable; \
|
||||
HASH_ADD_INT(uttable, keyName, node); \
|
||||
(tablePtr)->uttable = uttable; \
|
||||
} while (0)
|
||||
|
||||
#define UTHASHTABLE_ADD_STR(tablePtr, keyName, node, nodeType) \
|
||||
do { \
|
||||
nodeType *uttable = (tablePtr)->uttable; \
|
||||
HASH_ADD_STR(uttable, keyName, node); \
|
||||
(tablePtr)->uttable = uttable; \
|
||||
} while (0)
|
||||
|
||||
#endif /* MMHASHTABLE_H */
|
@ -1,56 +0,0 @@
|
||||
#include "UTHashTable.h"
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* Base struct class (all nodes must contain at least the elements in
|
||||
* this struct). */
|
||||
struct _UTHashNode {
|
||||
UTHashNode_HEAD
|
||||
};
|
||||
|
||||
typedef struct _UTHashNode UTHashNode;
|
||||
|
||||
void initHashTable(UTHashTable *table, size_t initialCount, size_t nodeSize)
|
||||
{
|
||||
assert(table != NULL);
|
||||
assert(nodeSize >= sizeof(UTHashNode));
|
||||
|
||||
table->uttable = NULL; /* Must be set to NULL for uthash. */
|
||||
table->allocedNodeCount = (initialCount == 0) ? 1 : initialCount;
|
||||
table->nodeCount = 0;
|
||||
table->nodeSize = nodeSize;
|
||||
table->nodes = calloc(table->nodeSize, nodeSize * table->allocedNodeCount);
|
||||
}
|
||||
|
||||
void destroyHashTable(UTHashTable *table)
|
||||
{
|
||||
UTHashNode *uttable = table->uttable;
|
||||
UTHashNode *node;
|
||||
|
||||
/* Let uthash do its magic. */
|
||||
while (uttable != NULL) {
|
||||
node = uttable; /* Grab pointer to first item. */
|
||||
HASH_DEL(uttable, node); /* Delete it (table advances to next). */
|
||||
}
|
||||
|
||||
/* Only giant malloc'd block containing each node must be freed. */
|
||||
if (table->nodes != NULL) free(table->nodes);
|
||||
table->uttable = table->nodes = NULL;
|
||||
}
|
||||
|
||||
void *getNewNode(UTHashTable *table)
|
||||
{
|
||||
/* Increment node count, resizing table if necessary. */
|
||||
const size_t newNodeCount = ++(table->nodeCount);
|
||||
if (table->allocedNodeCount < newNodeCount) {
|
||||
do {
|
||||
/* Double size each time to avoid calls to realloc(). */
|
||||
table->allocedNodeCount <<= 1;
|
||||
} while (table->allocedNodeCount < newNodeCount);
|
||||
|
||||
table->nodes = realloc(table->nodes, table->nodeSize *
|
||||
table->allocedNodeCount);
|
||||
}
|
||||
|
||||
return (char *)table->nodes + (table->nodeSize * (table->nodeCount - 1));
|
||||
}
|
109
base/base64.c
109
base/base64.c
@ -1,109 +0,0 @@
|
||||
#include "base64.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* Encoding table as described in RFC1113. */
|
||||
const static uint8_t b64_encode_table[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/* Decoding table. */
|
||||
const static int8_t b64_decode_table[256] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 00-0F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10-1F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 20-2F */
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 30-3F */
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 40-4F */
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 50-5F */
|
||||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 60-6F */
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /* 70-7F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80-8F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 90-9F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* A0-AF */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* B0-BF */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* C0-CF */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* D0-DF */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* E0-EF */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* F0-FF */
|
||||
};
|
||||
|
||||
uint8_t *base64decode(const uint8_t *src, const size_t buflen, size_t *retlen){
|
||||
int8_t digit, lastdigit;
|
||||
size_t i, j;
|
||||
uint8_t *decoded;
|
||||
const size_t maxlen = ((buflen + 3) / 4) * 3;
|
||||
|
||||
/* Sanity check */
|
||||
assert(src != NULL);
|
||||
|
||||
digit = lastdigit = j = 0;
|
||||
decoded = malloc(maxlen + 1);
|
||||
if (decoded == NULL) return NULL;
|
||||
for (i = 0; i < buflen; ++i) {
|
||||
if ((digit = b64_decode_table[src[i]]) != -1) {
|
||||
/* Decode block */
|
||||
switch (i % 4) {
|
||||
case 1:
|
||||
decoded[j++] = ((lastdigit << 2) | ((digit & 0x30) >> 4));
|
||||
break;
|
||||
case 2:
|
||||
decoded[j++] = (((lastdigit & 0xF) << 4) | ((digit & 0x3C) >> 2));
|
||||
break;
|
||||
case 3:
|
||||
decoded[j++] = (((lastdigit & 0x03) << 6) | digit);
|
||||
break;
|
||||
}
|
||||
lastdigit = digit;
|
||||
}
|
||||
}
|
||||
|
||||
if (retlen != NULL) *retlen = j;
|
||||
decoded[j] = '\0';
|
||||
return decoded; /* Must be free()'d by caller */
|
||||
}
|
||||
|
||||
uint8_t *base64encode(const uint8_t *src, const size_t buflen, size_t *retlen){
|
||||
size_t i, j;
|
||||
const size_t maxlen = (((buflen + 3) & ~3)) * 4;
|
||||
uint8_t *encoded = malloc(maxlen + 1);
|
||||
if (encoded == NULL) return NULL;
|
||||
|
||||
/* Sanity check */
|
||||
assert(src != NULL);
|
||||
assert(buflen > 0);
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < buflen + 1; ++i) {
|
||||
/* Encode block */
|
||||
switch (i % 3) {
|
||||
case 0:
|
||||
encoded[j++] = b64_encode_table[src[i] >> 2];
|
||||
encoded[j++] = b64_encode_table[((src[i] & 0x03) << 4) |
|
||||
((src[i + 1] & 0xF0) >> 4)];
|
||||
break;
|
||||
case 1:
|
||||
encoded[j++] = b64_encode_table[((src[i] & 0x0F) << 2) |
|
||||
((src[i + 1] & 0xC0) >> 6)];
|
||||
break;
|
||||
case 2:
|
||||
encoded[j++] = b64_encode_table[(src[i] & 0x3F)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add padding if necessary */
|
||||
if ((j % 4) != 0) {
|
||||
const size_t with_padding = ((j + 3) & ~3); /* Align to 4 bytes */
|
||||
do {
|
||||
encoded[j++] = '=';
|
||||
} while (j < with_padding);
|
||||
}
|
||||
|
||||
assert(j <= maxlen);
|
||||
|
||||
if (retlen != NULL) *retlen = j;
|
||||
encoded[j] = '\0';
|
||||
return encoded; /* Must be free()'d by caller */
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef BASE64_H
|
||||
#define BASE64_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include "ms_stdint.h"
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* Decode a base64 encoded string discarding line breaks and noise.
|
||||
*
|
||||
* Returns a new string to be free()'d by caller, or NULL on error.
|
||||
* Returned string is guaranteed to be NUL-terminated.
|
||||
*
|
||||
* If |retlen| is not NULL, it is set to the length of the returned string
|
||||
* (minus the NUL-terminator) on successful return. */
|
||||
uint8_t *base64decode(const uint8_t *buf, const size_t buflen, size_t *retlen);
|
||||
|
||||
/* Encode a base64 encoded string without line breaks or noise.
|
||||
*
|
||||
* Returns a new string to be free()'d by caller, or NULL on error.
|
||||
* Returned string is guaranteed to be NUL-terminated with the correct padding.
|
||||
*
|
||||
* If |retlen| is not NULL, it is set to the length of the returned string
|
||||
* (minus the NUL-terminator) on successful return. */
|
||||
uint8_t *base64encode(const uint8_t *buf, const size_t buflen, size_t *retlen);
|
||||
|
||||
#endif /* BASE64_H */
|
111
base/base64_c.h
111
base/base64_c.h
@ -1,111 +0,0 @@
|
||||
#include "base64.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* Encoding table as described in RFC1113. */
|
||||
const static uint8_t b64_encode_table[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/* Decoding table. */
|
||||
const static int8_t b64_decode_table[256] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 00-0F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10-1F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 20-2F */
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 30-3F */
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 40-4F */
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 50-5F */
|
||||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 60-6F */
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /* 70-7F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80-8F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 90-9F */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* A0-AF */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* B0-BF */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* C0-CF */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* D0-DF */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* E0-EF */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* F0-FF */
|
||||
};
|
||||
|
||||
uint8_t *base64decode(const uint8_t *src, const size_t buflen, size_t *retlen)
|
||||
{
|
||||
int8_t digit, lastdigit;
|
||||
size_t i, j;
|
||||
uint8_t *decoded;
|
||||
const size_t maxlen = ((buflen + 3) / 4) * 3;
|
||||
|
||||
/* Sanity check */
|
||||
assert(src != NULL);
|
||||
|
||||
digit = lastdigit = j = 0;
|
||||
decoded = malloc(maxlen + 1);
|
||||
if (decoded == NULL) return NULL;
|
||||
for (i = 0; i < buflen; ++i) {
|
||||
if ((digit = b64_decode_table[src[i]]) != -1) {
|
||||
/* Decode block */
|
||||
switch (i % 4) {
|
||||
case 1:
|
||||
decoded[j++] = ((lastdigit << 2) | ((digit & 0x30) >> 4));
|
||||
break;
|
||||
case 2:
|
||||
decoded[j++] = (((lastdigit & 0xF) << 4) | ((digit & 0x3C) >> 2));
|
||||
break;
|
||||
case 3:
|
||||
decoded[j++] = (((lastdigit & 0x03) << 6) | digit);
|
||||
break;
|
||||
}
|
||||
lastdigit = digit;
|
||||
}
|
||||
}
|
||||
|
||||
if (retlen != NULL) *retlen = j;
|
||||
decoded[j] = '\0';
|
||||
return decoded; /* Must be free()'d by caller */
|
||||
}
|
||||
|
||||
uint8_t *base64encode(const uint8_t *src, const size_t buflen, size_t *retlen)
|
||||
{
|
||||
size_t i, j;
|
||||
const size_t maxlen = (((buflen + 3) & ~3)) * 4;
|
||||
uint8_t *encoded = malloc(maxlen + 1);
|
||||
if (encoded == NULL) return NULL;
|
||||
|
||||
/* Sanity check */
|
||||
assert(src != NULL);
|
||||
assert(buflen > 0);
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < buflen + 1; ++i) {
|
||||
/* Encode block */
|
||||
switch (i % 3) {
|
||||
case 0:
|
||||
encoded[j++] = b64_encode_table[src[i] >> 2];
|
||||
encoded[j++] = b64_encode_table[((src[i] & 0x03) << 4) |
|
||||
((src[i + 1] & 0xF0) >> 4)];
|
||||
break;
|
||||
case 1:
|
||||
encoded[j++] = b64_encode_table[((src[i] & 0x0F) << 2) |
|
||||
((src[i + 1] & 0xC0) >> 6)];
|
||||
break;
|
||||
case 2:
|
||||
encoded[j++] = b64_encode_table[(src[i] & 0x3F)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add padding if necessary */
|
||||
if ((j % 4) != 0) {
|
||||
const size_t with_padding = ((j + 3) & ~3); /* Align to 4 bytes */
|
||||
do {
|
||||
encoded[j++] = '=';
|
||||
} while (j < with_padding);
|
||||
}
|
||||
|
||||
assert(j <= maxlen);
|
||||
|
||||
if (retlen != NULL) *retlen = j;
|
||||
encoded[j] = '\0';
|
||||
return encoded; /* Must be free()'d by caller */
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef BMP_IO_H
|
||||
#define BMP_IO_H
|
||||
|
||||
#include "MMBitmap.h"
|
||||
#include "file_io.h"
|
||||
|
||||
enum _BMPReadError {
|
||||
kBMPGenericError = 0,
|
||||
kBMPAccessError,
|
||||
kBMPInvalidKeyError,
|
||||
kBMPUnsupportedHeaderError,
|
||||
kBMPInvalidColorPanesError,
|
||||
kBMPUnsupportedColorDepthError,
|
||||
kBMPUnsupportedCompressionError,
|
||||
kBMPInvalidPixelDataError
|
||||
};
|
||||
|
||||
typedef MMIOError MMBMPReadError;
|
||||
|
||||
/* Returns description of given MMBMPReadError.
|
||||
* Returned string is constant and hence should not be freed. */
|
||||
const char *MMBMPReadErrorString(MMIOError error);
|
||||
|
||||
/* Attempts to read bitmap file at path; returns new MMBitmap on success, or
|
||||
* NULL on error. If |error| is non-NULL, it will be set to the error code
|
||||
* on return.
|
||||
*
|
||||
* Currently supports:
|
||||
* - Uncompressed Windows v3/v4/v5 24-bit or 32-bit BMP.
|
||||
* - OS/2 v1 or v2 24-bit BMP.
|
||||
* - Does NOT yet support: 1-bit, 4-bit, 8-bit, 16-bit, compressed bitmaps,
|
||||
* or PNGs/JPEGs disguised as BMPs (and returns NULL if those are given).
|
||||
*
|
||||
* Responsibility for destroy()'ing returned MMBitmap is left up to caller. */
|
||||
MMBitmapRef newMMBitmapFromBMP(const char *path, MMBMPReadError *error);
|
||||
|
||||
/* Returns a buffer containing the raw BMP file data in Windows v3 BMP format,
|
||||
* ready to be saved to a file. If |len| is not NULL, it will be set to the
|
||||
* number of bytes allocated in the returned buffer.
|
||||
*
|
||||
* Responsibility for free()'ing data is left up to the caller. */
|
||||
uint8_t *createBitmapData(MMBitmapRef bitmap, size_t *len);
|
||||
|
||||
/* Saves bitmap to file in Windows v3 BMP format.
|
||||
* Returns 0 on success, -1 on error. */
|
||||
int saveMMBitmapAsBMP(MMBitmapRef bitmap, const char *path);
|
||||
|
||||
/* Swaps bitmap from Quadrant 1 to Quadran III format, or vice versa
|
||||
* (upside-down Cartesian/PostScript/GL <-> right side up QD/CG raster format).
|
||||
*/
|
||||
void flipBitmapData(void *data, size_t width, size_t height, size_t bytewidth);
|
||||
|
||||
#endif /* BMP_IO_H */
|
441
base/bmp_io_c.h
441
base/bmp_io_c.h
@ -1,441 +0,0 @@
|
||||
#include "bmp_io.h"
|
||||
#include "os.h"
|
||||
#include "endian.h"
|
||||
#include <stdio.h> /* fopen() */
|
||||
#include <string.h> /* memcpy() */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include "ms_stdbool.h"
|
||||
#include "ms_stdint.h"
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 1) /* The following structs should be continguous, so we can
|
||||
* copy them in one read. */
|
||||
/*
|
||||
* Standard, initial BMP Header
|
||||
*/
|
||||
struct BITMAP_FILE_HEADER {
|
||||
uint16_t magic; /* First two byes of the file; should be 0x4D42. */
|
||||
uint32_t fileSize; /* Size of the BMP file in bytes (unreliable). */
|
||||
uint32_t reserved; /* Application-specific. */
|
||||
uint32_t imageOffset; /* Offset to bitmap data. */
|
||||
};
|
||||
|
||||
#define BMP_MAGIC 0x4D42 /* The starting key that marks the file as a BMP. */
|
||||
|
||||
enum _BMP_COMPRESSION {
|
||||
kBMP_RGB = 0, /* No compression. */
|
||||
kBMP_RLE8 = 1, /* Can only be used with 8-bit bitmaps. */
|
||||
kBMP_RLE4 = 2, /* Can only be used with 4-bit bitmaps. */
|
||||
kBMP_BITFIELDS = 3, /* Can only be used with 16/32-bit bitmaps. */
|
||||
kBMP_JPEG = 4, /* Bitmap contains a JPEG image. */
|
||||
kBMP_PNG = 5 /* Bitmap contains a PNG image. */
|
||||
};
|
||||
|
||||
typedef uint32_t BMP_COMPRESSION;
|
||||
|
||||
/*
|
||||
* Windows 3 Header
|
||||
*/
|
||||
struct BITMAP_INFO_HEADER {
|
||||
uint32_t headerSize; /* The size of this header (40 bytes). */
|
||||
int32_t width; /* The bitmap width in pixels. */
|
||||
int32_t height; /* The bitmap height in pixels. */
|
||||
/* (A negative value denotes that the image
|
||||
* is flipped.) */
|
||||
uint16_t colorPlanes; /* The number of color planes; must be 1. */
|
||||
uint16_t bitsPerPixel; /* The color depth of the image (1, 4, 8, 16,
|
||||
* 24, or 32). */
|
||||
BMP_COMPRESSION compression; /* The compression method being used. */
|
||||
uint32_t imageSize; /* Size of the bitmap in bytes (unreliable).*/
|
||||
int32_t xRes; /* The horizontal resolution (unreliable). */
|
||||
int32_t yRes; /* The vertical resolution (unreliable). */
|
||||
uint32_t colorsUsed; /* The number of colors in the color table,
|
||||
* or 0 to default to 2^n. */
|
||||
uint32_t colorsImportant; /* Colors important for displaying bitmap,
|
||||
* or 0 when every color is equally important;
|
||||
* ignored. */
|
||||
};
|
||||
|
||||
/*
|
||||
* OS/2 v1 Header
|
||||
*/
|
||||
struct BITMAP_CORE_HEADER {
|
||||
uint32_t headerSize; /* The size of this header (12 bytes). */
|
||||
uint16_t width; /* The bitmap width in pixels. */
|
||||
uint16_t height; /* The bitmap height in pixels. */
|
||||
uint16_t colorPlanes; /* The number of color planes; must be 1. */
|
||||
uint16_t bitsPerPixel; /* Color depth of the image (1, 4, 8, or 24). */
|
||||
};
|
||||
|
||||
#pragma pack(pop) /* Let the compiler do what it wants now. */
|
||||
|
||||
/* BMP files are always saved in little endian format (x86), so we need to
|
||||
* convert them if we're not on a little endian machine (e.g., ARM & ppc). */
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
|
||||
/* Converts bitmap file header from to and from little endian, if and only if
|
||||
* host is big endian. */
|
||||
static void convertBitmapFileHeader(struct BITMAP_FILE_HEADER *header)
|
||||
{
|
||||
header->magic = swapLittleAndHost16(header->magic);
|
||||
swapLittleAndHost32(header->fileSize);
|
||||
swapLittleAndHost32(header->reserved);
|
||||
swapLittleAndHost32(header->imageOffset);
|
||||
}
|
||||
|
||||
/* Converts bitmap info header from to and from little endian, if and only if
|
||||
* host is big endian. */
|
||||
static void convertBitmapInfoHeader(struct BITMAP_INFO_HEADER *header)
|
||||
{
|
||||
header->headerSize = swapLittleAndHost32(header->headerSize);
|
||||
header->width = swapLittleAndHost32(header->width);
|
||||
header->height = swapLittleAndHost32(header->height);
|
||||
header->colorPlanes = swapLittleAndHost16(header->colorPlanes);
|
||||
header->bitsPerPixel = swapLittleAndHost16(header->bitsPerPixel);
|
||||
header->compression = swapLittleAndHost32(header->compression);
|
||||
header->imageSize = swapLittleAndHost32(header->imageSize);
|
||||
header->xRes = swapLittleAndHost32(header->xRes);
|
||||
header->yRes = swapLittleAndHost32(header->yRes);
|
||||
header->colorsUsed = swapLittleAndHost32(header->colorsUsed);
|
||||
header->colorsImportant = swapLittleAndHost32(header->colorsImportant);
|
||||
}
|
||||
|
||||
#elif __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
/* No conversion necessary if we are already little endian. */
|
||||
#define convertBitmapFileHeader(header)
|
||||
#define convertBitmapInfoHeader(header)
|
||||
#endif
|
||||
|
||||
/* Returns newly alloc'd image data from bitmap file. The current position of
|
||||
* the file must be at the start of the image before calling this. */
|
||||
static uint8_t *readImageData(FILE *fp, size_t width, size_t height,
|
||||
uint8_t bytesPerPixel, size_t bytewidth);
|
||||
|
||||
/* Copys image buffer from |bitmap| to |dest| in BGR format. */
|
||||
static void copyBGRDataFromMMBitmap(MMBitmapRef bitmap, uint8_t *dest);
|
||||
|
||||
const char *MMBMPReadErrorString(MMIOError error)
|
||||
{
|
||||
switch (error) {
|
||||
case kBMPAccessError:
|
||||
return "Could not open file";
|
||||
case kBMPInvalidKeyError:
|
||||
return "Not a BMP file";
|
||||
case kBMPUnsupportedHeaderError:
|
||||
return "Unsupported BMP header";
|
||||
case kBMPInvalidColorPanesError:
|
||||
return "Invalid number of color panes in BMP file";
|
||||
case kBMPUnsupportedColorDepthError:
|
||||
return "Unsupported color depth in BMP file";
|
||||
case kBMPUnsupportedCompressionError:
|
||||
return "Unsupported file compression in BMP file";
|
||||
case kBMPInvalidPixelDataError:
|
||||
return "Could not read BMP pixel data";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MMBitmapRef newMMBitmapFromBMP(const char *path, MMBMPReadError *err)
|
||||
{
|
||||
FILE *fp;
|
||||
struct BITMAP_FILE_HEADER fileHeader = {0}; /* Initialize elements to 0. */
|
||||
struct BITMAP_INFO_HEADER dibHeader = {0};
|
||||
uint32_t headerSize = 0;
|
||||
uint8_t bytesPerPixel;
|
||||
size_t bytewidth;
|
||||
uint8_t *imageBuf;
|
||||
|
||||
if ((fp = fopen(path, "rb")) == NULL) {
|
||||
if (err != NULL) *err = kBMPAccessError;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize error code to generic value. */
|
||||
if (err != NULL) *err = kBMPGenericError;
|
||||
|
||||
if (fread(&fileHeader, sizeof(fileHeader), 1, fp) == 0) goto bail;
|
||||
|
||||
/* Convert from little-endian if it's not already. */
|
||||
convertBitmapFileHeader(&fileHeader);
|
||||
|
||||
/* First two bytes should always be 0x4D42. */
|
||||
if (fileHeader.magic != BMP_MAGIC) {
|
||||
if (err != NULL) *err = kBMPInvalidKeyError;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Get header size. */
|
||||
if (fread(&headerSize, sizeof(headerSize), 1, fp) == 0) goto bail;
|
||||
headerSize = swapLittleAndHost32(headerSize);
|
||||
|
||||
/* Back up before reading header. */
|
||||
if (fseek(fp, -(long)sizeof(headerSize), SEEK_CUR) < 0) goto bail;
|
||||
|
||||
if (headerSize == 12) { /* OS/2 v1 header */
|
||||
struct BITMAP_CORE_HEADER coreHeader = {0};
|
||||
if (fread(&coreHeader, sizeof(coreHeader), 1, fp) == 0) goto bail;
|
||||
|
||||
dibHeader.width = coreHeader.width;
|
||||
dibHeader.height = coreHeader.height;
|
||||
dibHeader.colorPlanes = coreHeader.colorPlanes;
|
||||
dibHeader.bitsPerPixel = coreHeader.bitsPerPixel;
|
||||
} else if (headerSize == 40 || headerSize == 108 || headerSize == 124) {
|
||||
/* Windows v3/v4/v5 header */
|
||||
/* Read only the common part (v3) and skip over the rest. */
|
||||
if (fread(&dibHeader, sizeof(dibHeader), 1, fp) == 0) goto bail;
|
||||
} else {
|
||||
if (err != NULL) *err = kBMPUnsupportedHeaderError;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
convertBitmapInfoHeader(&dibHeader);
|
||||
|
||||
if (dibHeader.colorPlanes != 1) {
|
||||
if (err != NULL) *err = kBMPInvalidColorPanesError;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Currently only 24-bit and 32-bit are supported. */
|
||||
if (dibHeader.bitsPerPixel != 24 && dibHeader.bitsPerPixel != 32) {
|
||||
if (err != NULL) *err = kBMPUnsupportedColorDepthError;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (dibHeader.compression != kBMP_RGB) {
|
||||
if (err != NULL) *err = kBMPUnsupportedCompressionError;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* This can happen because we don't fully parse Windows v4/v5 headers. */
|
||||
if (ftell(fp) != (long)fileHeader.imageOffset) {
|
||||
fseek(fp, fileHeader.imageOffset, SEEK_SET);
|
||||
}
|
||||
|
||||
/* Get bytes per row, including padding. */
|
||||
bytesPerPixel = dibHeader.bitsPerPixel / 8;
|
||||
bytewidth = ADD_PADDING(dibHeader.width * bytesPerPixel);
|
||||
|
||||
imageBuf = readImageData(fp, dibHeader.width, abs(dibHeader.height),
|
||||
bytesPerPixel, bytewidth);
|
||||
fclose(fp);
|
||||
|
||||
if (imageBuf == NULL) {
|
||||
if (err != NULL) *err = kBMPInvalidPixelDataError;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* A negative height indicates that the image is flipped.
|
||||
*
|
||||
* We store our bitmaps as "flipped" according to the BMP format; i.e., (0, 0)
|
||||
* is the top left, not bottom left. So we only need to flip the bitmap if
|
||||
* the height is NOT negative. */
|
||||
if (dibHeader.height < 0) {
|
||||
dibHeader.height = -dibHeader.height;
|
||||
} else {
|
||||
flipBitmapData(imageBuf, dibHeader.width, dibHeader.height, bytewidth);
|
||||
}
|
||||
|
||||
return createMMBitmap(imageBuf, dibHeader.width, dibHeader.height,
|
||||
bytewidth, (uint8_t)dibHeader.bitsPerPixel,
|
||||
bytesPerPixel);
|
||||
|
||||
bail:
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t *createBitmapData(MMBitmapRef bitmap, size_t *len)
|
||||
{
|
||||
/* BMP files are always aligned to 4 bytes. */
|
||||
const size_t bytewidth = ((bitmap->width * bitmap->bytesPerPixel) + 3) & ~3;
|
||||
|
||||
const size_t imageSize = bytewidth * bitmap->height;
|
||||
struct BITMAP_FILE_HEADER *fileHeader;
|
||||
struct BITMAP_INFO_HEADER *dibHeader;
|
||||
|
||||
/* Should always be 54. */
|
||||
const size_t imageOffset = sizeof(*fileHeader) + sizeof(*dibHeader);
|
||||
uint8_t *data;
|
||||
const size_t dataLen = imageOffset + imageSize;
|
||||
|
||||
data = calloc(1, dataLen);
|
||||
if (data == NULL) return NULL;
|
||||
|
||||
/* Save top header. */
|
||||
fileHeader = (struct BITMAP_FILE_HEADER *)data;
|
||||
fileHeader->magic = BMP_MAGIC;
|
||||
fileHeader->fileSize = (uint32_t)(sizeof(*dibHeader) + imageSize);
|
||||
fileHeader->imageOffset = (uint32_t)imageOffset;
|
||||
|
||||
/* BMP files are always stored as little-endian, so we need to convert back
|
||||
* if necessary. */
|
||||
convertBitmapFileHeader(fileHeader);
|
||||
|
||||
/* Copy Windows v3 header. */
|
||||
dibHeader = (struct BITMAP_INFO_HEADER *)(data + sizeof(*fileHeader));
|
||||
dibHeader->headerSize = sizeof(*dibHeader); /* Should always be 40. */
|
||||
dibHeader->width = (int32_t)bitmap->width;
|
||||
dibHeader->height = -(int32_t)bitmap->height; /* Our bitmaps are "flipped". */
|
||||
dibHeader->colorPlanes = 1;
|
||||
dibHeader->bitsPerPixel = bitmap->bitsPerPixel;
|
||||
dibHeader->compression = kBMP_RGB; /* Don't save with compression. */
|
||||
dibHeader->imageSize = (uint32_t)imageSize;
|
||||
|
||||
convertBitmapInfoHeader(dibHeader);
|
||||
|
||||
/* Lastly, copy the pixel data. */
|
||||
copyBGRDataFromMMBitmap(bitmap, data + imageOffset);
|
||||
|
||||
if (len != NULL) *len = dataLen;
|
||||
return data;
|
||||
}
|
||||
|
||||
int saveMMBitmapAsBMP(MMBitmapRef bitmap, const char *path)
|
||||
{
|
||||
FILE *fp;
|
||||
size_t dataLen;
|
||||
uint8_t *data;
|
||||
|
||||
if ((fp = fopen(path, "wb")) == NULL) return -1;
|
||||
|
||||
if ((data = createBitmapData(bitmap, &dataLen)) == NULL) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fwrite(data, dataLen, 1, fp) == 0) {
|
||||
free(data);
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(data);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *saveMMBitmapAsBytes(MMBitmapRef bitmap, size_t *dataLen)
|
||||
{
|
||||
uint8_t *data;
|
||||
if ((data = createBitmapData(bitmap, dataLen)) == NULL) {
|
||||
*dataLen = -1;
|
||||
return NULL;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static uint8_t *readImageData(FILE *fp, size_t width, size_t height,
|
||||
uint8_t bytesPerPixel, size_t bytewidth)
|
||||
{
|
||||
size_t imageSize = bytewidth * height;
|
||||
uint8_t *imageBuf = calloc(1, imageSize);
|
||||
|
||||
if (MMRGB_IS_BGR && (bytewidth % 4) == 0) { /* No conversion needed. */
|
||||
if (fread(imageBuf, imageSize, 1, fp) == 0) {
|
||||
free(imageBuf);
|
||||
return NULL;
|
||||
}
|
||||
} else { /* Convert from BGR with 4-byte alignment. */
|
||||
uint8_t *row = malloc(bytewidth);
|
||||
size_t y;
|
||||
const size_t bmp_bytewidth = (width * bytesPerPixel + 3) & ~3;
|
||||
|
||||
if (row == NULL) return NULL;
|
||||
assert(bmp_bytewidth <= bytewidth);
|
||||
|
||||
/* Read image data row by row. */
|
||||
for (y = 0; y < height; ++y) {
|
||||
const size_t rowOffset = y * bytewidth;
|
||||
size_t x;
|
||||
uint8_t *rowptr = row;
|
||||
if (fread(row, bmp_bytewidth, 1, fp) == 0) {
|
||||
free(imageBuf);
|
||||
free(row);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (x = 0; x < width; ++x) {
|
||||
const size_t colOffset = x * bytesPerPixel;
|
||||
MMRGBColor *color = (MMRGBColor *)(imageBuf +
|
||||
rowOffset + colOffset);
|
||||
|
||||
/* BMP files are stored in BGR format. */
|
||||
color->blue = rowptr[0];
|
||||
color->green = rowptr[1];
|
||||
color->red = rowptr[2];
|
||||
rowptr += bytesPerPixel;
|
||||
}
|
||||
}
|
||||
|
||||
free(row);
|
||||
}
|
||||
|
||||
return imageBuf;
|
||||
}
|
||||
|
||||
static void copyBGRDataFromMMBitmap(MMBitmapRef bitmap, uint8_t *dest)
|
||||
{
|
||||
if (MMRGB_IS_BGR && (bitmap->bytewidth % 4) == 0) { /* No conversion needed. */
|
||||
memcpy(dest, bitmap->imageBuffer, bitmap->bytewidth * bitmap->height);
|
||||
} else { /* Convert to RGB with other-than-4-byte alignment. */
|
||||
const size_t bytewidth = (bitmap->width * bitmap->bytesPerPixel + 3) & ~3;
|
||||
size_t y;
|
||||
|
||||
/* Copy image data row by row. */
|
||||
for (y = 0; y < bitmap->height; ++y) {
|
||||
uint8_t *rowptr = dest + (y * bytewidth);
|
||||
size_t x;
|
||||
for (x = 0; x < bitmap->width; ++x) {
|
||||
MMRGBColor *color = MMRGBColorRefAtPoint(bitmap, x, y);
|
||||
|
||||
/* BMP files are stored in BGR format. */
|
||||
rowptr[0] = color->blue;
|
||||
rowptr[1] = color->green;
|
||||
rowptr[2] = color->red;
|
||||
|
||||
rowptr += bitmap->bytesPerPixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform an in-place swap from Quadrant 1 to Quadrant III format (upside-down
|
||||
* PostScript/GL to right side up QD/CG raster format) We do this in-place,
|
||||
* which requires more copying, but will touch only half the pages.
|
||||
*
|
||||
* This is blatantly copied from Apple's glGrab example code. */
|
||||
void flipBitmapData(void *data, size_t width, size_t height, size_t bytewidth)
|
||||
{
|
||||
size_t top, bottom;
|
||||
void *topP;
|
||||
void *bottomP;
|
||||
void *tempbuf;
|
||||
|
||||
if (height <= 1) return; /* No flipping necessary if height is <= 1. */
|
||||
|
||||
top = 0;
|
||||
bottom = height - 1;
|
||||
tempbuf = malloc(bytewidth);
|
||||
if (tempbuf == NULL) return;
|
||||
|
||||
while (top < bottom) {
|
||||
topP = (void *)((top * bytewidth) + (intptr_t)data);
|
||||
bottomP = (void *)((bottom * bytewidth) + (intptr_t)data);
|
||||
|
||||
/* Save and swap scanlines.
|
||||
* Does a simple in-place exchange with a temp buffer. */
|
||||
memcpy(tempbuf, topP, bytewidth);
|
||||
memcpy(topP, bottomP, bytewidth);
|
||||
memcpy(bottomP, tempbuf, bytewidth);
|
||||
|
||||
++top;
|
||||
--bottom;
|
||||
}
|
||||
free(tempbuf);
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef COLOR_FIND_H
|
||||
#define COLOR_FIND_H
|
||||
|
||||
#include "MMBitmap.h"
|
||||
#include "MMPointArray.h"
|
||||
|
||||
/* Convenience wrapper around findColorInRect(), where |rect| is the bounds of
|
||||
* the image. */
|
||||
#define findColorInImage(image, color, pointPtr, tolerance) \
|
||||
findColorInRect(image, color, pointPtr, MMBitmapGetBounds(image), tolerance)
|
||||
|
||||
/* Attempt to find a pixel with the given color in |image| inside |rect|.
|
||||
* Returns 0 on success, non-zero on failure. If the color was found and
|
||||
* |point| is not NULL, it will be initialized to the (x, y) coordinates the
|
||||
* RGB color.
|
||||
*
|
||||
* |tolerance| should be in the range 0.0f - 1.0f, denoting how closely the
|
||||
* colors need to match, with 0 being exact and 1 being any. */
|
||||
int findColorInRect(MMBitmapRef image, MMRGBHex color, MMPoint *point,
|
||||
MMRect rect, float tolerance);
|
||||
|
||||
/* Convenience wrapper around findAllRGBInRect(), where |rect| is the bounds of
|
||||
* the image. */
|
||||
#define findAllColorInImage(image, color, tolerance) \
|
||||
findAllColorInRect(image, color, MMBitmapGetBounds(image), tolerance)
|
||||
|
||||
/* Returns MMPointArray of all pixels of given color in |image| inside of
|
||||
* |rect|. Note that an array is returned regardless of whether the color was
|
||||
* found; check array->count to see if it actually was.
|
||||
*
|
||||
* Responsibility for freeing the MMPointArray with destroyMMPointArray() is
|
||||
* given to the caller.
|
||||
*
|
||||
* |tolerance| should be in the range 0.0f - 1.0f, denoting how closely the
|
||||
* colors need to match, with 0 being exact and 1 being any. */
|
||||
MMPointArrayRef findAllColorInRect(MMBitmapRef image, MMRGBHex color,
|
||||
MMRect rect, float tolerance);
|
||||
|
||||
/* Convenience wrapper around countOfColorsInRect, where |rect| is the bounds
|
||||
* of the image. */
|
||||
#define countOfColorsInImage(image, color, tolerance) \
|
||||
countOfColorsInRect(image, color, MMBitmapGetBounds(image), tolerance)
|
||||
|
||||
/* Returns the count of the given color in |rect| inside of |image|. */
|
||||
size_t countOfColorsInRect(MMBitmapRef image, MMRGBHex color, MMRect rect,
|
||||
float tolerance);
|
||||
|
||||
#endif /* COLOR_FIND_H */
|
@ -1,58 +0,0 @@
|
||||
#include "color_find.h"
|
||||
// #include "../screen/screen_init.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Abstracted, general function to avoid repeated code. */
|
||||
static int findColorInRectAt(MMBitmapRef image, MMRGBHex color, MMPoint *point,
|
||||
MMRect rect, float tolerance, MMPoint startPoint)
|
||||
{
|
||||
MMPoint scan = startPoint;
|
||||
if (!MMBitmapRectInBounds(image, rect)) return -1;
|
||||
|
||||
for (; scan.y < rect.size.height; ++scan.y) {
|
||||
for (; scan.x < rect.size.width; ++scan.x) {
|
||||
MMRGBHex found = MMRGBHexAtPoint(image, scan.x, scan.y);
|
||||
if (MMRGBHexSimilarToColor(color, found, tolerance)) {
|
||||
if (point != NULL) *point = scan;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
scan.x = rect.origin.x;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int findColorInRect(MMBitmapRef image, MMRGBHex color,
|
||||
MMPoint *point, MMRect rect, float tolerance)
|
||||
{
|
||||
return findColorInRectAt(image, color, point, rect, tolerance, rect.origin);
|
||||
}
|
||||
|
||||
MMPointArrayRef findAllColorInRect(MMBitmapRef image, MMRGBHex color,
|
||||
MMRect rect, float tolerance)
|
||||
{
|
||||
MMPointArrayRef pointArray = createMMPointArray(0);
|
||||
MMPoint point = MMPointZero;
|
||||
|
||||
while (findColorInRectAt(image, color, &point, rect, tolerance, point) == 0) {
|
||||
MMPointArrayAppendPoint(pointArray, point);
|
||||
ITER_NEXT_POINT(point, rect.size.width, rect.origin.x);
|
||||
}
|
||||
|
||||
return pointArray;
|
||||
}
|
||||
|
||||
size_t countOfColorsInRect(MMBitmapRef image, MMRGBHex color, MMRect rect,
|
||||
float tolerance)
|
||||
{
|
||||
size_t count = 0;
|
||||
MMPoint point = MMPointZero;
|
||||
|
||||
while (findColorInRectAt(image, color, &point, rect, tolerance, point) == 0) {
|
||||
ITER_NEXT_POINT(point, rect.size.width, rect.origin.x);
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef FILE_IO_H
|
||||
#define FILE_IO_H
|
||||
|
||||
#include "MMBitmap.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
enum _MMImageType {
|
||||
kInvalidImageType = 0,
|
||||
kPNGImageType,
|
||||
kBMPImageType /* Currently only PNG and BMP are supported. */
|
||||
};
|
||||
|
||||
typedef uint16_t MMImageType;
|
||||
|
||||
enum _MMIOError {
|
||||
kMMIOUnsupportedTypeError = 0
|
||||
};
|
||||
|
||||
typedef uint16_t MMIOError;
|
||||
|
||||
const char *getExtension(const char *fname, size_t len);
|
||||
|
||||
/* Returns best guess at the MMImageType based on a file extension, or
|
||||
* |kInvalidImageType| if no matching type was found. */
|
||||
MMImageType imageTypeFromExtension(const char *ext);
|
||||
|
||||
/* Attempts to parse the file of the given type at the given path.
|
||||
* |filepath| is an ASCII string describing the absolute POSIX path.
|
||||
* Returns new bitmap (to be destroy()'d by caller) on success, NULL on error.
|
||||
* If |error| is non-NULL, it will be set to the error code on return.
|
||||
*/
|
||||
MMBitmapRef newMMBitmapFromFile(const char *path, MMImageType type, MMIOError *err);
|
||||
|
||||
/* Saves |bitmap| to a file of the given type at the given path.
|
||||
* |filepath| is an ASCII string describing the absolute POSIX path.
|
||||
* Returns 0 on success, -1 on error. */
|
||||
int saveMMBitmapToFile(MMBitmapRef bitmap, const char *path, MMImageType type);
|
||||
|
||||
/* Returns description of given error code.
|
||||
* Returned string is constant and hence should not be freed. */
|
||||
const char *MMIOErrorString(MMImageType type, MMIOError error);
|
||||
|
||||
#endif /* IO_H */
|
@ -1,70 +0,0 @@
|
||||
#include "file_io.h"
|
||||
// #include "os.h"
|
||||
#include "bmp_io_c.h"
|
||||
#include "png_io_c.h"
|
||||
#include <stdio.h> /* For fputs() */
|
||||
#include <string.h> /* For strcmp() */
|
||||
#include <ctype.h> /* For tolower() */
|
||||
|
||||
const char *getExtension(const char *fname, size_t len){
|
||||
if (fname == NULL || len <= 0) return NULL;
|
||||
|
||||
while (--len > 0 && fname[len] != '.' && fname[len] != '\0')
|
||||
;
|
||||
|
||||
return fname + len + 1;
|
||||
}
|
||||
|
||||
MMImageType imageTypeFromExtension(const char *extension){
|
||||
char ext[4];
|
||||
const size_t maxlen = sizeof(ext) / sizeof(ext[0]);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; extension[i] != '\0'; ++i) {
|
||||
if (i >= maxlen) return kInvalidImageType;
|
||||
ext[i] = tolower(extension[i]);
|
||||
}
|
||||
ext[i] = '\0';
|
||||
|
||||
if (strcmp(ext, "png") == 0) {
|
||||
return kPNGImageType;
|
||||
} else if (strcmp(ext, "bmp") == 0) {
|
||||
return kBMPImageType;
|
||||
} else {
|
||||
return kInvalidImageType;
|
||||
}
|
||||
}
|
||||
|
||||
MMBitmapRef newMMBitmapFromFile(const char *path, MMImageType type, MMIOError *err){
|
||||
switch (type) {
|
||||
case kBMPImageType:
|
||||
return newMMBitmapFromBMP(path, err);
|
||||
case kPNGImageType:
|
||||
return newMMBitmapFromPNG(path, err);
|
||||
default:
|
||||
if (err != NULL) *err = kMMIOUnsupportedTypeError;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int saveMMBitmapToFile(MMBitmapRef bitmap, const char *path, MMImageType type){
|
||||
switch (type) {
|
||||
case kBMPImageType:
|
||||
return saveMMBitmapAsBMP(bitmap, path);
|
||||
case kPNGImageType:
|
||||
return saveMMBitmapAsPNG(bitmap, path);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
const char *MMIOErrorString(MMImageType type, MMIOError error){
|
||||
switch (type) {
|
||||
case kBMPImageType:
|
||||
return MMBMPReadErrorString(error);
|
||||
case kPNGImageType:
|
||||
return MMPNGReadErrorString(error);
|
||||
default:
|
||||
return "Unsupported image type";
|
||||
}
|
||||
}
|
70
base/io.c
70
base/io.c
@ -1,70 +0,0 @@
|
||||
#include "file_io.h"
|
||||
#include "os.h"
|
||||
#include "bmp_io.h"
|
||||
#include "png_io.h"
|
||||
#include <stdio.h> /* For fputs() */
|
||||
#include <string.h> /* For strcmp() */
|
||||
#include <ctype.h> /* For tolower() */
|
||||
|
||||
const char *getExtension(const char *fname, size_t len){
|
||||
if (fname == NULL || len <= 0) return NULL;
|
||||
|
||||
while (--len > 0 && fname[len] != '.' && fname[len] != '\0')
|
||||
;
|
||||
|
||||
return fname + len + 1;
|
||||
}
|
||||
|
||||
MMImageType imageTypeFromExtension(const char *extension){
|
||||
char ext[4];
|
||||
const size_t maxlen = sizeof(ext) / sizeof(ext[0]);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; extension[i] != '\0'; ++i) {
|
||||
if (i >= maxlen) return kInvalidImageType;
|
||||
ext[i] = tolower(extension[i]);
|
||||
}
|
||||
ext[i] = '\0';
|
||||
|
||||
if (strcmp(ext, "png") == 0) {
|
||||
return kPNGImageType;
|
||||
} else if (strcmp(ext, "bmp") == 0) {
|
||||
return kBMPImageType;
|
||||
} else {
|
||||
return kInvalidImageType;
|
||||
}
|
||||
}
|
||||
|
||||
MMBitmapRef newMMBitmapFromFile(const char *path, MMImageType type, MMIOError *err){
|
||||
switch (type) {
|
||||
case kBMPImageType:
|
||||
return newMMBitmapFromBMP(path, err);
|
||||
case kPNGImageType:
|
||||
return newMMBitmapFromPNG(path, err);
|
||||
default:
|
||||
if (err != NULL) *err = kMMIOUnsupportedTypeError;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int saveMMBitmapToFile(MMBitmapRef bitmap, const char *path, MMImageType type){
|
||||
switch (type) {
|
||||
case kBMPImageType:
|
||||
return saveMMBitmapAsBMP(bitmap, path);
|
||||
case kPNGImageType:
|
||||
return saveMMBitmapAsPNG(bitmap, path);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
const char *MMIOErrorString(MMImageType type, MMIOError error){
|
||||
switch (type) {
|
||||
case kBMPImageType:
|
||||
return MMBMPReadErrorString(error);
|
||||
case kPNGImageType:
|
||||
return MMPNGReadErrorString(error);
|
||||
default:
|
||||
return "Unsupported image type";
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef PASTEBOARD_H
|
||||
#define PASTEBOARD_H
|
||||
|
||||
#include "MMBitmap.h"
|
||||
#include "file_io.h"
|
||||
|
||||
enum _MMBitmapPasteError {
|
||||
kMMPasteNoError = 0,
|
||||
kMMPasteGenericError,
|
||||
kMMPasteOpenError,
|
||||
kMMPasteClearError,
|
||||
kMMPasteDataError,
|
||||
kMMPastePasteError,
|
||||
kMMPasteUnsupportedError
|
||||
};
|
||||
|
||||
typedef MMIOError MMPasteError;
|
||||
|
||||
/* Copies |bitmap| to the pasteboard as a PNG.
|
||||
* Returns 0 on success, non-zero on error. */
|
||||
MMPasteError copyMMBitmapToPasteboard(MMBitmapRef bitmap);
|
||||
|
||||
/* Returns description of given MMPasteError.
|
||||
* Returned string is constant and hence should not be freed. */
|
||||
const char *MMPasteErrorString(MMPasteError error);
|
||||
|
||||
#endif /* PASTEBOARD_H */
|
@ -1,106 +0,0 @@
|
||||
#include "pasteboard.h"
|
||||
#include "os.h"
|
||||
|
||||
#if defined(IS_MACOSX)
|
||||
#include "png_io.h"
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#elif defined(IS_WINDOWS)
|
||||
#include "bmp_io.h"
|
||||
#endif
|
||||
|
||||
MMPasteError copyMMBitmapToPasteboard(MMBitmapRef bitmap)
|
||||
{
|
||||
#if defined(IS_MACOSX)
|
||||
PasteboardRef clipboard;
|
||||
|
||||
size_t len;
|
||||
uint8_t *pngbuf;
|
||||
CFDataRef data;
|
||||
OSStatus err;
|
||||
|
||||
if (PasteboardCreate(kPasteboardClipboard, &clipboard) != noErr) {
|
||||
return kMMPasteOpenError;
|
||||
}
|
||||
|
||||
if (PasteboardClear(clipboard) != noErr) {
|
||||
CFRelease(clipboard);
|
||||
return kMMPasteClearError;
|
||||
}
|
||||
|
||||
pngbuf = createPNGData(bitmap, &len);
|
||||
if (pngbuf == NULL) {
|
||||
CFRelease(clipboard);
|
||||
return kMMPasteDataError;
|
||||
}
|
||||
|
||||
data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, pngbuf, len,
|
||||
kCFAllocatorNull);
|
||||
if (data == NULL) {
|
||||
CFRelease(clipboard);
|
||||
free(pngbuf);
|
||||
return kMMPasteDataError;
|
||||
}
|
||||
|
||||
err = PasteboardPutItemFlavor(clipboard, bitmap, kUTTypePNG, data, 0);
|
||||
CFRelease(data);
|
||||
CFRelease(clipboard);
|
||||
free(pngbuf);
|
||||
return (err == noErr) ? kMMPasteNoError : kMMPastePasteError;
|
||||
#elif defined(IS_WINDOWS)
|
||||
MMPasteError ret = kMMPasteNoError;
|
||||
uint8_t *bmpData;
|
||||
size_t len;
|
||||
HGLOBAL handle;
|
||||
|
||||
if (!OpenClipboard(NULL)) return kMMPasteOpenError;
|
||||
if (!EmptyClipboard()) return kMMPasteClearError;
|
||||
|
||||
bmpData = createBitmapData(bitmap, &len);
|
||||
if (bmpData == NULL) return kMMPasteDataError;
|
||||
|
||||
/* CF_DIB does not include the BITMAPFILEHEADER struct (and displays a
|
||||
* cryptic error if it is included). */
|
||||
len -= sizeof(BITMAPFILEHEADER);
|
||||
|
||||
/* SetClipboardData() needs a "handle", not just a buffer, so we have to
|
||||
* allocate one with GlobalAlloc(). */
|
||||
if ((handle = GlobalAlloc(GMEM_MOVEABLE, len)) == NULL) {
|
||||
CloseClipboard();
|
||||
free(bmpData);
|
||||
return kMMPasteDataError;
|
||||
}
|
||||
|
||||
memcpy(GlobalLock(handle), bmpData + sizeof(BITMAPFILEHEADER), len);
|
||||
GlobalUnlock(handle);
|
||||
free(bmpData);
|
||||
|
||||
if (SetClipboardData(CF_DIB, handle) == NULL) {
|
||||
ret = kMMPastePasteError;
|
||||
}
|
||||
|
||||
CloseClipboard();
|
||||
GlobalFree(handle);
|
||||
return ret;
|
||||
#elif defined(USE_X11)
|
||||
/* TODO (X11's clipboard is _weird_.) */
|
||||
return kMMPasteUnsupportedError;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *MMPasteErrorString(MMPasteError err)
|
||||
{
|
||||
switch (err) {
|
||||
case kMMPasteOpenError:
|
||||
return "Could not open pasteboard";
|
||||
case kMMPasteClearError:
|
||||
return "Could not clear pasteboard";
|
||||
case kMMPasteDataError:
|
||||
return "Could not create image data from bitmap";
|
||||
case kMMPastePasteError:
|
||||
return "Could not paste data";
|
||||
case kMMPasteUnsupportedError:
|
||||
return "Unsupported platform";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef PNG_IO_H
|
||||
#define PNG_IO_H
|
||||
|
||||
// #include "MMBitmap_c.h"
|
||||
// #include "file_io_c.h"
|
||||
|
||||
enum _PNGReadError {
|
||||
kPNGGenericError = 0,
|
||||
kPNGReadError,
|
||||
kPNGAccessError,
|
||||
kPNGInvalidHeaderError
|
||||
};
|
||||
|
||||
typedef MMIOError MMPNGReadError;
|
||||
|
||||
/* Returns description of given MMPNGReadError.
|
||||
* Returned string is constant and hence should not be freed. */
|
||||
const char *MMPNGReadErrorString(MMIOError error);
|
||||
|
||||
/* Attempts to read PNG file at path; returns new MMBitmap on success, or
|
||||
* NULL on error. If |error| is non-NULL, it will be set to the error code
|
||||
* on return.
|
||||
* Responsibility for destroy()'ing returned MMBitmap is left up to caller. */
|
||||
MMBitmapRef newMMBitmapFromPNG(const char *path, MMPNGReadError *error);
|
||||
|
||||
/* Attempts to write PNG at path; returns 0 on success, -1 on error. */
|
||||
int saveMMBitmapAsPNG(MMBitmapRef bitmap, const char *path);
|
||||
|
||||
/* Returns a buffer containing the raw PNG file data, ready to be saved to a
|
||||
* file. |len| will be set to the number of bytes allocated in the returned
|
||||
* buffer (it cannot be NULL).
|
||||
*
|
||||
* Responsibility for free()'ing data is left up to the caller. */
|
||||
uint8_t *createPNGData(MMBitmapRef bitmap, size_t *len);
|
||||
|
||||
#endif /* PNG_IO_H */
|
346
base/png_io_c.h
346
base/png_io_c.h
@ -1,346 +0,0 @@
|
||||
#include "png_io.h"
|
||||
#include "os.h"
|
||||
// #include "libpng/png.c"
|
||||
#if defined(IS_MACOSX)
|
||||
#include "../cdeps/mac/png.h"
|
||||
#elif defined(USE_X11)
|
||||
#include <png.h>
|
||||
#elif defined(IS_WINDOWS)
|
||||
#include "../cdeps/win/png.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* fopen() */
|
||||
#include <stdlib.h> /* malloc/realloc */
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include "ms_stdint.h"
|
||||
#include "ms_stdbool.h"
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
const char *MMPNGReadErrorString(MMIOError error)
|
||||
{
|
||||
switch (error) {
|
||||
case kPNGAccessError:
|
||||
return "Could not open file";
|
||||
case kPNGReadError:
|
||||
return "Could not read file";
|
||||
case kPNGInvalidHeaderError:
|
||||
return "Not a PNG file";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MMBitmapRef newMMBitmapFromPNG(const char *path, MMPNGReadError *err)
|
||||
{
|
||||
FILE *fp;
|
||||
uint8_t header[8];
|
||||
png_struct *png_ptr = NULL;
|
||||
png_info *info_ptr = NULL;
|
||||
png_byte bit_depth, color_type;
|
||||
uint8_t *row, *bitmapData;
|
||||
uint8_t bytesPerPixel;
|
||||
png_uint_32 width, height, y;
|
||||
uint32_t bytewidth;
|
||||
|
||||
if ((fp = fopen(path, "rb")) == NULL) {
|
||||
if (err != NULL) *err = kPNGAccessError;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize error code to generic value. */
|
||||
if (err != NULL) *err = kPNGGenericError;
|
||||
|
||||
/* Validate the PNG. */
|
||||
if (fread(header, 1, sizeof header, fp) == 0) {
|
||||
if (err != NULL) *err = kPNGReadError;
|
||||
goto bail;
|
||||
} else if (png_sig_cmp(header, 0, sizeof(header)) != 0) {
|
||||
if (err != NULL) *err = kPNGInvalidHeaderError;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (png_ptr == NULL) goto bail;
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL) goto bail;
|
||||
|
||||
/* Set up error handling. */
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
/* Skip past the header. */
|
||||
png_set_sig_bytes(png_ptr, sizeof header);
|
||||
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
/* Convert different image types to common type to be read. */
|
||||
bit_depth = png_get_bit_depth(png_ptr, info_ptr);
|
||||
color_type = png_get_color_type(png_ptr, info_ptr);
|
||||
|
||||
/* Convert color palettes to RGB. */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
png_set_palette_to_rgb(png_ptr);
|
||||
}
|
||||
|
||||
/* Convert PNG to bit depth of 8. */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
|
||||
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
||||
} else if (bit_depth == 16) {
|
||||
png_set_strip_16(png_ptr);
|
||||
}
|
||||
|
||||
/* Convert transparency chunk to alpha channel. */
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
|
||||
png_set_tRNS_to_alpha(png_ptr);
|
||||
}
|
||||
|
||||
/* Convert gray images to RGB. */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
}
|
||||
|
||||
/* Ignore alpha for now. */
|
||||
if (color_type & PNG_COLOR_MASK_ALPHA) {
|
||||
png_set_strip_alpha(png_ptr);
|
||||
}
|
||||
|
||||
/* Get image attributes. */
|
||||
width = png_get_image_width(png_ptr, info_ptr);
|
||||
height = png_get_image_height(png_ptr, info_ptr);
|
||||
bytesPerPixel = 3; /* All images decompress to this size. */
|
||||
bytewidth = ADD_PADDING(width * bytesPerPixel); /* Align width. */
|
||||
|
||||
/* Decompress the PNG row by row. */
|
||||
bitmapData = calloc(1, bytewidth * height);
|
||||
row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
|
||||
if (bitmapData == NULL || row == NULL) goto bail;
|
||||
for (y = 0; y < height; ++y) {
|
||||
png_uint_32 x;
|
||||
const uint32_t rowOffset = y * bytewidth;
|
||||
uint8_t *rowptr = row;
|
||||
png_read_row(png_ptr, (png_byte *)row, NULL);
|
||||
|
||||
for (x = 0; x < width; ++x) {
|
||||
const uint32_t colOffset = x * bytesPerPixel;
|
||||
MMRGBColor *color = (MMRGBColor *)(bitmapData + rowOffset + colOffset);
|
||||
color->red = *rowptr++;
|
||||
color->green = *rowptr++;
|
||||
color->blue = *rowptr++;
|
||||
}
|
||||
}
|
||||
free(row);
|
||||
|
||||
/* Finish reading. */
|
||||
png_read_end(png_ptr, NULL);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
fclose(fp);
|
||||
|
||||
return createMMBitmap(bitmapData, width, height,
|
||||
bytewidth, bytesPerPixel * 8, bytesPerPixel);
|
||||
|
||||
bail:
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct _PNGWriteInfo {
|
||||
png_struct *png_ptr;
|
||||
png_info *info_ptr;
|
||||
png_byte **row_pointers;
|
||||
size_t row_count;
|
||||
bool free_row_pointers;
|
||||
};
|
||||
|
||||
typedef struct _PNGWriteInfo PNGWriteInfo;
|
||||
typedef PNGWriteInfo *PNGWriteInfoRef;
|
||||
|
||||
/* Returns pointer to PNGWriteInfo struct containing data ready to be used with
|
||||
* functions such as png_write_png().
|
||||
*
|
||||
* It is the caller's responsibility to destroy() the returned structure with
|
||||
* destroyPNGWriteInfo(). */
|
||||
static PNGWriteInfoRef createPNGWriteInfo(MMBitmapRef bitmap)
|
||||
{
|
||||
PNGWriteInfoRef info = malloc(sizeof(PNGWriteInfo));
|
||||
png_uint_32 y;
|
||||
|
||||
if (info == NULL) return NULL;
|
||||
info->png_ptr = NULL;
|
||||
info->info_ptr = NULL;
|
||||
info->row_pointers = NULL;
|
||||
|
||||
assert(bitmap != NULL);
|
||||
|
||||
/* Initialize the write struct. */
|
||||
info->png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
||||
NULL, NULL, NULL);
|
||||
if (info->png_ptr == NULL) goto bail;
|
||||
|
||||
/* Set up error handling. */
|
||||
if (setjmp(png_jmpbuf(info->png_ptr))) {
|
||||
png_destroy_write_struct(&(info->png_ptr), &(info->info_ptr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Initialize the info struct. */
|
||||
info->info_ptr = png_create_info_struct(info->png_ptr);
|
||||
if (info->info_ptr == NULL) {
|
||||
png_destroy_write_struct(&(info->png_ptr), NULL);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Set image attributes. */
|
||||
png_set_IHDR(info->png_ptr,
|
||||
info->info_ptr,
|
||||
(png_uint_32)bitmap->width,
|
||||
(png_uint_32)bitmap->height,
|
||||
8,
|
||||
PNG_COLOR_TYPE_RGB,
|
||||
PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
info->row_count = bitmap->height;
|
||||
info->row_pointers = png_malloc(info->png_ptr,
|
||||
sizeof(png_byte *) * info->row_count);
|
||||
|
||||
if (bitmap->bytesPerPixel == 3) {
|
||||
/* No alpha channel; image data can be copied directly. */
|
||||
for (y = 0; y < info->row_count; ++y) {
|
||||
info->row_pointers[y] = bitmap->imageBuffer + (bitmap->bytewidth * y);
|
||||
}
|
||||
info->free_row_pointers = false;
|
||||
|
||||
/* Convert BGR to RGB if necessary. */
|
||||
if (MMRGB_IS_BGR) {
|
||||
png_set_bgr(info->png_ptr);
|
||||
}
|
||||
} else {
|
||||
/* Ignore alpha channel; copy image data row by row. */
|
||||
const size_t bytesPerPixel = 3;
|
||||
const size_t bytewidth = ADD_PADDING(bitmap->width * bytesPerPixel);
|
||||
|
||||
for (y = 0; y < info->row_count; ++y) {
|
||||
png_uint_32 x;
|
||||
png_byte *row_ptr = png_malloc(info->png_ptr, bytewidth);
|
||||
info->row_pointers[y] = row_ptr;
|
||||
for (x = 0; x < bitmap->width; ++x) {
|
||||
MMRGBColor *color = MMRGBColorRefAtPoint(bitmap, x, y);
|
||||
row_ptr[0] = color->red;
|
||||
row_ptr[1] = color->green;
|
||||
row_ptr[2] = color->blue;
|
||||
|
||||
row_ptr += bytesPerPixel;
|
||||
}
|
||||
}
|
||||
info->free_row_pointers = true;
|
||||
}
|
||||
|
||||
png_set_rows(info->png_ptr, info->info_ptr, info->row_pointers);
|
||||
return info;
|
||||
|
||||
bail:
|
||||
if (info != NULL) free(info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Free memory in use by |info|. */
|
||||
static void destroyPNGWriteInfo(PNGWriteInfoRef info)
|
||||
{
|
||||
assert(info != NULL);
|
||||
if (info->row_pointers != NULL) {
|
||||
if (info->free_row_pointers) {
|
||||
size_t y;
|
||||
for (y = 0; y < info->row_count; ++y) {
|
||||
free(info->row_pointers[y]);
|
||||
}
|
||||
}
|
||||
png_free(info->png_ptr, info->row_pointers);
|
||||
}
|
||||
|
||||
png_destroy_write_struct(&(info->png_ptr), &(info->info_ptr));
|
||||
free(info);
|
||||
}
|
||||
|
||||
int saveMMBitmapAsPNG(MMBitmapRef bitmap, const char *path)
|
||||
{
|
||||
FILE *fp = fopen(path, "wb");
|
||||
PNGWriteInfoRef info;
|
||||
if (fp == NULL) return -1;
|
||||
|
||||
if ((info = createPNGWriteInfo(bitmap)) == NULL) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
png_init_io(info->png_ptr, fp);
|
||||
png_write_png(info->png_ptr, info->info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
|
||||
fclose(fp);
|
||||
|
||||
destroyPNGWriteInfo(info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Structure to store PNG image bytes. */
|
||||
struct io_data
|
||||
{
|
||||
uint8_t *buffer; /* Pointer to raw file data. */
|
||||
size_t size; /* Number of bytes actually written to buffer. */
|
||||
size_t allocedSize; /* Number of bytes allocated for buffer. */
|
||||
};
|
||||
|
||||
/* Called each time libpng attempts to write data in createPNGData(). */
|
||||
void png_append_data(png_struct *png_ptr,
|
||||
png_byte *new_data,
|
||||
png_size_t length)
|
||||
{
|
||||
struct io_data *data = png_get_io_ptr(png_ptr);
|
||||
data->size += length;
|
||||
|
||||
/* Allocate or grow buffer. */
|
||||
if (data->buffer == NULL) {
|
||||
data->allocedSize = data->size;
|
||||
data->buffer = png_malloc(png_ptr, data->allocedSize);
|
||||
assert(data->buffer != NULL);
|
||||
} else if (data->allocedSize < data->size) {
|
||||
do {
|
||||
/* Double size each time to avoid calls to realloc. */
|
||||
data->allocedSize <<= 1;
|
||||
} while (data->allocedSize < data->size);
|
||||
|
||||
data->buffer = realloc(data->buffer, data->allocedSize);
|
||||
}
|
||||
|
||||
/* Copy new bytes to end of buffer. */
|
||||
memcpy(data->buffer + data->size - length, new_data, length);
|
||||
}
|
||||
|
||||
uint8_t *createPNGData(MMBitmapRef bitmap, size_t *len)
|
||||
{
|
||||
PNGWriteInfoRef info = NULL;
|
||||
struct io_data data = {NULL, 0, 0};
|
||||
|
||||
assert(bitmap != NULL);
|
||||
assert(len != NULL);
|
||||
|
||||
if ((info = createPNGWriteInfo(bitmap)) == NULL) return NULL;
|
||||
|
||||
png_set_write_fn(info->png_ptr, &data, &png_append_data, NULL);
|
||||
png_write_png(info->png_ptr, info->info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
|
||||
|
||||
destroyPNGWriteInfo(info);
|
||||
|
||||
*len = data.size;
|
||||
return data.buffer;
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
#ifndef _PORTABLE_SNPRINTF_H_
|
||||
#define _PORTABLE_SNPRINTF_H_
|
||||
|
||||
#define PORTABLE_SNPRINTF_VERSION_MAJOR 2
|
||||
#define PORTABLE_SNPRINTF_VERSION_MINOR 2
|
||||
|
||||
#include "os.h"
|
||||
#if defined(IS_MACOSX)
|
||||
#define HAVE_SNPRINTF
|
||||
#else
|
||||
#define HAVE_SNPRINTF
|
||||
#define PREFER_PORTABLE_SNPRINTF
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SNPRINTF
|
||||
#include <stdio.h>
|
||||
#else
|
||||
extern int snprintf(char *, size_t, const char *, /*args*/ ...);
|
||||
extern int vsnprintf(char *, size_t, const char *, va_list);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SNPRINTF) && defined(PREFER_PORTABLE_SNPRINTF)
|
||||
extern int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...);
|
||||
extern int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap);
|
||||
#define snprintf portable_snprintf
|
||||
#define vsnprintf portable_vsnprintf
|
||||
#endif
|
||||
|
||||
extern int asprintf (char **ptr, const char *fmt, /*args*/ ...);
|
||||
extern int vasprintf (char **ptr, const char *fmt, va_list ap);
|
||||
extern int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...);
|
||||
extern int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
1019
base/snprintf_c.h
1019
base/snprintf_c.h
File diff suppressed because it is too large
Load Diff
@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef STR_IO_H
|
||||
#define STR_IO_H
|
||||
|
||||
#include "MMBitmap.h"
|
||||
#include "file_io.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
enum _MMBMPStringError {
|
||||
kMMBMPStringGenericError = 0,
|
||||
kMMBMPStringInvalidHeaderError,
|
||||
kMMBMPStringDecodeError,
|
||||
kMMBMPStringDecompressError,
|
||||
kMMBMPStringSizeError, /* Size does not match header. */
|
||||
MMMBMPStringEncodeError,
|
||||
kMMBMPStringCompressError
|
||||
};
|
||||
|
||||
typedef MMIOError MMBMPStringError;
|
||||
|
||||
/* Creates a 24-bit bitmap from a compressed, printable string.
|
||||
*
|
||||
* String should be in the format: "b[width],[height],[data]",
|
||||
* where [width] and [height] are the image width & height, and [data]
|
||||
* is the raw image data run through zlib_compress() and base64_encode().
|
||||
*
|
||||
* Returns NULL on error; follows the Create Rule (that is, the caller is
|
||||
* responsible for destroy'()ing object).
|
||||
* If |error| is non-NULL, it will be set to the error code on return.
|
||||
*/
|
||||
MMBitmapRef createMMBitmapFromString(const uint8_t *buffer, size_t buflen,
|
||||
MMBMPStringError *error);
|
||||
|
||||
/* Inverse of createMMBitmapFromString().
|
||||
*
|
||||
* Creates string in the format: "b[width],[height],[data]", where [width] and
|
||||
* [height] are the image width & height, and [data] is the raw image data run
|
||||
* through zlib_compress() and base64_encode().
|
||||
*
|
||||
* Returns NULL on error, or new string on success (to be free'()d by caller).
|
||||
* If |error| is non-NULL, it will be set to the error code on return.
|
||||
*/
|
||||
uint8_t *createStringFromMMBitmap(MMBitmapRef bitmap, MMBMPStringError *error);
|
||||
|
||||
/* Returns description of given error code.
|
||||
* Returned string is constant and hence should not be freed. */
|
||||
const char *MMBitmapStringErrorString(MMBMPStringError err);
|
||||
|
||||
#endif /* STR_IO_H */
|
208
base/str_io_c.h
208
base/str_io_c.h
@ -1,208 +0,0 @@
|
||||
#include "str_io.h"
|
||||
#include "zlib_util_c.h"
|
||||
#include "base64_c.h"
|
||||
#include "snprintf_c.h" /* snprintf() */
|
||||
#include <stdio.h> /* fputs() */
|
||||
#include <ctype.h> /* isdigit() */
|
||||
#include <stdlib.h> /* atoi() */
|
||||
#include <string.h> /* strlen() */
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include "ms_stdbool.h"
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#define STR_BITS_PER_PIXEL 24
|
||||
#define STR_BYTES_PER_PIXEL ((STR_BITS_PER_PIXEL) / 8)
|
||||
|
||||
#define MAX_DIMENSION_LEN 5 /* Maximum length for [width] or [height]
|
||||
* in string. */
|
||||
|
||||
const char *MMBitmapStringErrorString(MMBMPStringError err)
|
||||
{
|
||||
switch (err) {
|
||||
case kMMBMPStringInvalidHeaderError:
|
||||
return "Invalid header for string";
|
||||
case kMMBMPStringDecodeError:
|
||||
return "Error decoding string";
|
||||
case kMMBMPStringDecompressError:
|
||||
return "Error decompressing string";
|
||||
case kMMBMPStringSizeError:
|
||||
return "String not of expected size";
|
||||
case MMMBMPStringEncodeError:
|
||||
return "Error encoding string";
|
||||
case kMMBMPStringCompressError:
|
||||
return "Error compressing string";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parses beginning of string in the form of "[width],[height],*".
|
||||
*
|
||||
* If successful, |width| and |height| are set to the appropropriate values,
|
||||
* |len| is set to the length of [width] + the length of [height] + 2,
|
||||
* and true is returned; otherwise, false is returned.
|
||||
*/
|
||||
static bool getSizeFromString(const uint8_t *buf, size_t buflen,
|
||||
size_t *width, size_t *height,
|
||||
size_t *len);
|
||||
|
||||
MMBitmapRef createMMBitmapFromString(const uint8_t *buffer, size_t buflen,
|
||||
MMBMPStringError *err)
|
||||
{
|
||||
uint8_t *decoded, *decompressed;
|
||||
size_t width, height;
|
||||
size_t len, bytewidth;
|
||||
|
||||
if (*buffer++ != 'b' || !getSizeFromString(buffer, --buflen,
|
||||
&width, &height, &len)) {
|
||||
if (err != NULL) *err = kMMBMPStringInvalidHeaderError;
|
||||
return NULL;
|
||||
}
|
||||
buffer += len;
|
||||
buflen -= len;
|
||||
|
||||
decoded = base64decode(buffer, buflen, NULL);
|
||||
if (decoded == NULL) {
|
||||
if (err != NULL) *err = kMMBMPStringDecodeError;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
decompressed = zlib_decompress(decoded, &len);
|
||||
free(decoded);
|
||||
|
||||
if (decompressed == NULL) {
|
||||
if (err != NULL) *err = kMMBMPStringDecompressError;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bytewidth = width * STR_BYTES_PER_PIXEL; /* Note that bytewidth is NOT
|
||||
* aligned to a padding. */
|
||||
if (height * bytewidth != len) {
|
||||
if (err != NULL) *err = kMMBMPStringSizeError;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return createMMBitmap(decompressed, width, height,
|
||||
bytewidth, STR_BITS_PER_PIXEL, STR_BYTES_PER_PIXEL);
|
||||
}
|
||||
|
||||
/* Returns bitmap data suitable for encoding to a string; that is, 24-bit BGR
|
||||
* bitmap with no padding and 3 bytes per pixel.
|
||||
*
|
||||
* Caller is responsible for free()'ing returned buffer. */
|
||||
static uint8_t *createRawBitmapData(MMBitmapRef bitmap);
|
||||
|
||||
uint8_t *createStringFromMMBitmap(MMBitmapRef bitmap, MMBMPStringError *err)
|
||||
{
|
||||
uint8_t *raw, *compressed;
|
||||
uint8_t *ret, *encoded;
|
||||
size_t len, retlen;
|
||||
|
||||
assert(bitmap != NULL);
|
||||
|
||||
raw = createRawBitmapData(bitmap);
|
||||
if (raw == NULL) {
|
||||
if (err != NULL) *err = kMMBMPStringGenericError;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
compressed = zlib_compress(raw,
|
||||
bitmap->width * bitmap->height *
|
||||
STR_BYTES_PER_PIXEL,
|
||||
9, &len);
|
||||
free(raw);
|
||||
if (compressed == NULL) {
|
||||
if (err != NULL) *err = kMMBMPStringCompressError;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
encoded = base64encode(compressed, len - 1, &retlen);
|
||||
free(compressed);
|
||||
if (encoded == NULL) {
|
||||
if (err != NULL) *err = MMMBMPStringEncodeError;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
retlen += 3 + (MAX_DIMENSION_LEN * 2);
|
||||
ret = calloc(sizeof(char), (retlen + 1));
|
||||
snprintf((char *)ret, retlen, "b%lu,%lu,%s", (unsigned long)bitmap->width,
|
||||
(unsigned long)bitmap->height,
|
||||
encoded);
|
||||
ret[retlen] = '\0';
|
||||
free(encoded);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t parseDimension(const uint8_t *buf, size_t buflen,
|
||||
size_t *numlen);
|
||||
|
||||
static bool getSizeFromString(const uint8_t *buf, size_t buflen,
|
||||
size_t *width, size_t *height,
|
||||
size_t *len)
|
||||
{
|
||||
size_t numlen;
|
||||
assert(buf != NULL);
|
||||
assert(width != NULL);
|
||||
assert(height != NULL);
|
||||
|
||||
if ((*width = parseDimension(buf, buflen, &numlen)) == 0) {
|
||||
return false;
|
||||
}
|
||||
*len = numlen + 1;
|
||||
|
||||
if ((*height = parseDimension(buf + *len, buflen, &numlen)) == 0) {
|
||||
return false;
|
||||
}
|
||||
*len += numlen + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Parses one dimension from string as described in getSizeFromString().
|
||||
* Returns dimension on success, or 0 on error. */
|
||||
static uint32_t parseDimension(const uint8_t *buf,
|
||||
size_t buflen, size_t *numlen){
|
||||
char num[MAX_DIMENSION_LEN + 1];
|
||||
size_t i;
|
||||
// ssize_t len;
|
||||
// size_t len;
|
||||
// uint8_t *len;
|
||||
|
||||
assert(buf != NULL);
|
||||
// assert(len != NULL);
|
||||
for (i = 0; i < buflen && buf[i] != ',' && buf[i] != '\0'; ++i) {
|
||||
if (!isdigit(buf[i]) || i > MAX_DIMENSION_LEN) return 0;
|
||||
num[i] = buf[i];
|
||||
}
|
||||
num[i] = '\0';
|
||||
*numlen = i;
|
||||
|
||||
return (uint32_t)atoi(num);
|
||||
}
|
||||
|
||||
static uint8_t *createRawBitmapData(MMBitmapRef bitmap)
|
||||
{
|
||||
uint8_t *raw = calloc(STR_BYTES_PER_PIXEL, bitmap->width * bitmap->height);
|
||||
size_t y;
|
||||
|
||||
for (y = 0; y < bitmap->height; ++y) {
|
||||
/* No padding is added to string bitmaps. */
|
||||
const size_t rowOffset = y * bitmap->width * STR_BYTES_PER_PIXEL;
|
||||
size_t x;
|
||||
for (x = 0; x < bitmap->width; ++x) {
|
||||
/* Copy in BGR format. */
|
||||
const size_t colOffset = x * STR_BYTES_PER_PIXEL;
|
||||
uint8_t *dest = raw + rowOffset + colOffset;
|
||||
MMRGBColor *srcColor = MMRGBColorRefAtPoint(bitmap, x, y);
|
||||
dest[0] = srcColor->blue;
|
||||
dest[1] = srcColor->green;
|
||||
dest[2] = srcColor->red;
|
||||
}
|
||||
}
|
||||
|
||||
return raw;
|
||||
}
|
929
base/uthash.h
929
base/uthash.h
@ -1,929 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2009, Troy D. Hanson http://uthash.sourceforge.net
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef UTHASH_H
|
||||
#define UTHASH_H
|
||||
|
||||
#include <string.h> /* memcmp, strlen */
|
||||
#include <stddef.h> /* ptrdiff_t */
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#define UTHASH_VERSION 1.8
|
||||
|
||||
/* C++ requires extra stringent casting */
|
||||
#if defined __cplusplus
|
||||
#define TYPEOF(x) (typeof(x))
|
||||
#else
|
||||
#define TYPEOF(x)
|
||||
#endif
|
||||
|
||||
|
||||
#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */
|
||||
#define uthash_malloc(sz) malloc(sz) /* malloc fcn */
|
||||
#define uthash_free(ptr) free(ptr) /* free fcn */
|
||||
|
||||
#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */
|
||||
#define uthash_expand_fyi(tbl) /* can be defined to log expands */
|
||||
|
||||
/* initial number of buckets */
|
||||
#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */
|
||||
#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */
|
||||
#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */
|
||||
|
||||
/* calculate the element whose hash handle address is hhe */
|
||||
#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)hhp) - (tbl)->hho))
|
||||
|
||||
#define HASH_FIND(hh,head,keyptr,keylen,out) \
|
||||
do { \
|
||||
unsigned _hf_bkt,_hf_hashv; \
|
||||
out=TYPEOF(out)NULL; \
|
||||
if (head) { \
|
||||
HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \
|
||||
if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \
|
||||
HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \
|
||||
keyptr,keylen,out); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if defined(HASH_BLOOM)
|
||||
#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM)
|
||||
#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0)
|
||||
#define HASH_BLOOM_MAKE(tbl) \
|
||||
do { \
|
||||
(tbl)->bloom_nbits = HASH_BLOOM; \
|
||||
(tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \
|
||||
if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \
|
||||
memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \
|
||||
(tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \
|
||||
} while (0);
|
||||
|
||||
#define HASH_BLOOM_FREE(tbl) \
|
||||
do { \
|
||||
uthash_free((tbl)->bloom_bv); \
|
||||
} while (0);
|
||||
|
||||
#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8)))
|
||||
#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8)))
|
||||
|
||||
#define HASH_BLOOM_ADD(tbl,hashv) \
|
||||
HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
|
||||
|
||||
#define HASH_BLOOM_TEST(tbl,hashv) \
|
||||
HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
|
||||
|
||||
#else
|
||||
#define HASH_BLOOM_MAKE(tbl)
|
||||
#define HASH_BLOOM_FREE(tbl)
|
||||
#define HASH_BLOOM_ADD(tbl,hashv)
|
||||
#define HASH_BLOOM_TEST(tbl,hashv) (1)
|
||||
#endif
|
||||
|
||||
#define HASH_MAKE_TABLE(hh,head) \
|
||||
do { \
|
||||
(head)->hh.tbl = (UT_hash_table*)uthash_malloc( \
|
||||
sizeof(UT_hash_table)); \
|
||||
if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \
|
||||
memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \
|
||||
(head)->hh.tbl->tail = &((head)->hh); \
|
||||
(head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \
|
||||
(head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \
|
||||
(head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \
|
||||
(head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \
|
||||
HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
|
||||
if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \
|
||||
memset((head)->hh.tbl->buckets, 0, \
|
||||
HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
|
||||
HASH_BLOOM_MAKE((head)->hh.tbl); \
|
||||
(head)->hh.tbl->signature = HASH_SIGNATURE; \
|
||||
} while(0)
|
||||
|
||||
#define HASH_ADD(hh,head,fieldname,keylen_in,add) \
|
||||
HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add)
|
||||
|
||||
#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \
|
||||
do { \
|
||||
unsigned _ha_bkt; \
|
||||
(add)->hh.next = NULL; \
|
||||
(add)->hh.key = (char*)keyptr; \
|
||||
(add)->hh.keylen = keylen_in; \
|
||||
if (!(head)) { \
|
||||
head = (add); \
|
||||
(head)->hh.prev = NULL; \
|
||||
HASH_MAKE_TABLE(hh,head); \
|
||||
} else { \
|
||||
(head)->hh.tbl->tail->next = (add); \
|
||||
(add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \
|
||||
(head)->hh.tbl->tail = &((add)->hh); \
|
||||
} \
|
||||
(head)->hh.tbl->num_items++; \
|
||||
(add)->hh.tbl = (head)->hh.tbl; \
|
||||
HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \
|
||||
(add)->hh.hashv, _ha_bkt); \
|
||||
HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \
|
||||
HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \
|
||||
HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \
|
||||
HASH_FSCK(hh,head); \
|
||||
} while(0)
|
||||
|
||||
#define HASH_TO_BKT( hashv, num_bkts, bkt ) \
|
||||
do { \
|
||||
bkt = ((hashv) & ((num_bkts) - 1)); \
|
||||
} while(0)
|
||||
|
||||
/* delete "delptr" from the hash table.
|
||||
* "the usual" patch-up process for the app-order doubly-linked-list.
|
||||
* The use of _hd_hh_del below deserves special explanation.
|
||||
* These used to be expressed using (delptr) but that led to a bug
|
||||
* if someone used the same symbol for the head and deletee, like
|
||||
* HASH_DELETE(hh,users,users);
|
||||
* We want that to work, but by changing the head (users) below
|
||||
* we were forfeiting our ability to further refer to the deletee (users)
|
||||
* in the patch-up process. Solution: use scratch space in the table to
|
||||
* copy the deletee pointer, then the latter references are via that
|
||||
* scratch pointer rather than through the repointed (users) symbol.
|
||||
*/
|
||||
#define HASH_DELETE(hh,head,delptr) \
|
||||
do { \
|
||||
unsigned _hd_bkt; \
|
||||
struct UT_hash_handle *_hd_hh_del; \
|
||||
if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \
|
||||
uthash_free((head)->hh.tbl->buckets ); \
|
||||
HASH_BLOOM_FREE((head)->hh.tbl); \
|
||||
uthash_free((head)->hh.tbl); \
|
||||
head = NULL; \
|
||||
} else { \
|
||||
_hd_hh_del = &((delptr)->hh); \
|
||||
if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \
|
||||
(head)->hh.tbl->tail = \
|
||||
(UT_hash_handle*)((char*)((delptr)->hh.prev) + \
|
||||
(head)->hh.tbl->hho); \
|
||||
} \
|
||||
if ((delptr)->hh.prev) { \
|
||||
((UT_hash_handle*)((char*)((delptr)->hh.prev) + \
|
||||
(head)->hh.tbl->hho))->next = (delptr)->hh.next; \
|
||||
} else { \
|
||||
head = TYPEOF(head)((delptr)->hh.next); \
|
||||
} \
|
||||
if (_hd_hh_del->next) { \
|
||||
((UT_hash_handle*)((char*)_hd_hh_del->next + \
|
||||
(head)->hh.tbl->hho))->prev = \
|
||||
_hd_hh_del->prev; \
|
||||
} \
|
||||
HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \
|
||||
HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \
|
||||
(head)->hh.tbl->num_items--; \
|
||||
} \
|
||||
HASH_FSCK(hh,head); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
|
||||
#define HASH_FIND_STR(head,findstr,out) \
|
||||
HASH_FIND(hh,head,findstr,strlen(findstr),out)
|
||||
#define HASH_ADD_STR(head,strfield,add) \
|
||||
HASH_ADD(hh,head,strfield,strlen(add->strfield),add)
|
||||
#define HASH_FIND_INT(head,findint,out) \
|
||||
HASH_FIND(hh,head,findint,sizeof(int),out)
|
||||
#define HASH_ADD_INT(head,intfield,add) \
|
||||
HASH_ADD(hh,head,intfield,sizeof(int),add)
|
||||
#define HASH_DEL(head,delptr) \
|
||||
HASH_DELETE(hh,head,delptr)
|
||||
|
||||
/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.
|
||||
* This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
|
||||
*/
|
||||
#if defined(HASH_DEBUG)
|
||||
#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
|
||||
#define HASH_FSCK(hh,head) \
|
||||
do { \
|
||||
unsigned _bkt_i; \
|
||||
unsigned _count, _bkt_count; \
|
||||
char *_prev; \
|
||||
struct UT_hash_handle *_thh; \
|
||||
if (head) { \
|
||||
_count = 0; \
|
||||
for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \
|
||||
_bkt_count = 0; \
|
||||
_thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \
|
||||
_prev = NULL; \
|
||||
while (_thh) { \
|
||||
if (_prev != (char*)(_thh->hh_prev)) { \
|
||||
HASH_OOPS("invalid hh_prev %p, actual %p\n", \
|
||||
_thh->hh_prev, _prev ); \
|
||||
} \
|
||||
_bkt_count++; \
|
||||
_prev = (char*)(_thh); \
|
||||
_thh = _thh->hh_next; \
|
||||
} \
|
||||
_count += _bkt_count; \
|
||||
if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \
|
||||
HASH_OOPS("invalid bucket count %d, actual %d\n", \
|
||||
(head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \
|
||||
} \
|
||||
} \
|
||||
if (_count != (head)->hh.tbl->num_items) { \
|
||||
HASH_OOPS("invalid hh item count %d, actual %d\n", \
|
||||
(head)->hh.tbl->num_items, _count ); \
|
||||
} \
|
||||
/* traverse hh in app order; check next/prev integrity, count */ \
|
||||
_count = 0; \
|
||||
_prev = NULL; \
|
||||
_thh = &(head)->hh; \
|
||||
while (_thh) { \
|
||||
_count++; \
|
||||
if (_prev !=(char*)(_thh->prev)) { \
|
||||
HASH_OOPS("invalid prev %p, actual %p\n", \
|
||||
_thh->prev, _prev ); \
|
||||
} \
|
||||
_prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \
|
||||
_thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \
|
||||
(head)->hh.tbl->hho) : NULL ); \
|
||||
} \
|
||||
if (_count != (head)->hh.tbl->num_items) { \
|
||||
HASH_OOPS("invalid app item count %d, actual %d\n", \
|
||||
(head)->hh.tbl->num_items, _count ); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define HASH_FSCK(hh,head)
|
||||
#endif
|
||||
|
||||
/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to
|
||||
* the descriptor to which this macro is defined for tuning the hash function.
|
||||
* The app can #include <unistd.h> to get the prototype for write(2). */
|
||||
#if defined(HASH_EMIT_KEYS)
|
||||
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \
|
||||
do { \
|
||||
unsigned _klen = fieldlen; \
|
||||
write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \
|
||||
write(HASH_EMIT_KEYS, keyptr, fieldlen); \
|
||||
} while (0)
|
||||
#else
|
||||
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
|
||||
#endif
|
||||
|
||||
/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
|
||||
#if defined(HASH_FUNCTION)
|
||||
#define HASH_FCN HASH_FUNCTION
|
||||
#else
|
||||
#define HASH_FCN HASH_JEN
|
||||
#endif
|
||||
|
||||
/* The Bernstein hash function, used in Perl prior to v5.6 */
|
||||
#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _hb_keylen=keylen; \
|
||||
char *_hb_key=(char*)key; \
|
||||
(hashv) = 0; \
|
||||
while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \
|
||||
bkt = (hashv) & (num_bkts-1); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
|
||||
* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
|
||||
#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _sx_i; \
|
||||
char *_hs_key=(char*)key; \
|
||||
hashv = 0; \
|
||||
for(_sx_i=0; _sx_i < keylen; _sx_i++) \
|
||||
hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while (0)
|
||||
|
||||
#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _fn_i; \
|
||||
char *_hf_key=(char*)key; \
|
||||
hashv = 2166136261UL; \
|
||||
for(_fn_i=0; _fn_i < keylen; _fn_i++) \
|
||||
hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0);
|
||||
|
||||
#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _ho_i; \
|
||||
char *_ho_key=(char*)key; \
|
||||
hashv = 0; \
|
||||
for(_ho_i=0; _ho_i < keylen; _ho_i++) { \
|
||||
hashv += _ho_key[_ho_i]; \
|
||||
hashv += (hashv << 10); \
|
||||
hashv ^= (hashv >> 6); \
|
||||
} \
|
||||
hashv += (hashv << 3); \
|
||||
hashv ^= (hashv >> 11); \
|
||||
hashv += (hashv << 15); \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0)
|
||||
|
||||
#define HASH_JEN_MIX(a,b,c) \
|
||||
do { \
|
||||
a -= b; a -= c; a ^= ( c >> 13 ); \
|
||||
b -= c; b -= a; b ^= ( a << 8 ); \
|
||||
c -= a; c -= b; c ^= ( b >> 13 ); \
|
||||
a -= b; a -= c; a ^= ( c >> 12 ); \
|
||||
b -= c; b -= a; b ^= ( a << 16 ); \
|
||||
c -= a; c -= b; c ^= ( b >> 5 ); \
|
||||
a -= b; a -= c; a ^= ( c >> 3 ); \
|
||||
b -= c; b -= a; b ^= ( a << 10 ); \
|
||||
c -= a; c -= b; c ^= ( b >> 15 ); \
|
||||
} while (0)
|
||||
|
||||
#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _hj_i,_hj_j,_hj_k; \
|
||||
char *_hj_key=(char*)key; \
|
||||
hashv = 0xfeedbeef; \
|
||||
_hj_i = _hj_j = 0x9e3779b9; \
|
||||
_hj_k = keylen; \
|
||||
while (_hj_k >= 12) { \
|
||||
_hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \
|
||||
+ ( (unsigned)_hj_key[2] << 16 ) \
|
||||
+ ( (unsigned)_hj_key[3] << 24 ) ); \
|
||||
_hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \
|
||||
+ ( (unsigned)_hj_key[6] << 16 ) \
|
||||
+ ( (unsigned)_hj_key[7] << 24 ) ); \
|
||||
hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \
|
||||
+ ( (unsigned)_hj_key[10] << 16 ) \
|
||||
+ ( (unsigned)_hj_key[11] << 24 ) ); \
|
||||
\
|
||||
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
|
||||
\
|
||||
_hj_key += 12; \
|
||||
_hj_k -= 12; \
|
||||
} \
|
||||
hashv += keylen; \
|
||||
switch ( _hj_k ) { \
|
||||
case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \
|
||||
case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \
|
||||
case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \
|
||||
case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \
|
||||
case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \
|
||||
case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \
|
||||
case 5: _hj_j += _hj_key[4]; \
|
||||
case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \
|
||||
case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \
|
||||
case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \
|
||||
case 1: _hj_i += _hj_key[0]; \
|
||||
} \
|
||||
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0)
|
||||
|
||||
/* The Paul Hsieh hash function */
|
||||
#undef get16bits
|
||||
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|
||||
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
|
||||
#define get16bits(d) (*((const uint16_t *) (d)))
|
||||
#endif
|
||||
|
||||
#if !defined (get16bits)
|
||||
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \
|
||||
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
||||
#endif
|
||||
#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
char *_sfh_key=(char*)key; \
|
||||
uint32_t _sfh_tmp, _sfh_len = keylen; \
|
||||
\
|
||||
int _sfh_rem = _sfh_len & 3; \
|
||||
_sfh_len >>= 2; \
|
||||
hashv = 0xcafebabe; \
|
||||
\
|
||||
/* Main loop */ \
|
||||
for (;_sfh_len > 0; _sfh_len--) { \
|
||||
hashv += get16bits (_sfh_key); \
|
||||
_sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \
|
||||
hashv = (hashv << 16) ^ _sfh_tmp; \
|
||||
_sfh_key += 2*sizeof (uint16_t); \
|
||||
hashv += hashv >> 11; \
|
||||
} \
|
||||
\
|
||||
/* Handle end cases */ \
|
||||
switch (_sfh_rem) { \
|
||||
case 3: hashv += get16bits (_sfh_key); \
|
||||
hashv ^= hashv << 16; \
|
||||
hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \
|
||||
hashv += hashv >> 11; \
|
||||
break; \
|
||||
case 2: hashv += get16bits (_sfh_key); \
|
||||
hashv ^= hashv << 11; \
|
||||
hashv += hashv >> 17; \
|
||||
break; \
|
||||
case 1: hashv += *_sfh_key; \
|
||||
hashv ^= hashv << 10; \
|
||||
hashv += hashv >> 1; \
|
||||
} \
|
||||
\
|
||||
/* Force "avalanching" of final 127 bits */ \
|
||||
hashv ^= hashv << 3; \
|
||||
hashv += hashv >> 5; \
|
||||
hashv ^= hashv << 4; \
|
||||
hashv += hashv >> 17; \
|
||||
hashv ^= hashv << 25; \
|
||||
hashv += hashv >> 6; \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0);
|
||||
|
||||
#if defined(HASH_USING_NO_STRICT_ALIASING)
|
||||
/* The MurmurHash exploits some CPU's (e.g. x86) tolerance for unaligned reads.
|
||||
* For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
|
||||
* So MurmurHash comes in two versions, the faster unaligned one and the slower
|
||||
* aligned one. We only use the faster one on CPU's where we know it's safe.
|
||||
*
|
||||
* Note the preprocessor built-in defines can be emitted using:
|
||||
*
|
||||
* gcc -m64 -dM -E - < /dev/null (on gcc)
|
||||
* cc -## a.c (where a.c is a simple test file) (Sun Studio)
|
||||
*/
|
||||
#if (defined(__i386__) || defined(__x86_64__))
|
||||
#define HASH_MUR HASH_MUR_UNALIGNED
|
||||
#else
|
||||
#define HASH_MUR HASH_MUR_ALIGNED
|
||||
#endif
|
||||
|
||||
/* Appleby's MurmurHash fast version for unaligned-tolerant archs like i386 */
|
||||
#define HASH_MUR_UNALIGNED(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
const unsigned int _mur_m = 0x5bd1e995; \
|
||||
const int _mur_r = 24; \
|
||||
hashv = 0xcafebabe ^ keylen; \
|
||||
char *_mur_key = (char *)key; \
|
||||
uint32_t _mur_tmp, _mur_len = keylen; \
|
||||
\
|
||||
for (;_mur_len >= 4; _mur_len-=4) { \
|
||||
_mur_tmp = *(uint32_t *)_mur_key; \
|
||||
_mur_tmp *= _mur_m; \
|
||||
_mur_tmp ^= _mur_tmp >> _mur_r; \
|
||||
_mur_tmp *= _mur_m; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= _mur_tmp; \
|
||||
_mur_key += 4; \
|
||||
} \
|
||||
\
|
||||
switch(_mur_len) \
|
||||
{ \
|
||||
case 3: hashv ^= _mur_key[2] << 16; \
|
||||
case 2: hashv ^= _mur_key[1] << 8; \
|
||||
case 1: hashv ^= _mur_key[0]; \
|
||||
hashv *= _mur_m; \
|
||||
}; \
|
||||
\
|
||||
hashv ^= hashv >> 13; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= hashv >> 15; \
|
||||
\
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0)
|
||||
|
||||
/* Appleby's MurmurHash version for alignment-sensitive archs like Sparc */
|
||||
#define HASH_MUR_ALIGNED(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
const unsigned int _mur_m = 0x5bd1e995; \
|
||||
const int _mur_r = 24; \
|
||||
hashv = 0xcafebabe ^ keylen; \
|
||||
char *_mur_key = (char *)key; \
|
||||
uint32_t _mur_len = keylen; \
|
||||
int _mur_align = (int)_mur_key & 3; \
|
||||
\
|
||||
if (_mur_align && (_mur_len >= 4)) { \
|
||||
unsigned _mur_t = 0, _mur_d = 0; \
|
||||
switch(_mur_align) { \
|
||||
case 1: _mur_t |= _mur_key[2] << 16; \
|
||||
case 2: _mur_t |= _mur_key[1] << 8; \
|
||||
case 3: _mur_t |= _mur_key[0]; \
|
||||
} \
|
||||
_mur_t <<= (8 * _mur_align); \
|
||||
_mur_key += 4-_mur_align; \
|
||||
_mur_len -= 4-_mur_align; \
|
||||
int _mur_sl = 8 * (4-_mur_align); \
|
||||
int _mur_sr = 8 * _mur_align; \
|
||||
\
|
||||
for (;_mur_len >= 4; _mur_len-=4) { \
|
||||
_mur_d = *(unsigned *)_mur_key; \
|
||||
_mur_t = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \
|
||||
unsigned _mur_k = _mur_t; \
|
||||
_mur_k *= _mur_m; \
|
||||
_mur_k ^= _mur_k >> _mur_r; \
|
||||
_mur_k *= _mur_m; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= _mur_k; \
|
||||
_mur_t = _mur_d; \
|
||||
_mur_key += 4; \
|
||||
} \
|
||||
_mur_d = 0; \
|
||||
if(_mur_len >= _mur_align) { \
|
||||
switch(_mur_align) { \
|
||||
case 3: _mur_d |= _mur_key[2] << 16; \
|
||||
case 2: _mur_d |= _mur_key[1] << 8; \
|
||||
case 1: _mur_d |= _mur_key[0]; \
|
||||
} \
|
||||
unsigned _mur_k = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \
|
||||
_mur_k *= _mur_m; \
|
||||
_mur_k ^= _mur_k >> _mur_r; \
|
||||
_mur_k *= _mur_m; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= _mur_k; \
|
||||
_mur_k += _mur_align; \
|
||||
_mur_len -= _mur_align; \
|
||||
\
|
||||
switch(_mur_len) \
|
||||
{ \
|
||||
case 3: hashv ^= _mur_key[2] << 16; \
|
||||
case 2: hashv ^= _mur_key[1] << 8; \
|
||||
case 1: hashv ^= _mur_key[0]; \
|
||||
hashv *= _mur_m; \
|
||||
} \
|
||||
} else { \
|
||||
switch(_mur_len) \
|
||||
{ \
|
||||
case 3: _mur_d ^= _mur_key[2] << 16; \
|
||||
case 2: _mur_d ^= _mur_key[1] << 8; \
|
||||
case 1: _mur_d ^= _mur_key[0]; \
|
||||
case 0: hashv ^= (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \
|
||||
hashv *= _mur_m; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
hashv ^= hashv >> 13; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= hashv >> 15; \
|
||||
} else { \
|
||||
for (;_mur_len >= 4; _mur_len-=4) { \
|
||||
unsigned _mur_k = *(unsigned*)_mur_key; \
|
||||
_mur_k *= _mur_m; \
|
||||
_mur_k ^= _mur_k >> _mur_r; \
|
||||
_mur_k *= _mur_m; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= _mur_k; \
|
||||
_mur_key += 4; \
|
||||
} \
|
||||
switch(_mur_len) \
|
||||
{ \
|
||||
case 3: hashv ^= _mur_key[2] << 16; \
|
||||
case 2: hashv ^= _mur_key[1] << 8; \
|
||||
case 1: hashv ^= _mur_key[0]; \
|
||||
hashv *= _mur_m; \
|
||||
} \
|
||||
\
|
||||
hashv ^= hashv >> 13; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= hashv >> 15; \
|
||||
} \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0)
|
||||
#endif /* HASH_USING_NO_STRICT_ALIASING */
|
||||
|
||||
/* key comparison function; return 0 if keys equal */
|
||||
#define HASH_KEYCMP(a,b,len) memcmp(a,b,len)
|
||||
|
||||
/* iterate over items in a known bucket to find desired item */
|
||||
#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \
|
||||
out = TYPEOF(out)((head.hh_head) ? ELMT_FROM_HH(tbl,head.hh_head) : NULL); \
|
||||
while (out) { \
|
||||
if (out->hh.keylen == keylen_in) { \
|
||||
if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break; \
|
||||
} \
|
||||
out= TYPEOF(out)((out->hh.hh_next) ? \
|
||||
ELMT_FROM_HH(tbl,out->hh.hh_next) : NULL); \
|
||||
}
|
||||
|
||||
/* add an item to a bucket */
|
||||
#define HASH_ADD_TO_BKT(head,addhh) \
|
||||
do { \
|
||||
head.count++; \
|
||||
(addhh)->hh_next = head.hh_head; \
|
||||
(addhh)->hh_prev = NULL; \
|
||||
if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \
|
||||
(head).hh_head=addhh; \
|
||||
if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \
|
||||
&& (addhh)->tbl->noexpand != 1) { \
|
||||
HASH_EXPAND_BUCKETS((addhh)->tbl); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* remove an item from a given bucket */
|
||||
#define HASH_DEL_IN_BKT(hh,head,hh_del) \
|
||||
(head).count--; \
|
||||
if ((head).hh_head == hh_del) { \
|
||||
(head).hh_head = hh_del->hh_next; \
|
||||
} \
|
||||
if (hh_del->hh_prev) { \
|
||||
hh_del->hh_prev->hh_next = hh_del->hh_next; \
|
||||
} \
|
||||
if (hh_del->hh_next) { \
|
||||
hh_del->hh_next->hh_prev = hh_del->hh_prev; \
|
||||
}
|
||||
|
||||
/* Bucket expansion has the effect of doubling the number of buckets
|
||||
* and redistributing the items into the new buckets. Ideally the
|
||||
* items will distribute more or less evenly into the new buckets
|
||||
* (the extent to which this is true is a measure of the quality of
|
||||
* the hash function as it applies to the key domain).
|
||||
*
|
||||
* With the items distributed into more buckets, the chain length
|
||||
* (item count) in each bucket is reduced. Thus by expanding buckets
|
||||
* the hash keeps a bound on the chain length. This bounded chain
|
||||
* length is the essence of how a hash provides constant time lookup.
|
||||
*
|
||||
* The calculation of tbl->ideal_chain_maxlen below deserves some
|
||||
* explanation. First, keep in mind that we're calculating the ideal
|
||||
* maximum chain length based on the *new* (doubled) bucket count.
|
||||
* In fractions this is just n/b (n=number of items,b=new num buckets).
|
||||
* Since the ideal chain length is an integer, we want to calculate
|
||||
* ceil(n/b). We don't depend on floating point arithmetic in this
|
||||
* hash, so to calculate ceil(n/b) with integers we could write
|
||||
*
|
||||
* ceil(n/b) = (n/b) + ((n%b)?1:0)
|
||||
*
|
||||
* and in fact a previous version of this hash did just that.
|
||||
* But now we have improved things a bit by recognizing that b is
|
||||
* always a power of two. We keep its base 2 log handy (call it lb),
|
||||
* so now we can write this with a bit shift and logical AND:
|
||||
*
|
||||
* ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
|
||||
*
|
||||
*/
|
||||
#define HASH_EXPAND_BUCKETS(tbl) \
|
||||
do { \
|
||||
unsigned _he_bkt; \
|
||||
unsigned _he_bkt_i; \
|
||||
struct UT_hash_handle *_he_thh, *_he_hh_nxt; \
|
||||
UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
|
||||
_he_new_buckets = (UT_hash_bucket*)uthash_malloc( \
|
||||
2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
|
||||
if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \
|
||||
memset(_he_new_buckets, 0, \
|
||||
2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
|
||||
tbl->ideal_chain_maxlen = \
|
||||
(tbl->num_items >> (tbl->log2_num_buckets+1)) + \
|
||||
((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \
|
||||
tbl->nonideal_items = 0; \
|
||||
for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \
|
||||
{ \
|
||||
_he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \
|
||||
while (_he_thh) { \
|
||||
_he_hh_nxt = _he_thh->hh_next; \
|
||||
HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \
|
||||
_he_newbkt = &(_he_new_buckets[ _he_bkt ]); \
|
||||
if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \
|
||||
tbl->nonideal_items++; \
|
||||
_he_newbkt->expand_mult = _he_newbkt->count / \
|
||||
tbl->ideal_chain_maxlen; \
|
||||
} \
|
||||
_he_thh->hh_prev = NULL; \
|
||||
_he_thh->hh_next = _he_newbkt->hh_head; \
|
||||
if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \
|
||||
_he_thh; \
|
||||
_he_newbkt->hh_head = _he_thh; \
|
||||
_he_thh = _he_hh_nxt; \
|
||||
} \
|
||||
} \
|
||||
tbl->num_buckets *= 2; \
|
||||
tbl->log2_num_buckets++; \
|
||||
uthash_free( tbl->buckets ); \
|
||||
tbl->buckets = _he_new_buckets; \
|
||||
tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \
|
||||
(tbl->ineff_expands+1) : 0; \
|
||||
if (tbl->ineff_expands > 1) { \
|
||||
tbl->noexpand=1; \
|
||||
uthash_noexpand_fyi(tbl); \
|
||||
} \
|
||||
uthash_expand_fyi(tbl); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
|
||||
/* Note that HASH_SORT assumes the hash handle name to be hh.
|
||||
* HASH_SRT was added to allow the hash handle name to be passed in. */
|
||||
#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)
|
||||
#define HASH_SRT(hh,head,cmpfcn) \
|
||||
do { \
|
||||
unsigned _hs_i; \
|
||||
unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \
|
||||
struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \
|
||||
if (head) { \
|
||||
_hs_insize = 1; \
|
||||
_hs_looping = 1; \
|
||||
_hs_list = &((head)->hh); \
|
||||
while (_hs_looping) { \
|
||||
_hs_p = _hs_list; \
|
||||
_hs_list = NULL; \
|
||||
_hs_tail = NULL; \
|
||||
_hs_nmerges = 0; \
|
||||
while (_hs_p) { \
|
||||
_hs_nmerges++; \
|
||||
_hs_q = _hs_p; \
|
||||
_hs_psize = 0; \
|
||||
for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \
|
||||
_hs_psize++; \
|
||||
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
|
||||
((void*)((char*)(_hs_q->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
if (! (_hs_q) ) break; \
|
||||
} \
|
||||
_hs_qsize = _hs_insize; \
|
||||
while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \
|
||||
if (_hs_psize == 0) { \
|
||||
_hs_e = _hs_q; \
|
||||
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
|
||||
((void*)((char*)(_hs_q->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
_hs_qsize--; \
|
||||
} else if ( (_hs_qsize == 0) || !(_hs_q) ) { \
|
||||
_hs_e = _hs_p; \
|
||||
_hs_p = (UT_hash_handle*)((_hs_p->next) ? \
|
||||
((void*)((char*)(_hs_p->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
_hs_psize--; \
|
||||
} else if (( \
|
||||
cmpfcn(TYPEOF(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \
|
||||
TYPEOF(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \
|
||||
) <= 0) { \
|
||||
_hs_e = _hs_p; \
|
||||
_hs_p = (UT_hash_handle*)((_hs_p->next) ? \
|
||||
((void*)((char*)(_hs_p->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
_hs_psize--; \
|
||||
} else { \
|
||||
_hs_e = _hs_q; \
|
||||
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
|
||||
((void*)((char*)(_hs_q->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
_hs_qsize--; \
|
||||
} \
|
||||
if ( _hs_tail ) { \
|
||||
_hs_tail->next = ((_hs_e) ? \
|
||||
ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \
|
||||
} else { \
|
||||
_hs_list = _hs_e; \
|
||||
} \
|
||||
_hs_e->prev = ((_hs_tail) ? \
|
||||
ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \
|
||||
_hs_tail = _hs_e; \
|
||||
} \
|
||||
_hs_p = _hs_q; \
|
||||
} \
|
||||
_hs_tail->next = NULL; \
|
||||
if ( _hs_nmerges <= 1 ) { \
|
||||
_hs_looping=0; \
|
||||
(head)->hh.tbl->tail = _hs_tail; \
|
||||
(head) = TYPEOF(head)ELMT_FROM_HH((head)->hh.tbl, _hs_list); \
|
||||
} \
|
||||
_hs_insize *= 2; \
|
||||
} \
|
||||
HASH_FSCK(hh,head); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* This function selects items from one hash into another hash.
|
||||
* The end result is that the selected items have dual presence
|
||||
* in both hashes. There is no copy of the items made; rather
|
||||
* they are added into the new hash through a secondary hash
|
||||
* hash handle that must be present in the structure. */
|
||||
#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \
|
||||
do { \
|
||||
unsigned _src_bkt, _dst_bkt; \
|
||||
void *_last_elt=NULL, *_elt; \
|
||||
UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \
|
||||
ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \
|
||||
if (src) { \
|
||||
for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \
|
||||
for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \
|
||||
_src_hh; \
|
||||
_src_hh = _src_hh->hh_next) { \
|
||||
_elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
|
||||
if (cond(_elt)) { \
|
||||
_dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \
|
||||
_dst_hh->key = _src_hh->key; \
|
||||
_dst_hh->keylen = _src_hh->keylen; \
|
||||
_dst_hh->hashv = _src_hh->hashv; \
|
||||
_dst_hh->prev = _last_elt; \
|
||||
_dst_hh->next = NULL; \
|
||||
if (_last_elt_hh) { _last_elt_hh->next = _elt; } \
|
||||
if (!dst) { \
|
||||
dst = TYPEOF(dst)_elt; \
|
||||
HASH_MAKE_TABLE(hh_dst,dst); \
|
||||
} else { \
|
||||
_dst_hh->tbl = (dst)->hh_dst.tbl; \
|
||||
} \
|
||||
HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \
|
||||
HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \
|
||||
(dst)->hh_dst.tbl->num_items++; \
|
||||
_last_elt = _elt; \
|
||||
_last_elt_hh = _dst_hh; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
HASH_FSCK(hh_dst,dst); \
|
||||
} while (0)
|
||||
|
||||
#define HASH_CLEAR(hh,head) \
|
||||
do { \
|
||||
if (head) { \
|
||||
uthash_free((head)->hh.tbl->buckets ); \
|
||||
uthash_free((head)->hh.tbl); \
|
||||
(head)=NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* obtain a count of items in the hash */
|
||||
#define HASH_COUNT(head) HASH_CNT(hh,head)
|
||||
#define HASH_CNT(hh,head) (head?(head->hh.tbl->num_items):0)
|
||||
|
||||
typedef struct UT_hash_bucket {
|
||||
struct UT_hash_handle *hh_head;
|
||||
unsigned count;
|
||||
|
||||
/* expand_mult is normally set to 0. In this situation, the max chain length
|
||||
* threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If
|
||||
* the bucket's chain exceeds this length, bucket expansion is triggered).
|
||||
* However, setting expand_mult to a non-zero value delays bucket expansion
|
||||
* (that would be triggered by additions to this particular bucket)
|
||||
* until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.
|
||||
* (The multiplier is simply expand_mult+1). The whole idea of this
|
||||
* multiplier is to reduce bucket expansions, since they are expensive, in
|
||||
* situations where we know that a particular bucket tends to be overused.
|
||||
* It is better to let its chain length grow to a longer yet-still-bounded
|
||||
* value, than to do an O(n) bucket expansion too often.
|
||||
*/
|
||||
unsigned expand_mult;
|
||||
|
||||
} UT_hash_bucket;
|
||||
|
||||
/* random signature used only to find hash tables in external analysis */
|
||||
#define HASH_SIGNATURE 0xa0111fe1
|
||||
#define HASH_BLOOM_SIGNATURE 0xb12220f2
|
||||
|
||||
typedef struct UT_hash_table {
|
||||
UT_hash_bucket *buckets;
|
||||
unsigned num_buckets, log2_num_buckets;
|
||||
unsigned num_items;
|
||||
struct UT_hash_handle *tail; /* tail hh in app order, for fast append */
|
||||
ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
|
||||
|
||||
/* in an ideal situation (all buckets used equally), no bucket would have
|
||||
* more than ceil(#items/#buckets) items. that's the ideal chain length. */
|
||||
unsigned ideal_chain_maxlen;
|
||||
|
||||
/* nonideal_items is the number of items in the hash whose chain position
|
||||
* exceeds the ideal chain maxlen. these items pay the penalty for an uneven
|
||||
* hash distribution; reaching them in a chain traversal takes >ideal steps */
|
||||
unsigned nonideal_items;
|
||||
|
||||
/* ineffective expands occur when a bucket doubling was performed, but
|
||||
* afterward, more than half the items in the hash had nonideal chain
|
||||
* positions. If this happens on two consecutive expansions we inhibit any
|
||||
* further expansion, as it's not helping; this happens when the hash
|
||||
* function isn't a good fit for the key domain. When expansion is inhibited
|
||||
* the hash will still work, albeit no longer in constant time. */
|
||||
unsigned ineff_expands, noexpand;
|
||||
|
||||
uint32_t signature; /* used only to find hash tables in external analysis */
|
||||
#if defined(HASH_BLOOM)
|
||||
uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
|
||||
uint8_t *bloom_bv;
|
||||
char bloom_nbits;
|
||||
#endif
|
||||
|
||||
} UT_hash_table;
|
||||
|
||||
typedef struct UT_hash_handle {
|
||||
struct UT_hash_table *tbl;
|
||||
void *prev; /* prev element in app order */
|
||||
void *next; /* next element in app order */
|
||||
struct UT_hash_handle *hh_prev; /* previous hh in bucket order */
|
||||
struct UT_hash_handle *hh_next; /* next hh in bucket order */
|
||||
void *key; /* ptr to enclosing struct's key */
|
||||
unsigned keylen; /* enclosing struct's key len */
|
||||
unsigned hashv; /* result of hash-fcn(key) */
|
||||
} UT_hash_handle;
|
||||
|
||||
#endif /* UTHASH_H */
|
@ -1,32 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef ZLIB_UTIL_H
|
||||
#define ZLIB_UTIL_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include "ms_stdint.h"
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* Attempts to decompress given deflated NUL-terminated buffer.
|
||||
*
|
||||
* If successful and |len| is not NULL, |len| will be set to the number of
|
||||
* bytes in the returned buffer.
|
||||
* Returns new string to be free()'d by caller, or NULL on error. */
|
||||
uint8_t *zlib_decompress(const uint8_t *buf, size_t *len);
|
||||
|
||||
/* Attempt to compress given buffer.
|
||||
*
|
||||
* The compression level is passed directly to zlib: it must between 0 and 9,
|
||||
* where 1 gives best speed, 9 gives best compression, and 0 gives no
|
||||
* compression at all.
|
||||
*
|
||||
* If successful and |len| is not NULL, |len| will be set to the number of
|
||||
* bytes in the returned buffer.
|
||||
* Returns new string to be free()'d by caller, or NULL on error. */
|
||||
uint8_t *zlib_compress(const uint8_t *buf, const size_t buflen, int level,
|
||||
size_t *len);
|
||||
|
||||
#endif /* ZLIB_UTIL_H */
|
@ -1,98 +0,0 @@
|
||||
#include "zlib_util.h"
|
||||
#include <zlib.h>
|
||||
#include <stdio.h> /* fprintf() */
|
||||
#include <stdlib.h> /* malloc() */
|
||||
#include <assert.h>
|
||||
|
||||
#define ZLIB_CHUNK (16 * 1024)
|
||||
|
||||
uint8_t *zlib_decompress(const uint8_t *buf, size_t *len){
|
||||
size_t output_size = ZLIB_CHUNK;
|
||||
uint8_t *output = malloc(output_size);
|
||||
int err;
|
||||
z_stream zst;
|
||||
|
||||
/* Sanity check */
|
||||
if (output == NULL) return NULL;
|
||||
assert(buf != NULL);
|
||||
|
||||
/* Set inflate state */
|
||||
zst.zalloc = Z_NULL;
|
||||
zst.zfree = Z_NULL;
|
||||
zst.opaque = Z_NULL;
|
||||
zst.next_out = (Byte *)output;
|
||||
zst.next_in = (Byte *)buf;
|
||||
zst.avail_out = ZLIB_CHUNK;
|
||||
|
||||
if (inflateInit(&zst) != Z_OK) goto error;
|
||||
|
||||
/* Decompress input buffer */
|
||||
do {
|
||||
if ((err = inflate(&zst, Z_NO_FLUSH)) == Z_OK) { /* Need more memory */
|
||||
zst.avail_out = (uInt)output_size;
|
||||
|
||||
/* Double size each time to avoid calls to realloc() */
|
||||
output_size <<= 1;
|
||||
output = realloc(output, output_size + 1);
|
||||
if (output == NULL) return NULL;
|
||||
|
||||
zst.next_out = (Byte *)(output + zst.avail_out);
|
||||
} else if (err != Z_STREAM_END) { /* Error decompressing */
|
||||
if (zst.msg != NULL) {
|
||||
fprintf(stderr, "Could not decompress data: %s\n", zst.msg);
|
||||
}
|
||||
inflateEnd(&zst);
|
||||
goto error;
|
||||
}
|
||||
} while (err != Z_STREAM_END);
|
||||
|
||||
if (len != NULL) *len = zst.total_out;
|
||||
if (inflateEnd(&zst) != Z_OK) goto error;
|
||||
return output; /* To be free()'d by caller */
|
||||
|
||||
error:
|
||||
if (output != NULL) free(output);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t *zlib_compress(const uint8_t *buf, const size_t buflen, int level,
|
||||
size_t *len)
|
||||
{
|
||||
z_stream zst;
|
||||
uint8_t *output = NULL;
|
||||
|
||||
/* Sanity check */
|
||||
assert(buf != NULL);
|
||||
assert(len != NULL);
|
||||
assert(level <= 9 && level >= 0);
|
||||
|
||||
zst.avail_out = (uInt)((buflen + (buflen / 10)) + 12);
|
||||
output = malloc(zst.avail_out);
|
||||
if (output == NULL) return NULL;
|
||||
|
||||
/* Set deflate state */
|
||||
zst.zalloc = Z_NULL;
|
||||
zst.zfree = Z_NULL;
|
||||
zst.next_out = (Byte *)output;
|
||||
zst.next_in = (Byte *)buf;
|
||||
zst.avail_in = (uInt)buflen;
|
||||
|
||||
if (deflateInit(&zst, level) != Z_OK) goto error;
|
||||
|
||||
/* Compress input buffer */
|
||||
if (deflate(&zst, Z_FINISH) != Z_STREAM_END) {
|
||||
if (zst.msg != NULL) {
|
||||
fprintf(stderr, "Could not compress data: %s\n", zst.msg);
|
||||
}
|
||||
deflateEnd(&zst);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (len != NULL) *len = zst.total_out;
|
||||
if (deflateEnd(&zst) != Z_OK) goto error;
|
||||
return output; /* To be free()'d by caller */
|
||||
|
||||
error:
|
||||
if (output != NULL) free(output);
|
||||
return NULL;
|
||||
}
|
550
bitmap.go
550
bitmap.go
@ -1,550 +0,0 @@
|
||||
// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// https://github.com/go-vgo/robotgo/blob/master/LICENSE
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
package robotgo
|
||||
|
||||
/*
|
||||
#cgo darwin,amd64 LDFLAGS:-L${SRCDIR}/cdeps/mac/amd -lpng -lz
|
||||
#cgo darwin,arm64 LDFLAGS:-L${SRCDIR}/cdeps/mac/m1 -lpng -lz
|
||||
//
|
||||
#cgo linux LDFLAGS: -L/usr/src -lpng -lz
|
||||
//
|
||||
#cgo windows,amd64 LDFLAGS: -L${SRCDIR}/cdeps/win/amd/win64 -lpng -lz
|
||||
#cgo windows,386 LDFLAGS: -L${SRCDIR}/cdeps/win/amd/win32 -lpng -lz
|
||||
#cgo windows,arm64 LDFLAGS:-L${SRCDIR}/cdeps/win/arm -lpng -lz
|
||||
//
|
||||
//#include "screen/goScreen.h"
|
||||
#include "bitmap/goBitmap.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/vcaesar/tt"
|
||||
)
|
||||
|
||||
/*
|
||||
.______ __ .___________..___ ___. ___ .______
|
||||
| _ \ | | | || \/ | / \ | _ \
|
||||
| |_) | | | `---| |----`| \ / | / ^ \ | |_) |
|
||||
| _ < | | | | | |\/| | / /_\ \ | ___/
|
||||
| |_) | | | | | | | | | / _____ \ | |
|
||||
|______/ |__| |__| |__| |__| /__/ \__\ | _|
|
||||
*/
|
||||
|
||||
// SaveCapture capture screen and save
|
||||
func SaveCapture(spath string, args ...int) string {
|
||||
bit := CaptureScreen(args...)
|
||||
|
||||
err := SaveBitmap(bit, spath)
|
||||
FreeBitmap(bit)
|
||||
return err
|
||||
}
|
||||
|
||||
// FreeBitmapArr free and dealloc the C bitmap array
|
||||
func FreeBitmapArr(bit ...C.MMBitmapRef) {
|
||||
for i := 0; i < len(bit); i++ {
|
||||
FreeBitmap(bit[i])
|
||||
}
|
||||
}
|
||||
|
||||
// ToCBitmap trans Bitmap to C.MMBitmapRef
|
||||
func ToCBitmap(bit Bitmap) C.MMBitmapRef {
|
||||
cbitmap := C.createMMBitmap(
|
||||
(*C.uint8_t)(bit.ImgBuf),
|
||||
C.size_t(bit.Width),
|
||||
C.size_t(bit.Height),
|
||||
C.size_t(bit.Bytewidth),
|
||||
C.uint8_t(bit.BitsPixel),
|
||||
C.uint8_t(bit.BytesPerPixel),
|
||||
)
|
||||
|
||||
return cbitmap
|
||||
}
|
||||
|
||||
// ToMMBitmapRef trans CBitmap to C.MMBitmapRef
|
||||
func ToMMBitmapRef(bit CBitmap) C.MMBitmapRef {
|
||||
return C.MMBitmapRef(bit)
|
||||
}
|
||||
|
||||
// ToBitmapBytes saves Bitmap to bitmap format in bytes
|
||||
func ToBitmapBytes(bit C.MMBitmapRef) []byte {
|
||||
var len C.size_t
|
||||
ptr := C.saveMMBitmapAsBytes(bit, &len)
|
||||
if int(len) < 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
bs := C.GoBytes(unsafe.Pointer(ptr), C.int(len))
|
||||
C.free(unsafe.Pointer(ptr))
|
||||
return bs
|
||||
}
|
||||
|
||||
// TostringBitmap tostring bitmap to string
|
||||
func TostringBitmap(bit C.MMBitmapRef) string {
|
||||
strBit := C.tostring_bitmap(bit)
|
||||
return C.GoString(strBit)
|
||||
}
|
||||
|
||||
// TocharBitmap tostring bitmap to C.char
|
||||
func TocharBitmap(bit C.MMBitmapRef) *C.char {
|
||||
strBit := C.tostring_bitmap(bit)
|
||||
return strBit
|
||||
}
|
||||
|
||||
func internalFindBitmap(bit, sbit C.MMBitmapRef, tolerance float64) (int, int) {
|
||||
pos := C.find_bitmap(bit, sbit, C.float(tolerance))
|
||||
// fmt.Println("pos----", pos)
|
||||
return int(pos.x), int(pos.y)
|
||||
}
|
||||
|
||||
// FindCBitmap find bitmap's pos by CBitmap
|
||||
func FindCBitmap(bmp CBitmap, args ...interface{}) (int, int) {
|
||||
return FindBitmap(ToMMBitmapRef(bmp), args...)
|
||||
}
|
||||
|
||||
// FindBitmap find the bitmap's pos
|
||||
//
|
||||
// robotgo.FindBitmap(bitmap, source_bitamp C.MMBitmapRef, tolerance float64)
|
||||
//
|
||||
// |tolerance| should be in the range 0.0f - 1.0f, denoting how closely the
|
||||
// colors in the bitmaps need to match, with 0 being exact and 1 being any.
|
||||
//
|
||||
// This method only automatically free the internal bitmap,
|
||||
// use `defer robotgo.FreeBitmap(bit)` to free the bitmap
|
||||
func FindBitmap(bit C.MMBitmapRef, args ...interface{}) (int, int) {
|
||||
var (
|
||||
sbit C.MMBitmapRef
|
||||
tolerance = 0.01
|
||||
)
|
||||
|
||||
if len(args) > 0 && args[0] != nil {
|
||||
sbit = args[0].(C.MMBitmapRef)
|
||||
} else {
|
||||
sbit = CaptureScreen()
|
||||
}
|
||||
|
||||
if len(args) > 1 {
|
||||
tolerance = args[1].(float64)
|
||||
}
|
||||
|
||||
fx, fy := internalFindBitmap(bit, sbit, tolerance)
|
||||
// FreeBitmap(bit)
|
||||
if len(args) <= 0 || (len(args) > 0 && args[0] == nil) {
|
||||
FreeBitmap(sbit)
|
||||
}
|
||||
|
||||
return fx, fy
|
||||
}
|
||||
|
||||
// FindPic finding the image by path
|
||||
//
|
||||
// robotgo.FindPic(path string, source_bitamp C.MMBitmapRef, tolerance float64)
|
||||
//
|
||||
// This method only automatically free the internal bitmap,
|
||||
// use `defer robotgo.FreeBitmap(bit)` to free the bitmap
|
||||
func FindPic(path string, args ...interface{}) (int, int) {
|
||||
var (
|
||||
sbit C.MMBitmapRef
|
||||
tolerance = 0.01
|
||||
)
|
||||
|
||||
openbit := OpenBitmap(path)
|
||||
|
||||
if len(args) > 0 && args[0] != nil {
|
||||
sbit = args[0].(C.MMBitmapRef)
|
||||
} else {
|
||||
sbit = CaptureScreen()
|
||||
}
|
||||
|
||||
if len(args) > 1 {
|
||||
tolerance = args[1].(float64)
|
||||
}
|
||||
|
||||
fx, fy := internalFindBitmap(openbit, sbit, tolerance)
|
||||
FreeBitmap(openbit)
|
||||
if len(args) <= 0 || (len(args) > 0 && args[0] == nil) {
|
||||
FreeBitmap(sbit)
|
||||
}
|
||||
|
||||
return fx, fy
|
||||
}
|
||||
|
||||
// FreeMMPointArr free MMPoint array
|
||||
func FreeMMPointArr(pointArray C.MMPointArrayRef) {
|
||||
C.destroyMMPointArray(pointArray)
|
||||
}
|
||||
|
||||
// Deprecated: use the FindAllBitmap(),
|
||||
//
|
||||
// FindEveryBitmap find the every bitmap, same with the FindAllBitmap()
|
||||
func FindEveryBitmap(bit C.MMBitmapRef, args ...interface{}) []Point {
|
||||
return FindAllBitmap(bit, args...)
|
||||
}
|
||||
|
||||
// FindAllBitmap find the all bitmap
|
||||
func FindAllBitmap(bit C.MMBitmapRef, args ...interface{}) (posArr []Point) {
|
||||
var (
|
||||
sbit C.MMBitmapRef
|
||||
tolerance C.float = 0.01
|
||||
lpos C.MMPoint
|
||||
)
|
||||
|
||||
if len(args) > 0 && args[0] != nil {
|
||||
sbit = args[0].(C.MMBitmapRef)
|
||||
} else {
|
||||
sbit = CaptureScreen()
|
||||
}
|
||||
|
||||
if len(args) > 1 {
|
||||
tolerance = C.float(args[1].(float64))
|
||||
}
|
||||
|
||||
if len(args) > 2 {
|
||||
lpos.x = C.size_t(args[2].(int))
|
||||
lpos.y = 0
|
||||
} else {
|
||||
lpos.x = 0
|
||||
lpos.y = 0
|
||||
}
|
||||
|
||||
if len(args) > 3 {
|
||||
lpos.x = C.size_t(args[2].(int))
|
||||
lpos.y = C.size_t(args[3].(int))
|
||||
}
|
||||
|
||||
pos := C.find_every_bitmap(bit, sbit, tolerance, &lpos)
|
||||
// FreeBitmap(bit)
|
||||
if len(args) <= 0 || (len(args) > 0 && args[0] == nil) {
|
||||
FreeBitmap(sbit)
|
||||
}
|
||||
if pos == nil {
|
||||
return
|
||||
}
|
||||
defer FreeMMPointArr(pos)
|
||||
|
||||
cSize := pos.count
|
||||
cArray := pos.array
|
||||
gSlice := (*[(1 << 28) - 1]C.MMPoint)(unsafe.Pointer(cArray))[:cSize:cSize]
|
||||
for i := 0; i < len(gSlice); i++ {
|
||||
posArr = append(posArr, Point{
|
||||
X: int(gSlice[i].x),
|
||||
Y: int(gSlice[i].y),
|
||||
})
|
||||
}
|
||||
|
||||
// fmt.Println("pos----", pos)
|
||||
return
|
||||
}
|
||||
|
||||
// CountBitmap count of the bitmap
|
||||
func CountBitmap(bitmap, sbit C.MMBitmapRef, args ...float32) int {
|
||||
var tolerance C.float = 0.01
|
||||
if len(args) > 0 {
|
||||
tolerance = C.float(args[0])
|
||||
}
|
||||
|
||||
count := C.count_of_bitmap(bitmap, sbit, tolerance)
|
||||
return int(count)
|
||||
}
|
||||
|
||||
// BitmapClick find the bitmap and click
|
||||
func BitmapClick(bitmap C.MMBitmapRef, args ...interface{}) {
|
||||
x, y := FindBitmap(bitmap)
|
||||
MovesClick(x, y, args...)
|
||||
}
|
||||
|
||||
// PointInBounds bitmap point in bounds
|
||||
func PointInBounds(bitmap C.MMBitmapRef, x, y int) bool {
|
||||
var point C.MMPoint
|
||||
point.x = C.size_t(x)
|
||||
point.y = C.size_t(y)
|
||||
cbool := C.point_in_bounds(bitmap, point)
|
||||
|
||||
return bool(cbool)
|
||||
}
|
||||
|
||||
// OpenBitmap open the bitmap return C.MMBitmapRef
|
||||
//
|
||||
// robotgo.OpenBitmap(path string, type int)
|
||||
func OpenBitmap(gpath string, args ...int) C.MMBitmapRef {
|
||||
path := C.CString(gpath)
|
||||
var mtype C.uint16_t = 1
|
||||
|
||||
if len(args) > 0 {
|
||||
mtype = C.uint16_t(args[0])
|
||||
}
|
||||
|
||||
bit := C.bitmap_open(path, mtype)
|
||||
C.free(unsafe.Pointer(path))
|
||||
|
||||
return bit
|
||||
}
|
||||
|
||||
// Deprecated: use the BitmapFromStr(),
|
||||
//
|
||||
// BitmapStr bitmap from string
|
||||
func BitmapStr(str string) C.MMBitmapRef {
|
||||
return BitmapFromStr(str)
|
||||
}
|
||||
|
||||
// BitmapFromStr read bitmap from the string
|
||||
func BitmapFromStr(str string) C.MMBitmapRef {
|
||||
cs := C.CString(str)
|
||||
bit := C.bitmap_from_string(cs)
|
||||
C.free(unsafe.Pointer(cs))
|
||||
|
||||
return bit
|
||||
}
|
||||
|
||||
// SaveBitmap save the bitmap to image
|
||||
//
|
||||
// robotgo.SaveBimap(bitmap C.MMBitmapRef, path string, type int)
|
||||
func SaveBitmap(bitmap C.MMBitmapRef, gpath string, args ...int) string {
|
||||
var mtype C.uint16_t = 1
|
||||
if len(args) > 0 {
|
||||
mtype = C.uint16_t(args[0])
|
||||
}
|
||||
|
||||
path := C.CString(gpath)
|
||||
saveBit := C.bitmap_save(bitmap, path, mtype)
|
||||
C.free(unsafe.Pointer(path))
|
||||
|
||||
return C.GoString(saveBit)
|
||||
}
|
||||
|
||||
// GetPortion get bitmap portion
|
||||
func GetPortion(bit C.MMBitmapRef, x, y, w, h int) C.MMBitmapRef {
|
||||
var rect C.MMRect
|
||||
rect.origin.x = C.size_t(x)
|
||||
rect.origin.y = C.size_t(y)
|
||||
rect.size.width = C.size_t(w)
|
||||
rect.size.height = C.size_t(h)
|
||||
|
||||
pos := C.get_portion(bit, rect)
|
||||
return pos
|
||||
}
|
||||
|
||||
// Convert convert the bitmap
|
||||
//
|
||||
// robotgo.Convert(opath, spath string, type int)
|
||||
func Convert(opath, spath string, args ...int) string {
|
||||
var mtype = 1
|
||||
if len(args) > 0 {
|
||||
mtype = args[0]
|
||||
}
|
||||
|
||||
// C.CString()
|
||||
bitmap := OpenBitmap(opath)
|
||||
// fmt.Println("a----", bit_map)
|
||||
return SaveBitmap(bitmap, spath, mtype)
|
||||
}
|
||||
|
||||
// ReadBitmap returns false and sets error if |bitmap| is NULL
|
||||
func ReadBitmap(bitmap C.MMBitmapRef) bool {
|
||||
abool := C.bitmap_ready(bitmap)
|
||||
gbool := bool(abool)
|
||||
return gbool
|
||||
}
|
||||
|
||||
// CopyBitPB copy bitmap to pasteboard
|
||||
func CopyBitPB(bitmap C.MMBitmapRef) bool {
|
||||
abool := C.bitmap_copy_to_pboard(bitmap)
|
||||
gbool := bool(abool)
|
||||
|
||||
return gbool
|
||||
}
|
||||
|
||||
// Deprecated: CopyBitpb copy bitmap to pasteboard, Wno-deprecated
|
||||
//
|
||||
// This function will be removed in version v1.0.0
|
||||
func CopyBitpb(bitmap C.MMBitmapRef) bool {
|
||||
tt.Drop("CopyBitpb", "CopyBitPB")
|
||||
return CopyBitPB(bitmap)
|
||||
}
|
||||
|
||||
// DeepCopyBit deep copy bitmap
|
||||
func DeepCopyBit(bitmap C.MMBitmapRef) C.MMBitmapRef {
|
||||
bit := C.bitmap_deepcopy(bitmap)
|
||||
return bit
|
||||
}
|
||||
|
||||
// GetColor get the bitmap color
|
||||
func GetColor(bitmap C.MMBitmapRef, x, y int) C.MMRGBHex {
|
||||
color := C.bitmap_get_color(bitmap, C.size_t(x), C.size_t(y))
|
||||
|
||||
return color
|
||||
}
|
||||
|
||||
// GetColors get bitmap color retrun string
|
||||
func GetColors(bitmap C.MMBitmapRef, x, y int) string {
|
||||
clo := GetColor(bitmap, x, y)
|
||||
|
||||
return PadHex(clo)
|
||||
}
|
||||
|
||||
// FindColor find bitmap color
|
||||
//
|
||||
// robotgo.FindColor(color CHex, bitmap C.MMBitmapRef, tolerance float)
|
||||
func FindColor(color CHex, args ...interface{}) (int, int) {
|
||||
var (
|
||||
tolerance C.float = 0.01
|
||||
bitmap C.MMBitmapRef
|
||||
)
|
||||
|
||||
if len(args) > 0 && args[0] != nil {
|
||||
bitmap = args[0].(C.MMBitmapRef)
|
||||
} else {
|
||||
bitmap = CaptureScreen()
|
||||
}
|
||||
|
||||
if len(args) > 1 {
|
||||
tolerance = C.float(args[1].(float64))
|
||||
}
|
||||
|
||||
pos := C.bitmap_find_color(bitmap, C.MMRGBHex(color), tolerance)
|
||||
if len(args) <= 0 || (len(args) > 0 && args[0] == nil) {
|
||||
FreeBitmap(bitmap)
|
||||
}
|
||||
|
||||
x := int(pos.x)
|
||||
y := int(pos.y)
|
||||
|
||||
return x, y
|
||||
}
|
||||
|
||||
// FindColorCS findcolor by CaptureScreen
|
||||
func FindColorCS(color CHex, x, y, w, h int, args ...float64) (int, int) {
|
||||
var tolerance = 0.01
|
||||
|
||||
if len(args) > 0 {
|
||||
tolerance = args[0]
|
||||
}
|
||||
|
||||
bitmap := CaptureScreen(x, y, w, h)
|
||||
rx, ry := FindColor(color, bitmap, tolerance)
|
||||
FreeBitmap(bitmap)
|
||||
|
||||
return rx, ry
|
||||
}
|
||||
|
||||
// Deprecated: use the FindAllColor(),
|
||||
//
|
||||
// FindEveryColor find the every color, same with the FindAllColor()
|
||||
func FindEveryColor(color CHex, args ...interface{}) []Point {
|
||||
return FindAllColor(color, args...)
|
||||
}
|
||||
|
||||
// FindAllColor find the all color
|
||||
func FindAllColor(color CHex, args ...interface{}) (posArr []Point) {
|
||||
var (
|
||||
bitmap C.MMBitmapRef
|
||||
tolerance C.float = 0.01
|
||||
lpos C.MMPoint
|
||||
)
|
||||
|
||||
if len(args) > 0 && args[0] != nil {
|
||||
bitmap = args[0].(C.MMBitmapRef)
|
||||
} else {
|
||||
bitmap = CaptureScreen()
|
||||
}
|
||||
|
||||
if len(args) > 1 {
|
||||
tolerance = C.float(args[1].(float64))
|
||||
}
|
||||
|
||||
if len(args) > 2 {
|
||||
lpos.x = C.size_t(args[2].(int))
|
||||
lpos.y = 0
|
||||
} else {
|
||||
lpos.x = 0
|
||||
lpos.y = 0
|
||||
}
|
||||
|
||||
if len(args) > 3 {
|
||||
lpos.x = C.size_t(args[2].(int))
|
||||
lpos.y = C.size_t(args[3].(int))
|
||||
}
|
||||
|
||||
pos := C.bitmap_find_every_color(bitmap, C.MMRGBHex(color), tolerance, &lpos)
|
||||
if len(args) <= 0 || (len(args) > 0 && args[0] == nil) {
|
||||
FreeBitmap(bitmap)
|
||||
}
|
||||
|
||||
if pos == nil {
|
||||
return
|
||||
}
|
||||
defer FreeMMPointArr(pos)
|
||||
|
||||
cSize := pos.count
|
||||
cArray := pos.array
|
||||
gSlice := (*[(1 << 28) - 1]C.MMPoint)(unsafe.Pointer(cArray))[:cSize:cSize]
|
||||
for i := 0; i < len(gSlice); i++ {
|
||||
posArr = append(posArr, Point{
|
||||
X: int(gSlice[i].x),
|
||||
Y: int(gSlice[i].y),
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CountColor count bitmap color
|
||||
func CountColor(color CHex, args ...interface{}) int {
|
||||
var (
|
||||
tolerance C.float = 0.01
|
||||
bitmap C.MMBitmapRef
|
||||
)
|
||||
|
||||
if len(args) > 0 && args[0] != nil {
|
||||
bitmap = args[0].(C.MMBitmapRef)
|
||||
} else {
|
||||
bitmap = CaptureScreen()
|
||||
}
|
||||
|
||||
if len(args) > 1 {
|
||||
tolerance = C.float(args[1].(float64))
|
||||
}
|
||||
|
||||
count := C.bitmap_count_of_color(bitmap, C.MMRGBHex(color), tolerance)
|
||||
if len(args) <= 0 || (len(args) > 0 && args[0] == nil) {
|
||||
FreeBitmap(bitmap)
|
||||
}
|
||||
|
||||
return int(count)
|
||||
}
|
||||
|
||||
// CountColorCS count bitmap color by CaptureScreen
|
||||
func CountColorCS(color CHex, x, y, w, h int, args ...float64) int {
|
||||
var tolerance = 0.01
|
||||
|
||||
if len(args) > 0 {
|
||||
tolerance = args[0]
|
||||
}
|
||||
|
||||
bitmap := CaptureScreen(x, y, w, h)
|
||||
rx := CountColor(color, bitmap, tolerance)
|
||||
FreeBitmap(bitmap)
|
||||
|
||||
return rx
|
||||
}
|
||||
|
||||
// GetImgSize get the image size
|
||||
func GetImgSize(imgPath string) (int, int) {
|
||||
bitmap := OpenBitmap(imgPath)
|
||||
gbit := ToBitmap(bitmap)
|
||||
|
||||
w := gbit.Width / 2
|
||||
h := gbit.Height / 2
|
||||
FreeBitmap(bitmap)
|
||||
|
||||
return w, h
|
||||
}
|
@ -1 +0,0 @@
|
||||
C language dependent package, better to compilation. ( zlib and libpng )
|
Binary file not shown.
Binary file not shown.
3278
cdeps/mac/png.h
3278
cdeps/mac/png.h
File diff suppressed because it is too large
Load Diff
@ -1,622 +0,0 @@
|
||||
|
||||
/* pngconf.h - machine configurable file for libpng
|
||||
*
|
||||
* libpng version 1.6.34, September 29, 2017
|
||||
*
|
||||
* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*
|
||||
* Any machine specific code is near the front of this file, so if you
|
||||
* are configuring libpng for a machine, you may want to read the section
|
||||
* starting here down to where it starts to typedef png_color, png_text,
|
||||
* and png_info.
|
||||
*/
|
||||
|
||||
#ifndef PNGCONF_H
|
||||
#define PNGCONF_H
|
||||
|
||||
#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */
|
||||
|
||||
/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C
|
||||
* compiler for correct compilation. The following header files are required by
|
||||
* the standard. If your compiler doesn't provide these header files, or they
|
||||
* do not match the standard, you will need to provide/improve them.
|
||||
*/
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* Library header files. These header files are all defined by ISOC90; libpng
|
||||
* expects conformant implementations, however, an ISOC90 conformant system need
|
||||
* not provide these header files if the functionality cannot be implemented.
|
||||
* In this case it will be necessary to disable the relevant parts of libpng in
|
||||
* the build of pnglibconf.h.
|
||||
*
|
||||
* Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not
|
||||
* include this unnecessary header file.
|
||||
*/
|
||||
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
/* Required for the definition of FILE: */
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
/* Required for the definition of jmp_buf and the declaration of longjmp: */
|
||||
# include <setjmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef PNG_CONVERT_tIME_SUPPORTED
|
||||
/* Required for struct tm: */
|
||||
# include <time.h>
|
||||
#endif
|
||||
|
||||
#endif /* PNG_BUILDING_SYMBOL_TABLE */
|
||||
|
||||
/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using
|
||||
* PNG_NO_CONST; this is no longer supported except for data declarations which
|
||||
* apparently still cause problems in 2011 on some compilers.
|
||||
*/
|
||||
#define PNG_CONST const /* backward compatibility only */
|
||||
|
||||
/* This controls optimization of the reading of 16-bit and 32-bit values
|
||||
* from PNG files. It can be set on a per-app-file basis - it
|
||||
* just changes whether a macro is used when the function is called.
|
||||
* The library builder sets the default; if read functions are not
|
||||
* built into the library the macro implementation is forced on.
|
||||
*/
|
||||
#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED
|
||||
# define PNG_USE_READ_MACROS
|
||||
#endif
|
||||
#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS)
|
||||
# if PNG_DEFAULT_READ_MACROS
|
||||
# define PNG_USE_READ_MACROS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* COMPILER SPECIFIC OPTIONS.
|
||||
*
|
||||
* These options are provided so that a variety of difficult compilers
|
||||
* can be used. Some are fixed at build time (e.g. PNG_API_RULE
|
||||
* below) but still have compiler specific implementations, others
|
||||
* may be changed on a per-file basis when compiling against libpng.
|
||||
*/
|
||||
|
||||
/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect
|
||||
* against legacy (pre ISOC90) compilers that did not understand function
|
||||
* prototypes. It is not required for modern C compilers.
|
||||
*/
|
||||
#ifndef PNGARG
|
||||
# define PNGARG(arglist) arglist
|
||||
#endif
|
||||
|
||||
/* Function calling conventions.
|
||||
* =============================
|
||||
* Normally it is not necessary to specify to the compiler how to call
|
||||
* a function - it just does it - however on x86 systems derived from
|
||||
* Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems
|
||||
* and some others) there are multiple ways to call a function and the
|
||||
* default can be changed on the compiler command line. For this reason
|
||||
* libpng specifies the calling convention of every exported function and
|
||||
* every function called via a user supplied function pointer. This is
|
||||
* done in this file by defining the following macros:
|
||||
*
|
||||
* PNGAPI Calling convention for exported functions.
|
||||
* PNGCBAPI Calling convention for user provided (callback) functions.
|
||||
* PNGCAPI Calling convention used by the ANSI-C library (required
|
||||
* for longjmp callbacks and sometimes used internally to
|
||||
* specify the calling convention for zlib).
|
||||
*
|
||||
* These macros should never be overridden. If it is necessary to
|
||||
* change calling convention in a private build this can be done
|
||||
* by setting PNG_API_RULE (which defaults to 0) to one of the values
|
||||
* below to select the correct 'API' variants.
|
||||
*
|
||||
* PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout.
|
||||
* This is correct in every known environment.
|
||||
* PNG_API_RULE=1 Use the operating system convention for PNGAPI and
|
||||
* the 'C' calling convention (from PNGCAPI) for
|
||||
* callbacks (PNGCBAPI). This is no longer required
|
||||
* in any known environment - if it has to be used
|
||||
* please post an explanation of the problem to the
|
||||
* libpng mailing list.
|
||||
*
|
||||
* These cases only differ if the operating system does not use the C
|
||||
* calling convention, at present this just means the above cases
|
||||
* (x86 DOS/Windows sytems) and, even then, this does not apply to
|
||||
* Cygwin running on those systems.
|
||||
*
|
||||
* Note that the value must be defined in pnglibconf.h so that what
|
||||
* the application uses to call the library matches the conventions
|
||||
* set when building the library.
|
||||
*/
|
||||
|
||||
/* Symbol export
|
||||
* =============
|
||||
* When building a shared library it is almost always necessary to tell
|
||||
* the compiler which symbols to export. The png.h macro 'PNG_EXPORT'
|
||||
* is used to mark the symbols. On some systems these symbols can be
|
||||
* extracted at link time and need no special processing by the compiler,
|
||||
* on other systems the symbols are flagged by the compiler and just
|
||||
* the declaration requires a special tag applied (unfortunately) in a
|
||||
* compiler dependent way. Some systems can do either.
|
||||
*
|
||||
* A small number of older systems also require a symbol from a DLL to
|
||||
* be flagged to the program that calls it. This is a problem because
|
||||
* we do not know in the header file included by application code that
|
||||
* the symbol will come from a shared library, as opposed to a statically
|
||||
* linked one. For this reason the application must tell us by setting
|
||||
* the magic flag PNG_USE_DLL to turn on the special processing before
|
||||
* it includes png.h.
|
||||
*
|
||||
* Four additional macros are used to make this happen:
|
||||
*
|
||||
* PNG_IMPEXP The magic (if any) to cause a symbol to be exported from
|
||||
* the build or imported if PNG_USE_DLL is set - compiler
|
||||
* and system specific.
|
||||
*
|
||||
* PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to
|
||||
* 'type', compiler specific.
|
||||
*
|
||||
* PNG_DLL_EXPORT Set to the magic to use during a libpng build to
|
||||
* make a symbol exported from the DLL. Not used in the
|
||||
* public header files; see pngpriv.h for how it is used
|
||||
* in the libpng build.
|
||||
*
|
||||
* PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come
|
||||
* from a DLL - used to define PNG_IMPEXP when
|
||||
* PNG_USE_DLL is set.
|
||||
*/
|
||||
|
||||
/* System specific discovery.
|
||||
* ==========================
|
||||
* This code is used at build time to find PNG_IMPEXP, the API settings
|
||||
* and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL
|
||||
* import processing is possible. On Windows systems it also sets
|
||||
* compiler-specific macros to the values required to change the calling
|
||||
* conventions of the various functions.
|
||||
*/
|
||||
#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\
|
||||
defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
||||
/* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or
|
||||
* MinGW on any architecture currently supported by Windows. Also includes
|
||||
* Watcom builds but these need special treatment because they are not
|
||||
* compatible with GCC or Visual C because of different calling conventions.
|
||||
*/
|
||||
# if PNG_API_RULE == 2
|
||||
/* If this line results in an error, either because __watcall is not
|
||||
* understood or because of a redefine just below you cannot use *this*
|
||||
* build of the library with the compiler you are using. *This* build was
|
||||
* build using Watcom and applications must also be built using Watcom!
|
||||
*/
|
||||
# define PNGCAPI __watcall
|
||||
# endif
|
||||
|
||||
# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
|
||||
# define PNGCAPI __cdecl
|
||||
# if PNG_API_RULE == 1
|
||||
/* If this line results in an error __stdcall is not understood and
|
||||
* PNG_API_RULE should not have been set to '1'.
|
||||
*/
|
||||
# define PNGAPI __stdcall
|
||||
# endif
|
||||
# else
|
||||
/* An older compiler, or one not detected (erroneously) above,
|
||||
* if necessary override on the command line to get the correct
|
||||
* variants for the compiler.
|
||||
*/
|
||||
# ifndef PNGCAPI
|
||||
# define PNGCAPI _cdecl
|
||||
# endif
|
||||
# if PNG_API_RULE == 1 && !defined(PNGAPI)
|
||||
# define PNGAPI _stdcall
|
||||
# endif
|
||||
# endif /* compiler/api */
|
||||
|
||||
/* NOTE: PNGCBAPI always defaults to PNGCAPI. */
|
||||
|
||||
# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)
|
||||
# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed"
|
||||
# endif
|
||||
|
||||
# if (defined(_MSC_VER) && _MSC_VER < 800) ||\
|
||||
(defined(__BORLANDC__) && __BORLANDC__ < 0x500)
|
||||
/* older Borland and MSC
|
||||
* compilers used '__export' and required this to be after
|
||||
* the type.
|
||||
*/
|
||||
# ifndef PNG_EXPORT_TYPE
|
||||
# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
|
||||
# endif
|
||||
# define PNG_DLL_EXPORT __export
|
||||
# else /* newer compiler */
|
||||
# define PNG_DLL_EXPORT __declspec(dllexport)
|
||||
# ifndef PNG_DLL_IMPORT
|
||||
# define PNG_DLL_IMPORT __declspec(dllimport)
|
||||
# endif
|
||||
# endif /* compiler */
|
||||
|
||||
#else /* !Windows */
|
||||
# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
|
||||
# define PNGAPI _System
|
||||
# else /* !Windows/x86 && !OS/2 */
|
||||
/* Use the defaults, or define PNG*API on the command line (but
|
||||
* this will have to be done for every compile!)
|
||||
*/
|
||||
# endif /* other system, !OS/2 */
|
||||
#endif /* !Windows/x86 */
|
||||
|
||||
/* Now do all the defaulting . */
|
||||
#ifndef PNGCAPI
|
||||
# define PNGCAPI
|
||||
#endif
|
||||
#ifndef PNGCBAPI
|
||||
# define PNGCBAPI PNGCAPI
|
||||
#endif
|
||||
#ifndef PNGAPI
|
||||
# define PNGAPI PNGCAPI
|
||||
#endif
|
||||
|
||||
/* PNG_IMPEXP may be set on the compilation system command line or (if not set)
|
||||
* then in an internal header file when building the library, otherwise (when
|
||||
* using the library) it is set here.
|
||||
*/
|
||||
#ifndef PNG_IMPEXP
|
||||
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
|
||||
/* This forces use of a DLL, disallowing static linking */
|
||||
# define PNG_IMPEXP PNG_DLL_IMPORT
|
||||
# endif
|
||||
|
||||
# ifndef PNG_IMPEXP
|
||||
# define PNG_IMPEXP
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat
|
||||
* 'attributes' as a storage class - the attributes go at the start of the
|
||||
* function definition, and attributes are always appended regardless of the
|
||||
* compiler. This considerably simplifies these macros but may cause problems
|
||||
* if any compilers both need function attributes and fail to handle them as
|
||||
* a storage class (this is unlikely.)
|
||||
*/
|
||||
#ifndef PNG_FUNCTION
|
||||
# define PNG_FUNCTION(type, name, args, attributes) attributes type name args
|
||||
#endif
|
||||
|
||||
#ifndef PNG_EXPORT_TYPE
|
||||
# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type
|
||||
#endif
|
||||
|
||||
/* The ordinal value is only relevant when preprocessing png.h for symbol
|
||||
* table entries, so we discard it here. See the .dfn files in the
|
||||
* scripts directory.
|
||||
*/
|
||||
|
||||
#ifndef PNG_EXPORTA
|
||||
# define PNG_EXPORTA(ordinal, type, name, args, attributes) \
|
||||
PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), PNGARG(args), \
|
||||
PNG_LINKAGE_API attributes)
|
||||
#endif
|
||||
|
||||
/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,
|
||||
* so make something non-empty to satisfy the requirement:
|
||||
*/
|
||||
#define PNG_EMPTY /*empty list*/
|
||||
|
||||
#define PNG_EXPORT(ordinal, type, name, args) \
|
||||
PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)
|
||||
|
||||
/* Use PNG_REMOVED to comment out a removed interface. */
|
||||
#ifndef PNG_REMOVED
|
||||
# define PNG_REMOVED(ordinal, type, name, args, attributes)
|
||||
#endif
|
||||
|
||||
#ifndef PNG_CALLBACK
|
||||
# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)
|
||||
#endif
|
||||
|
||||
/* Support for compiler specific function attributes. These are used
|
||||
* so that where compiler support is available incorrect use of API
|
||||
* functions in png.h will generate compiler warnings.
|
||||
*
|
||||
* Added at libpng-1.2.41.
|
||||
*/
|
||||
|
||||
#ifndef PNG_NO_PEDANTIC_WARNINGS
|
||||
# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
|
||||
# define PNG_PEDANTIC_WARNINGS_SUPPORTED
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
|
||||
/* Support for compiler specific function attributes. These are used
|
||||
* so that where compiler support is available, incorrect use of API
|
||||
* functions in png.h will generate compiler warnings. Added at libpng
|
||||
* version 1.2.41. Disabling these removes the warnings but may also produce
|
||||
* less efficient code.
|
||||
*/
|
||||
# if defined(__clang__) && defined(__has_attribute)
|
||||
/* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
|
||||
# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
|
||||
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
|
||||
# endif
|
||||
# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__)
|
||||
# define PNG_NORETURN __attribute__((__noreturn__))
|
||||
# endif
|
||||
# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__)
|
||||
# define PNG_ALLOCATED __attribute__((__malloc__))
|
||||
# endif
|
||||
# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__)
|
||||
# define PNG_DEPRECATED __attribute__((__deprecated__))
|
||||
# endif
|
||||
# if !defined(PNG_PRIVATE)
|
||||
# ifdef __has_extension
|
||||
# if __has_extension(attribute_unavailable_with_message)
|
||||
# define PNG_PRIVATE __attribute__((__unavailable__(\
|
||||
"This function is not exported by libpng.")))
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# ifndef PNG_RESTRICT
|
||||
# define PNG_RESTRICT __restrict
|
||||
# endif
|
||||
|
||||
# elif defined(__GNUC__)
|
||||
# ifndef PNG_USE_RESULT
|
||||
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
|
||||
# endif
|
||||
# ifndef PNG_NORETURN
|
||||
# define PNG_NORETURN __attribute__((__noreturn__))
|
||||
# endif
|
||||
# if __GNUC__ >= 3
|
||||
# ifndef PNG_ALLOCATED
|
||||
# define PNG_ALLOCATED __attribute__((__malloc__))
|
||||
# endif
|
||||
# ifndef PNG_DEPRECATED
|
||||
# define PNG_DEPRECATED __attribute__((__deprecated__))
|
||||
# endif
|
||||
# ifndef PNG_PRIVATE
|
||||
# if 0 /* Doesn't work so we use deprecated instead*/
|
||||
# define PNG_PRIVATE \
|
||||
__attribute__((warning("This function is not exported by libpng.")))
|
||||
# else
|
||||
# define PNG_PRIVATE \
|
||||
__attribute__((__deprecated__))
|
||||
# endif
|
||||
# endif
|
||||
# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1))
|
||||
# ifndef PNG_RESTRICT
|
||||
# define PNG_RESTRICT __restrict
|
||||
# endif
|
||||
# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */
|
||||
# endif /* __GNUC__ >= 3 */
|
||||
|
||||
# elif defined(_MSC_VER) && (_MSC_VER >= 1300)
|
||||
# ifndef PNG_USE_RESULT
|
||||
# define PNG_USE_RESULT /* not supported */
|
||||
# endif
|
||||
# ifndef PNG_NORETURN
|
||||
# define PNG_NORETURN __declspec(noreturn)
|
||||
# endif
|
||||
# ifndef PNG_ALLOCATED
|
||||
# if (_MSC_VER >= 1400)
|
||||
# define PNG_ALLOCATED __declspec(restrict)
|
||||
# endif
|
||||
# endif
|
||||
# ifndef PNG_DEPRECATED
|
||||
# define PNG_DEPRECATED __declspec(deprecated)
|
||||
# endif
|
||||
# ifndef PNG_PRIVATE
|
||||
# define PNG_PRIVATE __declspec(deprecated)
|
||||
# endif
|
||||
# ifndef PNG_RESTRICT
|
||||
# if (_MSC_VER >= 1400)
|
||||
# define PNG_RESTRICT __restrict
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# elif defined(__WATCOMC__)
|
||||
# ifndef PNG_RESTRICT
|
||||
# define PNG_RESTRICT __restrict
|
||||
# endif
|
||||
# endif
|
||||
#endif /* PNG_PEDANTIC_WARNINGS */
|
||||
|
||||
#ifndef PNG_DEPRECATED
|
||||
# define PNG_DEPRECATED /* Use of this function is deprecated */
|
||||
#endif
|
||||
#ifndef PNG_USE_RESULT
|
||||
# define PNG_USE_RESULT /* The result of this function must be checked */
|
||||
#endif
|
||||
#ifndef PNG_NORETURN
|
||||
# define PNG_NORETURN /* This function does not return */
|
||||
#endif
|
||||
#ifndef PNG_ALLOCATED
|
||||
# define PNG_ALLOCATED /* The result of the function is new memory */
|
||||
#endif
|
||||
#ifndef PNG_PRIVATE
|
||||
# define PNG_PRIVATE /* This is a private libpng function */
|
||||
#endif
|
||||
#ifndef PNG_RESTRICT
|
||||
# define PNG_RESTRICT /* The C99 "restrict" feature */
|
||||
#endif
|
||||
|
||||
#ifndef PNG_FP_EXPORT /* A floating point API. */
|
||||
# ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
# define PNG_FP_EXPORT(ordinal, type, name, args)\
|
||||
PNG_EXPORT(ordinal, type, name, args);
|
||||
# else /* No floating point APIs */
|
||||
# define PNG_FP_EXPORT(ordinal, type, name, args)
|
||||
# endif
|
||||
#endif
|
||||
#ifndef PNG_FIXED_EXPORT /* A fixed point API. */
|
||||
# ifdef PNG_FIXED_POINT_SUPPORTED
|
||||
# define PNG_FIXED_EXPORT(ordinal, type, name, args)\
|
||||
PNG_EXPORT(ordinal, type, name, args);
|
||||
# else /* No fixed point APIs */
|
||||
# define PNG_FIXED_EXPORT(ordinal, type, name, args)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PNG_BUILDING_SYMBOL_TABLE
|
||||
/* Some typedefs to get us started. These should be safe on most of the common
|
||||
* platforms.
|
||||
*
|
||||
* png_uint_32 and png_int_32 may, currently, be larger than required to hold a
|
||||
* 32-bit value however this is not normally advisable.
|
||||
*
|
||||
* png_uint_16 and png_int_16 should always be two bytes in size - this is
|
||||
* verified at library build time.
|
||||
*
|
||||
* png_byte must always be one byte in size.
|
||||
*
|
||||
* The checks below use constants from limits.h, as defined by the ISOC90
|
||||
* standard.
|
||||
*/
|
||||
#if CHAR_BIT == 8 && UCHAR_MAX == 255
|
||||
typedef unsigned char png_byte;
|
||||
#else
|
||||
# error "libpng requires 8-bit bytes"
|
||||
#endif
|
||||
|
||||
#if INT_MIN == -32768 && INT_MAX == 32767
|
||||
typedef int png_int_16;
|
||||
#elif SHRT_MIN == -32768 && SHRT_MAX == 32767
|
||||
typedef short png_int_16;
|
||||
#else
|
||||
# error "libpng requires a signed 16-bit type"
|
||||
#endif
|
||||
|
||||
#if UINT_MAX == 65535
|
||||
typedef unsigned int png_uint_16;
|
||||
#elif USHRT_MAX == 65535
|
||||
typedef unsigned short png_uint_16;
|
||||
#else
|
||||
# error "libpng requires an unsigned 16-bit type"
|
||||
#endif
|
||||
|
||||
#if INT_MIN < -2147483646 && INT_MAX > 2147483646
|
||||
typedef int png_int_32;
|
||||
#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646
|
||||
typedef long int png_int_32;
|
||||
#else
|
||||
# error "libpng requires a signed 32-bit (or more) type"
|
||||
#endif
|
||||
|
||||
#if UINT_MAX > 4294967294U
|
||||
typedef unsigned int png_uint_32;
|
||||
#elif ULONG_MAX > 4294967294U
|
||||
typedef unsigned long int png_uint_32;
|
||||
#else
|
||||
# error "libpng requires an unsigned 32-bit (or more) type"
|
||||
#endif
|
||||
|
||||
/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however,
|
||||
* requires an ISOC90 compiler and relies on consistent behavior of sizeof.
|
||||
*/
|
||||
typedef size_t png_size_t;
|
||||
typedef ptrdiff_t png_ptrdiff_t;
|
||||
|
||||
/* libpng needs to know the maximum value of 'size_t' and this controls the
|
||||
* definition of png_alloc_size_t, below. This maximum value of size_t limits
|
||||
* but does not control the maximum allocations the library makes - there is
|
||||
* direct application control of this through png_set_user_limits().
|
||||
*/
|
||||
#ifndef PNG_SMALL_SIZE_T
|
||||
/* Compiler specific tests for systems where size_t is known to be less than
|
||||
* 32 bits (some of these systems may no longer work because of the lack of
|
||||
* 'far' support; see above.)
|
||||
*/
|
||||
# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\
|
||||
(defined(_MSC_VER) && defined(MAXSEG_64K))
|
||||
# define PNG_SMALL_SIZE_T
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no
|
||||
* smaller than png_uint_32. Casts from png_size_t or png_uint_32 to
|
||||
* png_alloc_size_t are not necessary; in fact, it is recommended not to use
|
||||
* them at all so that the compiler can complain when something turns out to be
|
||||
* problematic.
|
||||
*
|
||||
* Casts in the other direction (from png_alloc_size_t to png_size_t or
|
||||
* png_uint_32) should be explicitly applied; however, we do not expect to
|
||||
* encounter practical situations that require such conversions.
|
||||
*
|
||||
* PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than
|
||||
* 4294967295 - i.e. less than the maximum value of png_uint_32.
|
||||
*/
|
||||
#ifdef PNG_SMALL_SIZE_T
|
||||
typedef png_uint_32 png_alloc_size_t;
|
||||
#else
|
||||
typedef png_size_t png_alloc_size_t;
|
||||
#endif
|
||||
|
||||
/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler
|
||||
* implementations of Intel CPU specific support of user-mode segmented address
|
||||
* spaces, where 16-bit pointers address more than 65536 bytes of memory using
|
||||
* separate 'segment' registers. The implementation requires two different
|
||||
* types of pointer (only one of which includes the segment value.)
|
||||
*
|
||||
* If required this support is available in version 1.2 of libpng and may be
|
||||
* available in versions through 1.5, although the correctness of the code has
|
||||
* not been verified recently.
|
||||
*/
|
||||
|
||||
/* Typedef for floating-point numbers that are converted to fixed-point with a
|
||||
* multiple of 100,000, e.g., gamma
|
||||
*/
|
||||
typedef png_int_32 png_fixed_point;
|
||||
|
||||
/* Add typedefs for pointers */
|
||||
typedef void * png_voidp;
|
||||
typedef const void * png_const_voidp;
|
||||
typedef png_byte * png_bytep;
|
||||
typedef const png_byte * png_const_bytep;
|
||||
typedef png_uint_32 * png_uint_32p;
|
||||
typedef const png_uint_32 * png_const_uint_32p;
|
||||
typedef png_int_32 * png_int_32p;
|
||||
typedef const png_int_32 * png_const_int_32p;
|
||||
typedef png_uint_16 * png_uint_16p;
|
||||
typedef const png_uint_16 * png_const_uint_16p;
|
||||
typedef png_int_16 * png_int_16p;
|
||||
typedef const png_int_16 * png_const_int_16p;
|
||||
typedef char * png_charp;
|
||||
typedef const char * png_const_charp;
|
||||
typedef png_fixed_point * png_fixed_point_p;
|
||||
typedef const png_fixed_point * png_const_fixed_point_p;
|
||||
typedef png_size_t * png_size_tp;
|
||||
typedef const png_size_t * png_const_size_tp;
|
||||
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
typedef FILE * png_FILE_p;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
typedef double * png_doublep;
|
||||
typedef const double * png_const_doublep;
|
||||
#endif
|
||||
|
||||
/* Pointers to pointers; i.e. arrays */
|
||||
typedef png_byte * * png_bytepp;
|
||||
typedef png_uint_32 * * png_uint_32pp;
|
||||
typedef png_int_32 * * png_int_32pp;
|
||||
typedef png_uint_16 * * png_uint_16pp;
|
||||
typedef png_int_16 * * png_int_16pp;
|
||||
typedef const char * * png_const_charpp;
|
||||
typedef char * * png_charpp;
|
||||
typedef png_fixed_point * * png_fixed_point_pp;
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
typedef double * * png_doublepp;
|
||||
#endif
|
||||
|
||||
/* Pointers to pointers to pointers; i.e., pointer to array */
|
||||
typedef char * * * png_charppp;
|
||||
|
||||
#endif /* PNG_BUILDING_SYMBOL_TABLE */
|
||||
|
||||
#endif /* PNGCONF_H */
|
@ -1,218 +0,0 @@
|
||||
/* pnglibconf.h - library build configuration */
|
||||
|
||||
/* libpng version 1.6.34, September 29, 2017 */
|
||||
|
||||
/* Copyright (c) 1998-2017 Glenn Randers-Pehrson */
|
||||
|
||||
/* This code is released under the libpng license. */
|
||||
/* For conditions of distribution and use, see the disclaimer */
|
||||
/* and license in png.h */
|
||||
|
||||
/* pnglibconf.h */
|
||||
/* Machine generated file: DO NOT EDIT */
|
||||
/* Derived from: scripts/pnglibconf.dfa */
|
||||
#ifndef PNGLCONF_H
|
||||
#define PNGLCONF_H
|
||||
/* options */
|
||||
#define PNG_16BIT_SUPPORTED
|
||||
#define PNG_ALIGNED_MEMORY_SUPPORTED
|
||||
/*#undef PNG_ARM_NEON_API_SUPPORTED*/
|
||||
/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/
|
||||
#define PNG_BENIGN_ERRORS_SUPPORTED
|
||||
#define PNG_BENIGN_READ_ERRORS_SUPPORTED
|
||||
/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
|
||||
#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
|
||||
#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
|
||||
#define PNG_COLORSPACE_SUPPORTED
|
||||
#define PNG_CONSOLE_IO_SUPPORTED
|
||||
#define PNG_CONVERT_tIME_SUPPORTED
|
||||
#define PNG_EASY_ACCESS_SUPPORTED
|
||||
/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
|
||||
#define PNG_ERROR_TEXT_SUPPORTED
|
||||
#define PNG_FIXED_POINT_SUPPORTED
|
||||
#define PNG_FLOATING_ARITHMETIC_SUPPORTED
|
||||
#define PNG_FLOATING_POINT_SUPPORTED
|
||||
#define PNG_FORMAT_AFIRST_SUPPORTED
|
||||
#define PNG_FORMAT_BGR_SUPPORTED
|
||||
#define PNG_GAMMA_SUPPORTED
|
||||
#define PNG_GET_PALETTE_MAX_SUPPORTED
|
||||
#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
|
||||
#define PNG_INCH_CONVERSIONS_SUPPORTED
|
||||
#define PNG_INFO_IMAGE_SUPPORTED
|
||||
#define PNG_IO_STATE_SUPPORTED
|
||||
#define PNG_MNG_FEATURES_SUPPORTED
|
||||
#define PNG_POINTER_INDEXING_SUPPORTED
|
||||
/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/
|
||||
/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/
|
||||
#define PNG_PROGRESSIVE_READ_SUPPORTED
|
||||
#define PNG_READ_16BIT_SUPPORTED
|
||||
#define PNG_READ_ALPHA_MODE_SUPPORTED
|
||||
#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
|
||||
#define PNG_READ_BACKGROUND_SUPPORTED
|
||||
#define PNG_READ_BGR_SUPPORTED
|
||||
#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
|
||||
#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
|
||||
#define PNG_READ_COMPRESSED_TEXT_SUPPORTED
|
||||
#define PNG_READ_EXPAND_16_SUPPORTED
|
||||
#define PNG_READ_EXPAND_SUPPORTED
|
||||
#define PNG_READ_FILLER_SUPPORTED
|
||||
#define PNG_READ_GAMMA_SUPPORTED
|
||||
#define PNG_READ_GET_PALETTE_MAX_SUPPORTED
|
||||
#define PNG_READ_GRAY_TO_RGB_SUPPORTED
|
||||
#define PNG_READ_INTERLACING_SUPPORTED
|
||||
#define PNG_READ_INT_FUNCTIONS_SUPPORTED
|
||||
#define PNG_READ_INVERT_ALPHA_SUPPORTED
|
||||
#define PNG_READ_INVERT_SUPPORTED
|
||||
#define PNG_READ_OPT_PLTE_SUPPORTED
|
||||
#define PNG_READ_PACKSWAP_SUPPORTED
|
||||
#define PNG_READ_PACK_SUPPORTED
|
||||
#define PNG_READ_QUANTIZE_SUPPORTED
|
||||
#define PNG_READ_RGB_TO_GRAY_SUPPORTED
|
||||
#define PNG_READ_SCALE_16_TO_8_SUPPORTED
|
||||
#define PNG_READ_SHIFT_SUPPORTED
|
||||
#define PNG_READ_STRIP_16_TO_8_SUPPORTED
|
||||
#define PNG_READ_STRIP_ALPHA_SUPPORTED
|
||||
#define PNG_READ_SUPPORTED
|
||||
#define PNG_READ_SWAP_ALPHA_SUPPORTED
|
||||
#define PNG_READ_SWAP_SUPPORTED
|
||||
#define PNG_READ_TEXT_SUPPORTED
|
||||
#define PNG_READ_TRANSFORMS_SUPPORTED
|
||||
#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_READ_USER_CHUNKS_SUPPORTED
|
||||
#define PNG_READ_USER_TRANSFORM_SUPPORTED
|
||||
#define PNG_READ_bKGD_SUPPORTED
|
||||
#define PNG_READ_cHRM_SUPPORTED
|
||||
#define PNG_READ_eXIf_SUPPORTED
|
||||
#define PNG_READ_gAMA_SUPPORTED
|
||||
#define PNG_READ_hIST_SUPPORTED
|
||||
#define PNG_READ_iCCP_SUPPORTED
|
||||
#define PNG_READ_iTXt_SUPPORTED
|
||||
#define PNG_READ_oFFs_SUPPORTED
|
||||
#define PNG_READ_pCAL_SUPPORTED
|
||||
#define PNG_READ_pHYs_SUPPORTED
|
||||
#define PNG_READ_sBIT_SUPPORTED
|
||||
#define PNG_READ_sCAL_SUPPORTED
|
||||
#define PNG_READ_sPLT_SUPPORTED
|
||||
#define PNG_READ_sRGB_SUPPORTED
|
||||
#define PNG_READ_tEXt_SUPPORTED
|
||||
#define PNG_READ_tIME_SUPPORTED
|
||||
#define PNG_READ_tRNS_SUPPORTED
|
||||
#define PNG_READ_zTXt_SUPPORTED
|
||||
#define PNG_SAVE_INT_32_SUPPORTED
|
||||
#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_SEQUENTIAL_READ_SUPPORTED
|
||||
#define PNG_SETJMP_SUPPORTED
|
||||
#define PNG_SET_OPTION_SUPPORTED
|
||||
#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_SET_USER_LIMITS_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_READ_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_WRITE_SUPPORTED
|
||||
#define PNG_STDIO_SUPPORTED
|
||||
#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_TEXT_SUPPORTED
|
||||
#define PNG_TIME_RFC1123_SUPPORTED
|
||||
#define PNG_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_USER_CHUNKS_SUPPORTED
|
||||
#define PNG_USER_LIMITS_SUPPORTED
|
||||
#define PNG_USER_MEM_SUPPORTED
|
||||
#define PNG_USER_TRANSFORM_INFO_SUPPORTED
|
||||
#define PNG_USER_TRANSFORM_PTR_SUPPORTED
|
||||
#define PNG_WARNINGS_SUPPORTED
|
||||
#define PNG_WRITE_16BIT_SUPPORTED
|
||||
#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
|
||||
#define PNG_WRITE_BGR_SUPPORTED
|
||||
#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
|
||||
#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
|
||||
#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
|
||||
#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
|
||||
#define PNG_WRITE_FILLER_SUPPORTED
|
||||
#define PNG_WRITE_FILTER_SUPPORTED
|
||||
#define PNG_WRITE_FLUSH_SUPPORTED
|
||||
#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED
|
||||
#define PNG_WRITE_INTERLACING_SUPPORTED
|
||||
#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
|
||||
#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
||||
#define PNG_WRITE_INVERT_SUPPORTED
|
||||
#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
|
||||
#define PNG_WRITE_PACKSWAP_SUPPORTED
|
||||
#define PNG_WRITE_PACK_SUPPORTED
|
||||
#define PNG_WRITE_SHIFT_SUPPORTED
|
||||
#define PNG_WRITE_SUPPORTED
|
||||
#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
|
||||
#define PNG_WRITE_SWAP_SUPPORTED
|
||||
#define PNG_WRITE_TEXT_SUPPORTED
|
||||
#define PNG_WRITE_TRANSFORMS_SUPPORTED
|
||||
#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
|
||||
#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
|
||||
#define PNG_WRITE_bKGD_SUPPORTED
|
||||
#define PNG_WRITE_cHRM_SUPPORTED
|
||||
#define PNG_WRITE_eXIf_SUPPORTED
|
||||
#define PNG_WRITE_gAMA_SUPPORTED
|
||||
#define PNG_WRITE_hIST_SUPPORTED
|
||||
#define PNG_WRITE_iCCP_SUPPORTED
|
||||
#define PNG_WRITE_iTXt_SUPPORTED
|
||||
#define PNG_WRITE_oFFs_SUPPORTED
|
||||
#define PNG_WRITE_pCAL_SUPPORTED
|
||||
#define PNG_WRITE_pHYs_SUPPORTED
|
||||
#define PNG_WRITE_sBIT_SUPPORTED
|
||||
#define PNG_WRITE_sCAL_SUPPORTED
|
||||
#define PNG_WRITE_sPLT_SUPPORTED
|
||||
#define PNG_WRITE_sRGB_SUPPORTED
|
||||
#define PNG_WRITE_tEXt_SUPPORTED
|
||||
#define PNG_WRITE_tIME_SUPPORTED
|
||||
#define PNG_WRITE_tRNS_SUPPORTED
|
||||
#define PNG_WRITE_zTXt_SUPPORTED
|
||||
#define PNG_bKGD_SUPPORTED
|
||||
#define PNG_cHRM_SUPPORTED
|
||||
#define PNG_eXIf_SUPPORTED
|
||||
#define PNG_gAMA_SUPPORTED
|
||||
#define PNG_hIST_SUPPORTED
|
||||
#define PNG_iCCP_SUPPORTED
|
||||
#define PNG_iTXt_SUPPORTED
|
||||
#define PNG_oFFs_SUPPORTED
|
||||
#define PNG_pCAL_SUPPORTED
|
||||
#define PNG_pHYs_SUPPORTED
|
||||
#define PNG_sBIT_SUPPORTED
|
||||
#define PNG_sCAL_SUPPORTED
|
||||
#define PNG_sPLT_SUPPORTED
|
||||
#define PNG_sRGB_SUPPORTED
|
||||
#define PNG_tEXt_SUPPORTED
|
||||
#define PNG_tIME_SUPPORTED
|
||||
#define PNG_tRNS_SUPPORTED
|
||||
#define PNG_zTXt_SUPPORTED
|
||||
/* end of options */
|
||||
/* settings */
|
||||
#define PNG_API_RULE 0
|
||||
#define PNG_DEFAULT_READ_MACROS 1
|
||||
#define PNG_GAMMA_THRESHOLD_FIXED 5000
|
||||
#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
|
||||
#define PNG_INFLATE_BUF_SIZE 1024
|
||||
#define PNG_LINKAGE_API extern
|
||||
#define PNG_LINKAGE_CALLBACK extern
|
||||
#define PNG_LINKAGE_DATA extern
|
||||
#define PNG_LINKAGE_FUNCTION extern
|
||||
#define PNG_MAX_GAMMA_8 11
|
||||
#define PNG_QUANTIZE_BLUE_BITS 5
|
||||
#define PNG_QUANTIZE_GREEN_BITS 5
|
||||
#define PNG_QUANTIZE_RED_BITS 5
|
||||
#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
|
||||
#define PNG_TEXT_Z_DEFAULT_STRATEGY 0
|
||||
#define PNG_USER_CHUNK_CACHE_MAX 1000
|
||||
#define PNG_USER_CHUNK_MALLOC_MAX 8000000
|
||||
#define PNG_USER_HEIGHT_MAX 1000000
|
||||
#define PNG_USER_WIDTH_MAX 1000000
|
||||
#define PNG_ZBUF_SIZE 8192
|
||||
#define PNG_ZLIB_VERNUM 0x12b0
|
||||
#define PNG_Z_DEFAULT_COMPRESSION (-1)
|
||||
#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
|
||||
#define PNG_Z_DEFAULT_STRATEGY 1
|
||||
#define PNG_sCAL_PRECISION 5
|
||||
#define PNG_sRGB_PROFILE_CHECKS 2
|
||||
/* end of settings */
|
||||
#endif /* PNGLCONF_H */
|
Binary file not shown.
Binary file not shown.
2309
cdeps/win/png.h
2309
cdeps/win/png.h
File diff suppressed because it is too large
Load Diff
@ -1,649 +0,0 @@
|
||||
|
||||
/* pngconf.h - machine configurable file for libpng
|
||||
*
|
||||
* libpng version 1.5.2 - March 31, 2011
|
||||
*
|
||||
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*
|
||||
*/
|
||||
|
||||
/* Any machine specific code is near the front of this file, so if you
|
||||
* are configuring libpng for a machine, you may want to read the section
|
||||
* starting here down to where it starts to typedef png_color, png_text,
|
||||
* and png_info.
|
||||
*/
|
||||
|
||||
#ifndef PNGCONF_H
|
||||
#define PNGCONF_H
|
||||
|
||||
#ifndef PNG_BUILDING_SYMBOL_TABLE
|
||||
/* PNG_NO_LIMITS_H may be used to turn off the use of the standard C
|
||||
* definition file for machine specific limits, this may impact the
|
||||
* correctness of the definitons below (see uses of INT_MAX).
|
||||
*/
|
||||
# ifndef PNG_NO_LIMITS_H
|
||||
# include <limits.h>
|
||||
# endif
|
||||
|
||||
/* For the memory copy APIs (i.e. the standard definitions of these),
|
||||
* because this file defines png_memcpy and so on the base APIs must
|
||||
* be defined here.
|
||||
*/
|
||||
# ifdef BSD
|
||||
# include <strings.h>
|
||||
# else
|
||||
# include <string.h>
|
||||
# endif
|
||||
|
||||
/* For png_FILE_p - this provides the standard definition of a
|
||||
* FILE
|
||||
*/
|
||||
# ifdef PNG_STDIO_SUPPORTED
|
||||
# include <stdio.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* This controls optimization of the reading of 16 and 32 bit values
|
||||
* from PNG files. It can be set on a per-app-file basis - it
|
||||
* just changes whether a macro is used to the function is called.
|
||||
* The library builder sets the default, if read functions are not
|
||||
* built into the library the macro implementation is forced on.
|
||||
*/
|
||||
#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED
|
||||
# define PNG_USE_READ_MACROS
|
||||
#endif
|
||||
#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS)
|
||||
# if PNG_DEFAULT_READ_MACROS
|
||||
# define PNG_USE_READ_MACROS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* COMPILER SPECIFIC OPTIONS.
|
||||
*
|
||||
* These options are provided so that a variety of difficult compilers
|
||||
* can be used. Some are fixed at build time (e.g. PNG_API_RULE
|
||||
* below) but still have compiler specific implementations, others
|
||||
* may be changed on a per-file basis when compiling against libpng.
|
||||
*/
|
||||
|
||||
/* The PNGARG macro protects us against machines that don't have function
|
||||
* prototypes (ie K&R style headers). If your compiler does not handle
|
||||
* function prototypes, define this macro and use the included ansi2knr.
|
||||
* I've always been able to use _NO_PROTO as the indicator, but you may
|
||||
* need to drag the empty declaration out in front of here, or change the
|
||||
* ifdef to suit your own needs.
|
||||
*/
|
||||
#ifndef PNGARG
|
||||
|
||||
# ifdef OF /* zlib prototype munger */
|
||||
# define PNGARG(arglist) OF(arglist)
|
||||
# else
|
||||
|
||||
# ifdef _NO_PROTO
|
||||
# define PNGARG(arglist) ()
|
||||
# else
|
||||
# define PNGARG(arglist) arglist
|
||||
# endif /* _NO_PROTO */
|
||||
|
||||
# endif /* OF */
|
||||
|
||||
#endif /* PNGARG */
|
||||
|
||||
/* Function calling conventions.
|
||||
* =============================
|
||||
* Normally it is not necessary to specify to the compiler how to call
|
||||
* a function - it just does it - however on x86 systems derived from
|
||||
* Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems
|
||||
* and some others) there are multiple ways to call a function and the
|
||||
* default can be changed on the compiler command line. For this reason
|
||||
* libpng specifies the calling convention of every exported function and
|
||||
* every function called via a user supplied function pointer. This is
|
||||
* done in this file by defining the following macros:
|
||||
*
|
||||
* PNGAPI Calling convention for exported functions.
|
||||
* PNGCBAPI Calling convention for user provided (callback) functions.
|
||||
* PNGCAPI Calling convention used by the ANSI-C library (required
|
||||
* for longjmp callbacks and sometimes used internally to
|
||||
* specify the calling convention for zlib).
|
||||
*
|
||||
* These macros should never be overridden. If it is necessary to
|
||||
* change calling convention in a private build this can be done
|
||||
* by setting PNG_API_RULE (which defaults to 0) to one of the values
|
||||
* below to select the correct 'API' variants.
|
||||
*
|
||||
* PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout.
|
||||
* This is correct in every known environment.
|
||||
* PNG_API_RULE=1 Use the operating system convention for PNGAPI and
|
||||
* the 'C' calling convention (from PNGCAPI) for
|
||||
* callbacks (PNGCBAPI). This is no longer required
|
||||
* in any known environment - if it has to be used
|
||||
* please post an explanation of the problem to the
|
||||
* libpng mailing list.
|
||||
*
|
||||
* These cases only differ if the operating system does not use the C
|
||||
* calling convention, at present this just means the above cases
|
||||
* (x86 DOS/Windows sytems) and, even then, this does not apply to
|
||||
* Cygwin running on those systems.
|
||||
*
|
||||
* Note that the value must be defined in pnglibconf.h so that what
|
||||
* the application uses to call the library matches the conventions
|
||||
* set when building the library.
|
||||
*/
|
||||
|
||||
/* Symbol export
|
||||
* =============
|
||||
* When building a shared library it is almost always necessary to tell
|
||||
* the compiler which symbols to export. The png.h macro 'PNG_EXPORT'
|
||||
* is used to mark the symbols. On some systems these symbols can be
|
||||
* extracted at link time and need no special processing by the compiler,
|
||||
* on other systems the symbols are flagged by the compiler and just
|
||||
* the declaration requires a special tag applied (unfortunately) in a
|
||||
* compiler dependent way. Some systems can do either.
|
||||
*
|
||||
* A small number of older systems also require a symbol from a DLL to
|
||||
* be flagged to the program that calls it. This is a problem because
|
||||
* we do not know in the header file included by application code that
|
||||
* the symbol will come from a shared library, as opposed to a statically
|
||||
* linked one. For this reason the application must tell us by setting
|
||||
* the magic flag PNG_USE_DLL to turn on the special processing before
|
||||
* it includes png.h.
|
||||
*
|
||||
* Four additional macros are used to make this happen:
|
||||
*
|
||||
* PNG_IMPEXP The magic (if any) to cause a symbol to be exported from
|
||||
* the build or imported if PNG_USE_DLL is set - compiler
|
||||
* and system specific.
|
||||
*
|
||||
* PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to
|
||||
* 'type', compiler specific.
|
||||
*
|
||||
* PNG_DLL_EXPORT Set to the magic to use during a libpng build to
|
||||
* make a symbol exported from the DLL.
|
||||
*
|
||||
* PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come
|
||||
* from a DLL - used to define PNG_IMPEXP when
|
||||
* PNG_USE_DLL is set.
|
||||
*/
|
||||
|
||||
/* System specific discovery.
|
||||
* ==========================
|
||||
* This code is used at build time to find PNG_IMPEXP, the API settings
|
||||
* and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL
|
||||
* import processing is possible. On Windows/x86 systems it also sets
|
||||
* compiler-specific macros to the values required to change the calling
|
||||
* conventions of the various functions.
|
||||
*/
|
||||
#if ( defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\
|
||||
defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) ) &&\
|
||||
( defined(_X86_) || defined(_X64_) || defined(_M_IX86) ||\
|
||||
defined(_M_X64) || defined(_M_IA64) )
|
||||
/* Windows system (DOS doesn't support DLLs) running on x86/x64. Includes
|
||||
* builds under Cygwin or MinGW. Also includes Watcom builds but these need
|
||||
* special treatment because they are not compatible with GCC or Visual C
|
||||
* because of different calling conventions.
|
||||
*/
|
||||
# if PNG_API_RULE == 2
|
||||
/* If this line results in an error, either because __watcall is not
|
||||
* understood or because of a redefine just below you cannot use *this*
|
||||
* build of the library with the compiler you are using. *This* build was
|
||||
* build using Watcom and applications must also be built using Watcom!
|
||||
*/
|
||||
# define PNGCAPI __watcall
|
||||
# endif
|
||||
|
||||
# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
|
||||
# define PNGCAPI __cdecl
|
||||
# if PNG_API_RULE == 1
|
||||
# define PNGAPI __stdcall
|
||||
# endif
|
||||
# else
|
||||
/* An older compiler, or one not detected (erroneously) above,
|
||||
* if necessary override on the command line to get the correct
|
||||
* variants for the compiler.
|
||||
*/
|
||||
# ifndef PNGCAPI
|
||||
# define PNGCAPI _cdecl
|
||||
# endif
|
||||
# if PNG_API_RULE == 1 && !defined(PNGAPI)
|
||||
# define PNGAPI _stdcall
|
||||
# endif
|
||||
# endif /* compiler/api */
|
||||
/* NOTE: PNGCBAPI always defaults to PNGCAPI. */
|
||||
|
||||
# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)
|
||||
ERROR: PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed
|
||||
# endif
|
||||
|
||||
# if (defined(_MSC_VER) && _MSC_VER < 800) ||\
|
||||
(defined(__BORLANDC__) && __BORLANDC__ < 0x500)
|
||||
/* older Borland and MSC
|
||||
* compilers used '__export' and required this to be after
|
||||
* the type.
|
||||
*/
|
||||
# ifndef PNG_EXPORT_TYPE
|
||||
# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
|
||||
# endif
|
||||
# define PNG_DLL_EXPORT __export
|
||||
# else /* newer compiler */
|
||||
# define PNG_DLL_EXPORT __declspec(dllexport)
|
||||
# ifndef PNG_DLL_IMPORT
|
||||
# define PNG_DLL_IMPORT __declspec(dllimport)
|
||||
# endif
|
||||
# endif /* compiler */
|
||||
|
||||
#else /* !Windows/x86 */
|
||||
# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
|
||||
# define PNGAPI _System
|
||||
# else /* !Windows/x86 && !OS/2 */
|
||||
/* Use the defaults, or define PNG*API on the command line (but
|
||||
* this will have to be done for every compile!)
|
||||
*/
|
||||
# endif /* other system, !OS/2 */
|
||||
#endif /* !Windows/x86 */
|
||||
|
||||
/* Now do all the defaulting . */
|
||||
#ifndef PNGCAPI
|
||||
# define PNGCAPI
|
||||
#endif
|
||||
#ifndef PNGCBAPI
|
||||
# define PNGCBAPI PNGCAPI
|
||||
#endif
|
||||
#ifndef PNGAPI
|
||||
# define PNGAPI PNGCAPI
|
||||
#endif
|
||||
|
||||
/* The default for PNG_IMPEXP depends on whether the library is
|
||||
* being built or used.
|
||||
*/
|
||||
#ifndef PNG_IMPEXP
|
||||
# ifdef PNGLIB_BUILD
|
||||
/* Building the library */
|
||||
# if (defined(DLL_EXPORT)/*from libtool*/ ||\
|
||||
defined(_WINDLL) || defined(_DLL) || defined(__DLL__) ||\
|
||||
defined(_USRDLL) ||\
|
||||
defined(PNG_BUILD_DLL)) && defined(PNG_DLL_EXPORT)
|
||||
/* Building a DLL. */
|
||||
# define PNG_IMPEXP PNG_DLL_EXPORT
|
||||
# endif /* DLL */
|
||||
# else
|
||||
/* Using the library */
|
||||
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
|
||||
/* This forces use of a DLL, disallowing static linking */
|
||||
# define PNG_IMPEXP PNG_DLL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef PNG_IMPEXP
|
||||
# define PNG_IMPEXP
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat
|
||||
* 'attributes' as a storage class - the attributes go at the start of the
|
||||
* function definition, and attributes are always appended regardless of the
|
||||
* compiler. This considerably simplifies these macros but may cause problems
|
||||
* if any compilers both need function attributes and fail to handle them as
|
||||
* a storage class (this is unlikely.)
|
||||
*/
|
||||
#ifndef PNG_FUNCTION
|
||||
# define PNG_FUNCTION(type, name, args, attributes) attributes type name args
|
||||
#endif
|
||||
|
||||
#ifndef PNG_EXPORT_TYPE
|
||||
# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type
|
||||
#endif
|
||||
|
||||
/* The ordinal value is only relevant when preprocessing png.h for symbol
|
||||
* table entries, so we discard it here. See the .dfn files in the
|
||||
* scripts directory.
|
||||
*/
|
||||
#ifndef PNG_EXPORTA
|
||||
|
||||
# define PNG_EXPORTA(ordinal, type, name, args, attributes)\
|
||||
PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \
|
||||
extern attributes)
|
||||
#endif
|
||||
|
||||
/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,
|
||||
* so make something non-empty to satisfy the requirement:
|
||||
*/
|
||||
#define PNG_EMPTY /*empty list*/
|
||||
|
||||
#define PNG_EXPORT(ordinal, type, name, args)\
|
||||
PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)
|
||||
|
||||
/* Use PNG_REMOVED to comment out a removed interface. */
|
||||
#ifndef PNG_REMOVED
|
||||
# define PNG_REMOVED(ordinal, type, name, args, attributes)
|
||||
#endif
|
||||
|
||||
#ifndef PNG_CALLBACK
|
||||
# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)
|
||||
#endif
|
||||
|
||||
/* Support for compiler specific function attributes. These are used
|
||||
* so that where compiler support is available incorrect use of API
|
||||
* functions in png.h will generate compiler warnings.
|
||||
*
|
||||
* Added at libpng-1.2.41.
|
||||
*/
|
||||
|
||||
#ifndef PNG_NO_PEDANTIC_WARNINGS
|
||||
# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
|
||||
# define PNG_PEDANTIC_WARNINGS_SUPPORTED
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
|
||||
/* Support for compiler specific function attributes. These are used
|
||||
* so that where compiler support is available incorrect use of API
|
||||
* functions in png.h will generate compiler warnings. Added at libpng
|
||||
* version 1.2.41.
|
||||
*/
|
||||
# if defined(__GNUC__)
|
||||
# ifndef PNG_USE_RESULT
|
||||
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
|
||||
# endif
|
||||
# ifndef PNG_NORETURN
|
||||
# define PNG_NORETURN __attribute__((__noreturn__))
|
||||
# endif
|
||||
# ifndef PNG_PTR_NORETURN
|
||||
/* It's not enough to have the compiler be the correct compiler at
|
||||
* this point - it's necessary for the library (which defines
|
||||
* the type of the library longjmp) to also be the GNU library.
|
||||
* This is because many systems use the GNU compiler with a
|
||||
* non-GNU libc implementation. Min/GW headers are also compatible
|
||||
* with GCC as well as uclibc, so it seems best to exclude known
|
||||
* problem libcs here rather than just including known libcs.
|
||||
*
|
||||
* NOTE: this relies on the only use of PNG_PTR_NORETURN being with
|
||||
* the system longjmp. If the same type is used elsewhere then this
|
||||
* will need to be changed.
|
||||
*/
|
||||
# if !defined(__CYGWIN__)
|
||||
# define PNG_PTR_NORETURN __attribute__((__noreturn__))
|
||||
# endif
|
||||
# endif
|
||||
# ifndef PNG_ALLOCATED
|
||||
# define PNG_ALLOCATED __attribute__((__malloc__))
|
||||
# endif
|
||||
|
||||
/* This specifically protects structure members that should only be
|
||||
* accessed from within the library, therefore should be empty during
|
||||
* a library build.
|
||||
*/
|
||||
# ifndef PNGLIB_BUILD
|
||||
# ifndef PNG_DEPRECATED
|
||||
# define PNG_DEPRECATED __attribute__((__deprecated__))
|
||||
# endif
|
||||
# ifndef PNG_DEPSTRUCT
|
||||
# define PNG_DEPSTRUCT __attribute__((__deprecated__))
|
||||
# endif
|
||||
# ifndef PNG_PRIVATE
|
||||
# if 0 /* Doesn't work so we use deprecated instead*/
|
||||
# define PNG_PRIVATE \
|
||||
__attribute__((warning("This function is not exported by libpng.")))
|
||||
# else
|
||||
# define PNG_PRIVATE \
|
||||
__attribute__((__deprecated__))
|
||||
# endif
|
||||
# endif
|
||||
# endif /* PNGLIB_BUILD */
|
||||
# endif /* __GNUC__ */
|
||||
|
||||
# if defined(_MSC_VER) && (_MSC_VER >= 1300)
|
||||
# ifndef PNG_USE_RESULT
|
||||
# define PNG_USE_RESULT /* not supported */
|
||||
# endif
|
||||
# ifndef PNG_NORETURN
|
||||
# define PNG_NORETURN __declspec(noreturn)
|
||||
# endif
|
||||
# ifndef PNG_PTR_NORETURN
|
||||
# define PNG_PTR_NORETURN /* not supported */
|
||||
# endif
|
||||
# ifndef PNG_ALLOCATED
|
||||
# define PNG_ALLOCATED __declspec(restrict)
|
||||
# endif
|
||||
|
||||
/* This specifically protects structure members that should only be
|
||||
* accessed from within the library, therefore should be empty during
|
||||
* a library build.
|
||||
*/
|
||||
# ifndef PNGLIB_BUILD
|
||||
# ifndef PNG_DEPRECATED
|
||||
# define PNG_DEPRECATED __declspec(deprecated)
|
||||
# endif
|
||||
# ifndef PNG_DEPSTRUCT
|
||||
# define PNG_DEPSTRUCT __declspec(deprecated)
|
||||
# endif
|
||||
# ifndef PNG_PRIVATE
|
||||
# define PNG_PRIVATE __declspec(deprecated)
|
||||
# endif
|
||||
# endif /* PNGLIB_BUILD */
|
||||
# endif /* _MSC_VER */
|
||||
#endif /* PNG_PEDANTIC_WARNINGS */
|
||||
|
||||
#ifndef PNG_DEPRECATED
|
||||
# define PNG_DEPRECATED /* Use of this function is deprecated */
|
||||
#endif
|
||||
#ifndef PNG_USE_RESULT
|
||||
# define PNG_USE_RESULT /* The result of this function must be checked */
|
||||
#endif
|
||||
#ifndef PNG_NORETURN
|
||||
# define PNG_NORETURN /* This function does not return */
|
||||
#endif
|
||||
#ifndef PNG_PTR_NORETURN
|
||||
# define PNG_PTR_NORETURN /* This function does not return */
|
||||
#endif
|
||||
#ifndef PNG_ALLOCATED
|
||||
# define PNG_ALLOCATED /* The result of the function is new memory */
|
||||
#endif
|
||||
#ifndef PNG_DEPSTRUCT
|
||||
# define PNG_DEPSTRUCT /* Access to this struct member is deprecated */
|
||||
#endif
|
||||
#ifndef PNG_PRIVATE
|
||||
# define PNG_PRIVATE /* This is a private libpng function */
|
||||
#endif
|
||||
#ifndef PNG_FP_EXPORT /* A floating point API. */
|
||||
# ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
# define PNG_FP_EXPORT(ordinal, type, name, args)\
|
||||
PNG_EXPORT(ordinal, type, name, args)
|
||||
# else /* No floating point APIs */
|
||||
# define PNG_FP_EXPORT(ordinal, type, name, args)
|
||||
# endif
|
||||
#endif
|
||||
#ifndef PNG_FIXED_EXPORT /* A fixed point API. */
|
||||
# ifdef PNG_FIXED_POINT_SUPPORTED
|
||||
# define PNG_FIXED_EXPORT(ordinal, type, name, args)\
|
||||
PNG_EXPORT(ordinal, type, name, args)
|
||||
# else /* No fixed point APIs */
|
||||
# define PNG_FIXED_EXPORT(ordinal, type, name, args)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following uses const char * instead of char * for error
|
||||
* and warning message functions, so some compilers won't complain.
|
||||
* If you do not want to use const, define PNG_NO_CONST here.
|
||||
*
|
||||
* This should not change how the APIs are called, so it can be done
|
||||
* on a per-file basis in the application.
|
||||
*/
|
||||
#ifndef PNG_CONST
|
||||
# ifndef PNG_NO_CONST
|
||||
# define PNG_CONST const
|
||||
# else
|
||||
# define PNG_CONST
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some typedefs to get us started. These should be safe on most of the
|
||||
* common platforms. The typedefs should be at least as large as the
|
||||
* numbers suggest (a png_uint_32 must be at least 32 bits long), but they
|
||||
* don't have to be exactly that size. Some compilers dislike passing
|
||||
* unsigned shorts as function parameters, so you may be better off using
|
||||
* unsigned int for png_uint_16.
|
||||
*/
|
||||
|
||||
#if defined(INT_MAX) && (INT_MAX > 0x7ffffffeL)
|
||||
typedef unsigned int png_uint_32;
|
||||
typedef int png_int_32;
|
||||
#else
|
||||
typedef unsigned long png_uint_32;
|
||||
typedef long png_int_32;
|
||||
#endif
|
||||
typedef unsigned short png_uint_16;
|
||||
typedef short png_int_16;
|
||||
typedef unsigned char png_byte;
|
||||
|
||||
#ifdef PNG_NO_SIZE_T
|
||||
typedef unsigned int png_size_t;
|
||||
#else
|
||||
typedef size_t png_size_t;
|
||||
#endif
|
||||
#define png_sizeof(x) (sizeof (x))
|
||||
|
||||
/* The following is needed for medium model support. It cannot be in the
|
||||
* pngpriv.h header. Needs modification for other compilers besides
|
||||
* MSC. Model independent support declares all arrays and pointers to be
|
||||
* large using the far keyword. The zlib version used must also support
|
||||
* model independent data. As of version zlib 1.0.4, the necessary changes
|
||||
* have been made in zlib. The USE_FAR_KEYWORD define triggers other
|
||||
* changes that are needed. (Tim Wegner)
|
||||
*/
|
||||
|
||||
/* Separate compiler dependencies (problem here is that zlib.h always
|
||||
* defines FAR. (SJT)
|
||||
*/
|
||||
#ifdef __BORLANDC__
|
||||
# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
|
||||
# define LDATA 1
|
||||
# else
|
||||
# define LDATA 0
|
||||
# endif
|
||||
/* GRR: why is Cygwin in here? Cygwin is not Borland C... */
|
||||
# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
|
||||
# define PNG_MAX_MALLOC_64K /* only used in build */
|
||||
# if (LDATA != 1)
|
||||
# ifndef FAR
|
||||
# define FAR __far
|
||||
# endif
|
||||
# define USE_FAR_KEYWORD
|
||||
# endif /* LDATA != 1 */
|
||||
/* Possibly useful for moving data out of default segment.
|
||||
* Uncomment it if you want. Could also define FARDATA as
|
||||
* const if your compiler supports it. (SJT)
|
||||
# define FARDATA FAR
|
||||
*/
|
||||
# endif /* __WIN32__, __FLAT__, __CYGWIN__ */
|
||||
#endif /* __BORLANDC__ */
|
||||
|
||||
|
||||
/* Suggest testing for specific compiler first before testing for
|
||||
* FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM,
|
||||
* making reliance oncertain keywords suspect. (SJT)
|
||||
*/
|
||||
|
||||
/* MSC Medium model */
|
||||
#ifdef FAR
|
||||
# ifdef M_I86MM
|
||||
# define USE_FAR_KEYWORD
|
||||
# define FARDATA FAR
|
||||
# include <dos.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* SJT: default case */
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
/* At this point FAR is always defined */
|
||||
#ifndef FARDATA
|
||||
# define FARDATA
|
||||
#endif
|
||||
|
||||
/* Typedef for floating-point numbers that are converted
|
||||
* to fixed-point with a multiple of 100,000, e.g., gamma
|
||||
*/
|
||||
typedef png_int_32 png_fixed_point;
|
||||
|
||||
/* Add typedefs for pointers */
|
||||
typedef void FAR * png_voidp;
|
||||
typedef PNG_CONST void FAR * png_const_voidp;
|
||||
typedef png_byte FAR * png_bytep;
|
||||
typedef PNG_CONST png_byte FAR * png_const_bytep;
|
||||
typedef png_uint_32 FAR * png_uint_32p;
|
||||
typedef PNG_CONST png_uint_32 FAR * png_const_uint_32p;
|
||||
typedef png_int_32 FAR * png_int_32p;
|
||||
typedef PNG_CONST png_int_32 FAR * png_const_int_32p;
|
||||
typedef png_uint_16 FAR * png_uint_16p;
|
||||
typedef PNG_CONST png_uint_16 FAR * png_const_uint_16p;
|
||||
typedef png_int_16 FAR * png_int_16p;
|
||||
typedef PNG_CONST png_int_16 FAR * png_const_int_16p;
|
||||
typedef char FAR * png_charp;
|
||||
typedef PNG_CONST char FAR * png_const_charp;
|
||||
typedef png_fixed_point FAR * png_fixed_point_p;
|
||||
typedef PNG_CONST png_fixed_point FAR * png_const_fixed_point_p;
|
||||
typedef png_size_t FAR * png_size_tp;
|
||||
typedef PNG_CONST png_size_t FAR * png_const_size_tp;
|
||||
|
||||
#ifdef PNG_STDIO_SUPPORTED
|
||||
typedef FILE * png_FILE_p;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
typedef double FAR * png_doublep;
|
||||
typedef PNG_CONST double FAR * png_const_doublep;
|
||||
#endif
|
||||
|
||||
/* Pointers to pointers; i.e. arrays */
|
||||
typedef png_byte FAR * FAR * png_bytepp;
|
||||
typedef png_uint_32 FAR * FAR * png_uint_32pp;
|
||||
typedef png_int_32 FAR * FAR * png_int_32pp;
|
||||
typedef png_uint_16 FAR * FAR * png_uint_16pp;
|
||||
typedef png_int_16 FAR * FAR * png_int_16pp;
|
||||
typedef PNG_CONST char FAR * FAR * png_const_charpp;
|
||||
typedef char FAR * FAR * png_charpp;
|
||||
typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
typedef double FAR * FAR * png_doublepp;
|
||||
#endif
|
||||
|
||||
/* Pointers to pointers to pointers; i.e., pointer to array */
|
||||
typedef char FAR * FAR * FAR * png_charppp;
|
||||
|
||||
/* png_alloc_size_t is guaranteed to be no smaller than png_size_t,
|
||||
* and no smaller than png_uint_32. Casts from png_size_t or png_uint_32
|
||||
* to png_alloc_size_t are not necessary; in fact, it is recommended
|
||||
* not to use them at all so that the compiler can complain when something
|
||||
* turns out to be problematic.
|
||||
* Casts in the other direction (from png_alloc_size_t to png_size_t or
|
||||
* png_uint_32) should be explicitly applied; however, we do not expect
|
||||
* to encounter practical situations that require such conversions.
|
||||
*/
|
||||
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||
typedef unsigned long png_alloc_size_t;
|
||||
#else
|
||||
# if defined(_MSC_VER) && defined(MAXSEG_64K)
|
||||
typedef unsigned long png_alloc_size_t;
|
||||
# else
|
||||
/* This is an attempt to detect an old Windows system where (int) is
|
||||
* actually 16 bits, in that case png_malloc must have an argument with a
|
||||
* bigger size to accomodate the requirements of the library.
|
||||
*/
|
||||
# if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_)) && \
|
||||
(!defined(INT_MAX) || INT_MAX <= 0x7ffffffeL)
|
||||
typedef DWORD png_alloc_size_t;
|
||||
# else
|
||||
typedef png_size_t png_alloc_size_t;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* PNGCONF_H */
|
@ -1,181 +0,0 @@
|
||||
|
||||
/* libpng STANDARD API DEFINITION */
|
||||
|
||||
/* pnglibconf.h - library build configuration */
|
||||
|
||||
/* libpng version 1.5.0 - last changed on February 11, 2011 */
|
||||
|
||||
/* Copyright (c) 1998-2011 Glenn Randers-Pehrson */
|
||||
|
||||
/* This code is released under the libpng license. */
|
||||
/* For conditions of distribution and use, see the disclaimer */
|
||||
/* and license in png.h */
|
||||
|
||||
/* pnglibconf.h */
|
||||
/* Derived from: scripts/pnglibconf.dfa */
|
||||
/* If you edit this file by hand you must obey the rules expressed in */
|
||||
/* pnglibconf.dfa with respect to the dependencies between the following */
|
||||
/* symbols. It is much better to generate a new file using */
|
||||
/* scripts/libpngconf.mak */
|
||||
|
||||
#ifndef PNGLCONF_H
|
||||
#define PNGLCONF_H
|
||||
/* settings */
|
||||
#define PNG_API_RULE 0
|
||||
#define PNG_CALLOC_SUPPORTED
|
||||
#define PNG_COST_SHIFT 3
|
||||
#define PNG_DEFAULT_READ_MACROS 1
|
||||
#define PNG_GAMMA_THRESHOLD_FIXED 5000
|
||||
#define PNG_MAX_GAMMA_8 11
|
||||
#define PNG_QUANTIZE_BLUE_BITS 5
|
||||
#define PNG_QUANTIZE_GREEN_BITS 5
|
||||
#define PNG_QUANTIZE_RED_BITS 5
|
||||
#define PNG_sCAL_PRECISION 5
|
||||
#define PNG_USER_CHUNK_CACHE_MAX 0
|
||||
#define PNG_USER_CHUNK_MALLOC_MAX 0
|
||||
#define PNG_USER_HEIGHT_MAX 1000000L
|
||||
#define PNG_USER_WIDTH_MAX 1000000L
|
||||
#define PNG_WEIGHT_SHIFT 8
|
||||
#define PNG_ZBUF_SIZE 8192
|
||||
/* end of settings */
|
||||
/* options */
|
||||
#define PNG_16BIT_SUPPORTED
|
||||
#define PNG_ALIGN_MEMORY_SUPPORTED
|
||||
#define PNG_BENIGN_ERRORS_SUPPORTED
|
||||
#define PNG_bKGD_SUPPORTED
|
||||
#define PNG_CHECK_cHRM_SUPPORTED
|
||||
#define PNG_cHRM_SUPPORTED
|
||||
#define PNG_CONSOLE_IO_SUPPORTED
|
||||
#define PNG_CONVERT_tIME_SUPPORTED
|
||||
#define PNG_EASY_ACCESS_SUPPORTED
|
||||
#define PNG_ERROR_TEXT_SUPPORTED
|
||||
#define PNG_FIXED_POINT_SUPPORTED
|
||||
#define PNG_FLOATING_ARITHMETIC_SUPPORTED
|
||||
#define PNG_FLOATING_POINT_SUPPORTED
|
||||
#define PNG_gAMA_SUPPORTED
|
||||
#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
|
||||
#define PNG_hIST_SUPPORTED
|
||||
#define PNG_iCCP_SUPPORTED
|
||||
#define PNG_INCH_CONVERSIONS_SUPPORTED
|
||||
#define PNG_INFO_IMAGE_SUPPORTED
|
||||
#define PNG_IO_STATE_SUPPORTED
|
||||
#define PNG_iTXt_SUPPORTED
|
||||
#define PNG_MNG_FEATURES_SUPPORTED
|
||||
#define PNG_oFFs_SUPPORTED
|
||||
#define PNG_pCAL_SUPPORTED
|
||||
#define PNG_pHYs_SUPPORTED
|
||||
#define PNG_POINTER_INDEXING_SUPPORTED
|
||||
#define PNG_PROGRESSIVE_READ_SUPPORTED
|
||||
#define PNG_READ_16BIT_SUPPORTED
|
||||
#define PNG_READ_16_TO_8_SUPPORTED
|
||||
#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
|
||||
#define PNG_READ_BACKGROUND_SUPPORTED
|
||||
#define PNG_READ_BGR_SUPPORTED
|
||||
#define PNG_READ_bKGD_SUPPORTED
|
||||
#define PNG_READ_cHRM_SUPPORTED
|
||||
#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
|
||||
#define PNG_READ_EXPAND_16_SUPPORTED
|
||||
#define PNG_READ_EXPAND_SUPPORTED
|
||||
#define PNG_READ_FILLER_SUPPORTED
|
||||
#define PNG_READ_gAMA_SUPPORTED
|
||||
#define PNG_READ_GAMMA_SUPPORTED
|
||||
#define PNG_READ_GRAY_TO_RGB_SUPPORTED
|
||||
#define PNG_READ_hIST_SUPPORTED
|
||||
#define PNG_READ_iCCP_SUPPORTED
|
||||
#define PNG_READ_INTERLACING_SUPPORTED
|
||||
#define PNG_READ_INT_FUNCTIONS_SUPPORTED
|
||||
#define PNG_READ_INVERT_ALPHA_SUPPORTED
|
||||
#define PNG_READ_INVERT_SUPPORTED
|
||||
#define PNG_READ_iTXt_SUPPORTED
|
||||
#define PNG_READ_oFFs_SUPPORTED
|
||||
#define PNG_READ_OPT_PLTE_SUPPORTED
|
||||
#define PNG_READ_PACK_SUPPORTED
|
||||
#define PNG_READ_PACKSWAP_SUPPORTED
|
||||
#define PNG_READ_pCAL_SUPPORTED
|
||||
#define PNG_READ_pHYs_SUPPORTED
|
||||
#define PNG_READ_QUANTIZE_SUPPORTED
|
||||
#define PNG_READ_RGB_TO_GRAY_SUPPORTED
|
||||
#define PNG_READ_sBIT_SUPPORTED
|
||||
#define PNG_READ_sCAL_SUPPORTED
|
||||
#define PNG_READ_SHIFT_SUPPORTED
|
||||
#define PNG_READ_sPLT_SUPPORTED
|
||||
#define PNG_READ_sRGB_SUPPORTED
|
||||
#define PNG_READ_STRIP_ALPHA_SUPPORTED
|
||||
#define PNG_READ_SUPPORTED
|
||||
#define PNG_READ_SWAP_ALPHA_SUPPORTED
|
||||
#define PNG_READ_SWAP_SUPPORTED
|
||||
#define PNG_READ_tEXt_SUPPORTED
|
||||
#define PNG_READ_TEXT_SUPPORTED
|
||||
#define PNG_READ_tIME_SUPPORTED
|
||||
#define PNG_READ_TRANSFORMS_SUPPORTED
|
||||
#define PNG_READ_tRNS_SUPPORTED
|
||||
#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_READ_USER_CHUNKS_SUPPORTED
|
||||
#define PNG_READ_USER_TRANSFORM_SUPPORTED
|
||||
#define PNG_READ_zTXt_SUPPORTED
|
||||
#define PNG_SAVE_INT_32_SUPPORTED
|
||||
#define PNG_sBIT_SUPPORTED
|
||||
#define PNG_sCAL_SUPPORTED
|
||||
#define PNG_SEQUENTIAL_READ_SUPPORTED
|
||||
#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED
|
||||
#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
|
||||
#define PNG_SETJMP_SUPPORTED
|
||||
#define PNG_SET_USER_LIMITS_SUPPORTED
|
||||
#define PNG_sPLT_SUPPORTED
|
||||
#define PNG_sRGB_SUPPORTED
|
||||
#define PNG_STDIO_SUPPORTED
|
||||
#define PNG_tEXt_SUPPORTED
|
||||
#define PNG_TEXT_SUPPORTED
|
||||
#define PNG_TIME_RFC1123_SUPPORTED
|
||||
#define PNG_tIME_SUPPORTED
|
||||
#define PNG_tRNS_SUPPORTED
|
||||
#define PNG_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_USER_CHUNKS_SUPPORTED
|
||||
#define PNG_USER_LIMITS_SUPPORTED
|
||||
#define PNG_USER_MEM_SUPPORTED
|
||||
#define PNG_USER_TRANSFORM_INFO_SUPPORTED
|
||||
#define PNG_USER_TRANSFORM_PTR_SUPPORTED
|
||||
#define PNG_WARNINGS_SUPPORTED
|
||||
#define PNG_WRITE_16BIT_SUPPORTED
|
||||
#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
|
||||
#define PNG_WRITE_BGR_SUPPORTED
|
||||
#define PNG_WRITE_bKGD_SUPPORTED
|
||||
#define PNG_WRITE_cHRM_SUPPORTED
|
||||
#define PNG_WRITE_FILLER_SUPPORTED
|
||||
#define PNG_WRITE_FILTER_SUPPORTED
|
||||
#define PNG_WRITE_FLUSH_SUPPORTED
|
||||
#define PNG_WRITE_gAMA_SUPPORTED
|
||||
#define PNG_WRITE_hIST_SUPPORTED
|
||||
#define PNG_WRITE_iCCP_SUPPORTED
|
||||
#define PNG_WRITE_INTERLACING_SUPPORTED
|
||||
#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
|
||||
#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
||||
#define PNG_WRITE_INVERT_SUPPORTED
|
||||
#define PNG_WRITE_iTXt_SUPPORTED
|
||||
#define PNG_WRITE_oFFs_SUPPORTED
|
||||
#define PNG_WRITE_PACK_SUPPORTED
|
||||
#define PNG_WRITE_PACKSWAP_SUPPORTED
|
||||
#define PNG_WRITE_pCAL_SUPPORTED
|
||||
#define PNG_WRITE_pHYs_SUPPORTED
|
||||
#define PNG_WRITE_sBIT_SUPPORTED
|
||||
#define PNG_WRITE_sCAL_SUPPORTED
|
||||
#define PNG_WRITE_SHIFT_SUPPORTED
|
||||
#define PNG_WRITE_sPLT_SUPPORTED
|
||||
#define PNG_WRITE_sRGB_SUPPORTED
|
||||
#define PNG_WRITE_SUPPORTED
|
||||
#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
|
||||
#define PNG_WRITE_SWAP_SUPPORTED
|
||||
#define PNG_WRITE_tEXt_SUPPORTED
|
||||
#define PNG_WRITE_TEXT_SUPPORTED
|
||||
#define PNG_WRITE_tIME_SUPPORTED
|
||||
#define PNG_WRITE_TRANSFORMS_SUPPORTED
|
||||
#define PNG_WRITE_tRNS_SUPPORTED
|
||||
#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
|
||||
#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
|
||||
#define PNG_WRITE_zTXt_SUPPORTED
|
||||
#define PNG_zTXt_SUPPORTED
|
||||
/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
|
||||
/*#undef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED*/
|
||||
/* end of options */
|
||||
#endif /* PNGLCONF_H */
|
@ -1,428 +0,0 @@
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-2010 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZCONF_H
|
||||
#define ZCONF_H
|
||||
|
||||
/*
|
||||
* If you *really* need a unique prefix for all types and library functions,
|
||||
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
||||
* Even better than compiling with -DZ_PREFIX would be to use configure to set
|
||||
* this permanently in zconf.h using "./configure --zprefix".
|
||||
*/
|
||||
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
|
||||
|
||||
/* all linked symbols */
|
||||
# define _dist_code z__dist_code
|
||||
# define _length_code z__length_code
|
||||
# define _tr_align z__tr_align
|
||||
# define _tr_flush_block z__tr_flush_block
|
||||
# define _tr_init z__tr_init
|
||||
# define _tr_stored_block z__tr_stored_block
|
||||
# define _tr_tally z__tr_tally
|
||||
# define adler32 z_adler32
|
||||
# define adler32_combine z_adler32_combine
|
||||
# define adler32_combine64 z_adler32_combine64
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# define crc32 z_crc32
|
||||
# define crc32_combine z_crc32_combine
|
||||
# define crc32_combine64 z_crc32_combine64
|
||||
# define deflate z_deflate
|
||||
# define deflateBound z_deflateBound
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateEnd z_deflateEnd
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateInit_ z_deflateInit_
|
||||
# define deflateParams z_deflateParams
|
||||
# define deflatePrime z_deflatePrime
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateSetHeader z_deflateSetHeader
|
||||
# define deflateTune z_deflateTune
|
||||
# define deflate_copyright z_deflate_copyright
|
||||
# define get_crc_table z_get_crc_table
|
||||
# define gz_error z_gz_error
|
||||
# define gz_intmax z_gz_intmax
|
||||
# define gz_strwinerror z_gz_strwinerror
|
||||
# define gzbuffer z_gzbuffer
|
||||
# define gzclearerr z_gzclearerr
|
||||
# define gzclose z_gzclose
|
||||
# define gzclose_r z_gzclose_r
|
||||
# define gzclose_w z_gzclose_w
|
||||
# define gzdirect z_gzdirect
|
||||
# define gzdopen z_gzdopen
|
||||
# define gzeof z_gzeof
|
||||
# define gzerror z_gzerror
|
||||
# define gzflush z_gzflush
|
||||
# define gzgetc z_gzgetc
|
||||
# define gzgets z_gzgets
|
||||
# define gzoffset z_gzoffset
|
||||
# define gzoffset64 z_gzoffset64
|
||||
# define gzopen z_gzopen
|
||||
# define gzopen64 z_gzopen64
|
||||
# define gzprintf z_gzprintf
|
||||
# define gzputc z_gzputc
|
||||
# define gzputs z_gzputs
|
||||
# define gzread z_gzread
|
||||
# define gzrewind z_gzrewind
|
||||
# define gzseek z_gzseek
|
||||
# define gzseek64 z_gzseek64
|
||||
# define gzsetparams z_gzsetparams
|
||||
# define gztell z_gztell
|
||||
# define gztell64 z_gztell64
|
||||
# define gzungetc z_gzungetc
|
||||
# define gzwrite z_gzwrite
|
||||
# define inflate z_inflate
|
||||
# define inflateBack z_inflateBack
|
||||
# define inflateBackEnd z_inflateBackEnd
|
||||
# define inflateBackInit_ z_inflateBackInit_
|
||||
# define inflateCopy z_inflateCopy
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define inflateGetHeader z_inflateGetHeader
|
||||
# define inflateInit2_ z_inflateInit2_
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflateMark z_inflateMark
|
||||
# define inflatePrime z_inflatePrime
|
||||
# define inflateReset z_inflateReset
|
||||
# define inflateReset2 z_inflateReset2
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateUndermine z_inflateUndermine
|
||||
# define inflate_copyright z_inflate_copyright
|
||||
# define inflate_fast z_inflate_fast
|
||||
# define inflate_table z_inflate_table
|
||||
# define uncompress z_uncompress
|
||||
# define zError z_zError
|
||||
# define zcalloc z_zcalloc
|
||||
# define zcfree z_zcfree
|
||||
# define zlibCompileFlags z_zlibCompileFlags
|
||||
# define zlibVersion z_zlibVersion
|
||||
|
||||
/* all zlib typedefs in zlib.h and zconf.h */
|
||||
# define Byte z_Byte
|
||||
# define Bytef z_Bytef
|
||||
# define alloc_func z_alloc_func
|
||||
# define charf z_charf
|
||||
# define free_func z_free_func
|
||||
# define gzFile z_gzFile
|
||||
# define gz_header z_gz_header
|
||||
# define gz_headerp z_gz_headerp
|
||||
# define in_func z_in_func
|
||||
# define intf z_intf
|
||||
# define out_func z_out_func
|
||||
# define uInt z_uInt
|
||||
# define uIntf z_uIntf
|
||||
# define uLong z_uLong
|
||||
# define uLongf z_uLongf
|
||||
# define voidp z_voidp
|
||||
# define voidpc z_voidpc
|
||||
# define voidpf z_voidpf
|
||||
|
||||
/* all zlib structs in zlib.h and zconf.h */
|
||||
# define gz_header_s z_gz_header_s
|
||||
# define internal_state z_internal_state
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#endif
|
||||
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
|
||||
# define OS2
|
||||
#endif
|
||||
#if defined(_WINDOWS) && !defined(WINDOWS)
|
||||
# define WINDOWS
|
||||
#endif
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
|
||||
# ifndef WIN32
|
||||
# define WIN32
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
|
||||
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
|
||||
# ifndef SYS16BIT
|
||||
# define SYS16BIT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
||||
* than 64k bytes at a time (needed on systems with 16-bit int).
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# define MAXSEG_64K
|
||||
#endif
|
||||
#ifdef MSDOS
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#ifdef __STDC_VERSION__
|
||||
# ifndef STDC
|
||||
# define STDC
|
||||
# endif
|
||||
# if __STDC_VERSION__ >= 199901L
|
||||
# ifndef STDC99
|
||||
# define STDC99
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#ifndef STDC
|
||||
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
|
||||
# define const /* note: need a more gentle solution here */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some Mac compilers merge all .h files incorrectly: */
|
||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||
# define NO_DUMMY_DECL
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
#ifndef MAX_MEM_LEVEL
|
||||
# ifdef MAXSEG_64K
|
||||
# define MAX_MEM_LEVEL 8
|
||||
# else
|
||||
# define MAX_MEM_LEVEL 9
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
||||
* created by gzip. (Files created by minigzip can still be extracted by
|
||||
* gzip.)
|
||||
*/
|
||||
#ifndef MAX_WBITS
|
||||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
#endif
|
||||
|
||||
/* The memory requirements for deflate are (in bytes):
|
||||
(1 << (windowBits+2)) + (1 << (memLevel+9))
|
||||
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||
the default memory requirements from 256K to 128K, compile with
|
||||
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
#ifndef OF /* function prototypes */
|
||||
# ifdef STDC
|
||||
# define OF(args) args
|
||||
# else
|
||||
# define OF(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||
* model programming (small or medium model with some far allocations).
|
||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
|
||||
* just define FAR to be empty.
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# if defined(M_I86SM) || defined(M_I86MM)
|
||||
/* MSC small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef _MSC_VER
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
# if (defined(__SMALL__) || defined(__MEDIUM__))
|
||||
/* Turbo C small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef __BORLANDC__
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(WIN32)
|
||||
/* If building or using zlib as a DLL, define ZLIB_DLL.
|
||||
* This is not mandatory, but it offers a little performance increase.
|
||||
*/
|
||||
# ifdef ZLIB_DLL
|
||||
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXTERN extern __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXTERN extern __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
# endif /* ZLIB_DLL */
|
||||
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
|
||||
* define ZLIB_WINAPI.
|
||||
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
|
||||
*/
|
||||
# ifdef ZLIB_WINAPI
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
# define ZEXPORT WINAPI
|
||||
# ifdef WIN32
|
||||
# define ZEXPORTVA WINAPIV
|
||||
# else
|
||||
# define ZEXPORTVA FAR CDECL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (__BEOS__)
|
||||
# ifdef ZLIB_DLL
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXPORT __declspec(dllexport)
|
||||
# define ZEXPORTVA __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXPORT __declspec(dllimport)
|
||||
# define ZEXPORTVA __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZEXTERN
|
||||
# define ZEXTERN extern
|
||||
#endif
|
||||
#ifndef ZEXPORT
|
||||
# define ZEXPORT
|
||||
#endif
|
||||
#ifndef ZEXPORTVA
|
||||
# define ZEXPORTVA
|
||||
#endif
|
||||
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
#if !defined(__MACTYPES__)
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
#endif
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
|
||||
#ifdef SMALL_MEDIUM
|
||||
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
|
||||
# define Bytef Byte FAR
|
||||
#else
|
||||
typedef Byte FAR Bytef;
|
||||
#endif
|
||||
typedef char FAR charf;
|
||||
typedef int FAR intf;
|
||||
typedef uInt FAR uIntf;
|
||||
typedef uLong FAR uLongf;
|
||||
|
||||
#ifdef STDC
|
||||
typedef void const *voidpc;
|
||||
typedef void FAR *voidpf;
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef Byte const *voidpc;
|
||||
typedef Byte FAR *voidpf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#endif
|
||||
|
||||
#ifdef STDC
|
||||
# include <sys/types.h> /* for off_t */
|
||||
#endif
|
||||
|
||||
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
|
||||
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
|
||||
* though the former does not conform to the LFS document), but considering
|
||||
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
|
||||
* equivalently requesting no 64-bit operations
|
||||
*/
|
||||
#if -_LARGEFILE64_SOURCE - -1 == 1
|
||||
# undef _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
||||
# include <unistd.h> /* for SEEK_* and off_t */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
# endif
|
||||
# ifndef z_off_t
|
||||
# define z_off_t off_t
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
# define SEEK_CUR 1 /* Seek from current position. */
|
||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||
#endif
|
||||
|
||||
#ifndef z_off_t
|
||||
# define z_off_t long
|
||||
#endif
|
||||
|
||||
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
||||
# define z_off64_t off64_t
|
||||
#else
|
||||
# define z_off64_t z_off_t
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__)
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
/* MVS linker does not support external names larger than 8 bytes */
|
||||
#if defined(__MVS__)
|
||||
#pragma map(deflateInit_,"DEIN")
|
||||
#pragma map(deflateInit2_,"DEIN2")
|
||||
#pragma map(deflateEnd,"DEEND")
|
||||
#pragma map(deflateBound,"DEBND")
|
||||
#pragma map(inflateInit_,"ININ")
|
||||
#pragma map(inflateInit2_,"ININ2")
|
||||
#pragma map(inflateEnd,"INEND")
|
||||
#pragma map(inflateSync,"INSY")
|
||||
#pragma map(inflateSetDictionary,"INSEDI")
|
||||
#pragma map(compressBound,"CMBND")
|
||||
#pragma map(inflate_table,"INTABL")
|
||||
#pragma map(inflate_fast,"INFA")
|
||||
#pragma map(inflate_copyright,"INCOPY")
|
||||
#endif
|
||||
|
||||
#endif /* ZCONF_H */
|
1613
cdeps/win/zlib.h
1613
cdeps/win/zlib.h
File diff suppressed because it is too large
Load Diff
@ -1,34 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
|
||||
"image/jpeg"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/go-vgo/robotgo"
|
||||
"golang.org/x/image/bmp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
bitMap := robotgo.CaptureScreen()
|
||||
defer robotgo.FreeBitmap(bitMap)
|
||||
|
||||
bs := robotgo.ToBitmapBytes(bitMap)
|
||||
img, err := bmp.Decode(bytes.NewReader(bs))
|
||||
if err != nil {
|
||||
log.Println("bmp.Decode err is: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
err = jpeg.Encode(b, img, &jpeg.Options{Quality: 20})
|
||||
if err != nil {
|
||||
log.Println("jpeg.Encode err is: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("bytes: ", b.Bytes())
|
||||
ioutil.WriteFile("out.jpg", b.Bytes(), 0666)
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/go-vgo/robotgo"
|
||||
)
|
||||
|
||||
func main() {
|
||||
bmp, free := loadBitmaps("start.png", "chest.png", "eat.png")
|
||||
defer free()
|
||||
|
||||
for {
|
||||
clickBitmap(bmp["start.png"], false)
|
||||
clickBitmap(bmp["chest.png"], true)
|
||||
clickBitmap(bmp["eat.png"], false)
|
||||
}
|
||||
}
|
||||
|
||||
func loadBitmaps(files ...string) (bitmaps map[string]robotgo.Bitmap, free func()) {
|
||||
freeFuncs := make([]func(), 0)
|
||||
bitmaps = make(map[string]robotgo.Bitmap)
|
||||
for _, f := range files {
|
||||
bitmap, freeFunc := readBitmap(f)
|
||||
bitmaps[f] = bitmap
|
||||
freeFuncs = append(freeFuncs, freeFunc)
|
||||
}
|
||||
|
||||
free = func() {
|
||||
for key := range freeFuncs {
|
||||
freeFuncs[key]()
|
||||
}
|
||||
}
|
||||
return bitmaps, free
|
||||
}
|
||||
|
||||
func readBitmap(file string) (bitmap robotgo.Bitmap, free func()) {
|
||||
cBitmap := robotgo.OpenBitmap(file)
|
||||
bitmap = robotgo.ToBitmap(cBitmap)
|
||||
free = func() {
|
||||
robotgo.FreeBitmap(cBitmap)
|
||||
}
|
||||
return bitmap, free
|
||||
}
|
||||
|
||||
func clickBitmap(bmp robotgo.Bitmap, doubleClick bool) bool {
|
||||
fx, fy := robotgo.FindBitmap(robotgo.ToCBitmap(bmp))
|
||||
if fx != -1 && fy != -1 {
|
||||
robotgo.MoveMouse(fx, fy)
|
||||
robotgo.MouseClick("left", doubleClick)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
//go:build go1.16
|
||||
// +build go1.16
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-vgo/robotgo"
|
||||
"github.com/vcaesar/imgo"
|
||||
)
|
||||
|
||||
//go:embed test_007.jpeg
|
||||
var testPng []byte
|
||||
|
||||
func main() {
|
||||
bit1 := robotgo.CaptureScreen(300, 300, 100, 100)
|
||||
defer robotgo.FreeBitmap(bit1)
|
||||
robotgo.SaveBitmap(bit1, "test_003.jpeg")
|
||||
|
||||
m1 := robotgo.ToImage(bit1)
|
||||
fmt.Println("m1: ", m1.Bounds())
|
||||
imgo.SaveToPNG("test_01.png", m1)
|
||||
|
||||
r1 := robotgo.ToRGBA(bit1)
|
||||
fmt.Println("r1: ", r1.Pix)
|
||||
|
||||
bit2 := robotgo.ToCBitmap(robotgo.ImgToBitmap(m1))
|
||||
robotgo.SaveBitmap(bit2, "test_002.jpeg")
|
||||
|
||||
test()
|
||||
}
|
||||
|
||||
func test() {
|
||||
bitmap := robotgo.CaptureScreen(10, 10, 10, 10)
|
||||
defer robotgo.FreeBitmap(bitmap)
|
||||
|
||||
img := robotgo.ToImage(bitmap)
|
||||
robotgo.SavePng(img, "test_1.png")
|
||||
|
||||
img1, _ := robotgo.ByteToImg(testPng)
|
||||
robotgo.SaveJpeg(img1, "test_7.jpeg")
|
||||
|
||||
bit2 := robotgo.ToCBitmap(robotgo.ImgToBitmap(img))
|
||||
fx, fy := robotgo.FindBitmap(bit2)
|
||||
fmt.Println("FindBitmap------ ", fx, fy)
|
||||
|
||||
arr := robotgo.FindAllBitmap(bit2)
|
||||
fmt.Println("Find every bitmap: ", arr)
|
||||
robotgo.SaveBitmap(bitmap, "test.png")
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 3.2 KiB |
@ -1,207 +0,0 @@
|
||||
// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// https://github.com/go-vgo/robotgo/blob/master/LICENSE
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/go-vgo/robotgo"
|
||||
"github.com/vcaesar/imgo"
|
||||
// "go-vgo/robotgo"
|
||||
)
|
||||
|
||||
func toBitmap(bmp robotgo.CBitmap) {
|
||||
bitmap := robotgo.ToMMBitmapRef(bmp)
|
||||
img := robotgo.ToImage(bitmap)
|
||||
fmt.Println("img: ", img)
|
||||
imgo.SaveToPNG("test_IMG.png", img)
|
||||
|
||||
gbit := robotgo.ToBitmap(bitmap)
|
||||
fmt.Println("go bitmap", gbit, gbit.Width)
|
||||
|
||||
cbit := robotgo.ToCBitmap(gbit)
|
||||
// defer robotgo.FreeBitmap(cbit)
|
||||
log.Println("cbit == bitmap: ", cbit == bitmap)
|
||||
robotgo.SaveBitmap(cbit, "tocbitmap.png")
|
||||
}
|
||||
|
||||
// find color
|
||||
func findColor(bmp robotgo.CBitmap) {
|
||||
bitmap := robotgo.ToMMBitmapRef(bmp)
|
||||
|
||||
// find the color in bitmap
|
||||
color := robotgo.GetColor(bitmap, 1, 2)
|
||||
fmt.Println("color...", color)
|
||||
cx, cy := robotgo.FindColor(robotgo.CHex(color), bitmap, 1.0)
|
||||
fmt.Println("pos...", cx, cy)
|
||||
cx, cy = robotgo.FindColor(robotgo.CHex(color))
|
||||
fmt.Println("pos...", cx, cy)
|
||||
|
||||
cx, cy = robotgo.FindColor(0xAADCDC, bitmap)
|
||||
fmt.Println("pos...", cx, cy)
|
||||
cx, cy = robotgo.FindColor(0xAADCDC, nil, 0.1)
|
||||
fmt.Println("pos...", cx, cy)
|
||||
|
||||
cx, cy = robotgo.FindColorCS(0xAADCDC, 388, 179, 300, 300)
|
||||
fmt.Println("pos...", cx, cy)
|
||||
|
||||
cnt := robotgo.CountColor(0xAADCDC, bitmap)
|
||||
fmt.Println("count...", cnt)
|
||||
cnt1 := robotgo.CountColorCS(0xAADCDC, 10, 20, 30, 40)
|
||||
fmt.Println("count...", cnt1)
|
||||
|
||||
arr := robotgo.FindAllColor(0xAADCDC)
|
||||
fmt.Println("find all color: ", arr)
|
||||
for i := 0; i < len(arr); i++ {
|
||||
fmt.Println("pos is: ", arr[i].X, arr[i].Y)
|
||||
}
|
||||
}
|
||||
|
||||
func bitmapString(bmp robotgo.CBitmap) {
|
||||
bitmap := robotgo.ToMMBitmapRef(bmp)
|
||||
|
||||
// creates bitmap from string by bitmap
|
||||
bitstr := robotgo.TostringBitmap(bitmap)
|
||||
fmt.Println("bitstr...", bitstr)
|
||||
|
||||
// sbitmap := robotgo.BitmapFromstring(bitstr, 2)
|
||||
// fmt.Println("...", sbitmap)
|
||||
|
||||
// sbitmap := robotgo.BitmapStr(bitstr)
|
||||
sbitmap := robotgo.BitmapFromStr(bitstr)
|
||||
fmt.Println("bitmap str...", sbitmap)
|
||||
robotgo.SaveBitmap(sbitmap, "teststr.png")
|
||||
}
|
||||
|
||||
func bitmapTool(bmp robotgo.CBitmap) {
|
||||
bitmap := robotgo.ToMMBitmapRef(bmp)
|
||||
|
||||
// bitmap := robotgo.CaptureScreen(10, 20, 30, 40)
|
||||
abool := robotgo.PointInBounds(bitmap, 1, 2)
|
||||
fmt.Println("point in bounds...", abool)
|
||||
|
||||
// returns new bitmap object created from a portion of another
|
||||
bitpos := robotgo.GetPortion(bitmap, 10, 10, 11, 10)
|
||||
fmt.Println(bitpos)
|
||||
|
||||
// saves image to absolute filepath in the given format
|
||||
robotgo.SaveBitmap(bitmap, "test.png")
|
||||
robotgo.SaveBitmap(bitmap, "test31.tif", 1)
|
||||
}
|
||||
|
||||
func decode() {
|
||||
img, name, err := robotgo.DecodeImg("test.png")
|
||||
if err != nil {
|
||||
log.Println("decode image ", err)
|
||||
}
|
||||
fmt.Println("decode test.png", img, name)
|
||||
|
||||
byt, _ := robotgo.OpenImg("test.png")
|
||||
imgo.SaveByte("test2.png", byt)
|
||||
|
||||
w, h := robotgo.GetImgSize("test.png")
|
||||
fmt.Println("image width and hight ", w, h)
|
||||
w, h, _ = imgo.GetSize("test.png")
|
||||
fmt.Println("image width and hight ", w, h)
|
||||
|
||||
// convert image
|
||||
robotgo.Convert("test.png", "test.tif")
|
||||
}
|
||||
|
||||
func bitmapTest(bmp robotgo.CBitmap) {
|
||||
bitmap := robotgo.ToMMBitmapRef(bmp)
|
||||
|
||||
bit := robotgo.CaptureScreen(1, 2, 40, 40)
|
||||
defer robotgo.FreeBitmap(bit)
|
||||
fmt.Println("CaptureScreen...", bit)
|
||||
|
||||
// searches for needle in bitmap
|
||||
fx, fy := robotgo.FindBitmap(bit, bitmap)
|
||||
fmt.Println("FindBitmap------", fx, fy)
|
||||
|
||||
// fx, fy := robotgo.FindBit(bitmap)
|
||||
// fmt.Println("FindBitmap------", fx, fy)
|
||||
|
||||
fx, fy = robotgo.FindBitmap(bit)
|
||||
fmt.Println("FindBitmap------", fx, fy)
|
||||
|
||||
fx, fy = robotgo.FindBitmap(bit, nil, 0.2)
|
||||
fmt.Println("find bitmap: ", fx, fy)
|
||||
|
||||
fx, fy = robotgo.FindBitmap(bit, bitmap, 0.3)
|
||||
fmt.Println("find bitmap: ", fx, fy)
|
||||
}
|
||||
|
||||
func findBitmap(bmp robotgo.CBitmap) {
|
||||
fx, fy := robotgo.FindBitmap(robotgo.ToMMBitmapRef(bmp))
|
||||
fmt.Println("findBitmap: ", fx, fy)
|
||||
|
||||
fx, fy = robotgo.FindCBitmap(bmp)
|
||||
fmt.Println("findCBitmap: ", fx, fy)
|
||||
fx, fy = robotgo.FindCBitmap(bmp, nil, 0.1)
|
||||
fmt.Println("findCBitmap: ", fx, fy)
|
||||
|
||||
// open image bitmap
|
||||
openbit := robotgo.OpenBitmap("test.tif")
|
||||
fmt.Println("openBitmap...", openbit)
|
||||
|
||||
fx, fy = robotgo.FindBitmap(openbit)
|
||||
fmt.Println("FindBitmap------", fx, fy)
|
||||
|
||||
fx, fy = robotgo.FindPic("test.tif")
|
||||
fmt.Println("FindPic------", fx, fy)
|
||||
|
||||
arr := robotgo.FindAllBitmap(openbit)
|
||||
fmt.Println("find all bitmap: ", arr)
|
||||
for i := 0; i < len(arr); i++ {
|
||||
fmt.Println("pos is: ", arr[i].X, arr[i].Y)
|
||||
}
|
||||
}
|
||||
|
||||
func bitmap() {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Bitmap
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// gets all of the screen
|
||||
abitMap := robotgo.CaptureScreen()
|
||||
fmt.Println("abitMap...", abitMap)
|
||||
|
||||
// gets part of the screen
|
||||
bitmap := robotgo.CaptureScreen(100, 200, 30, 30)
|
||||
defer robotgo.FreeBitmap(bitmap)
|
||||
fmt.Println("CaptureScreen...", bitmap)
|
||||
|
||||
cbit := robotgo.CBitmap(bitmap)
|
||||
toBitmap(cbit)
|
||||
|
||||
findColor(cbit)
|
||||
|
||||
count := robotgo.CountBitmap(abitMap, bitmap)
|
||||
fmt.Println("count...", count)
|
||||
|
||||
bitmapTest(cbit)
|
||||
findBitmap(cbit)
|
||||
|
||||
bitmapString(cbit)
|
||||
bitmapTool(cbit)
|
||||
|
||||
decode()
|
||||
|
||||
// free the bitmap
|
||||
robotgo.FreeBitmap(abitMap)
|
||||
// robotgo.FreeBitmap(bitmap)
|
||||
}
|
||||
|
||||
func main() {
|
||||
bitmap()
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// https://github.com/go-vgo/robotgo/blob/master/LICENSE
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-vgo/robotgo"
|
||||
// "go-vgo/robotgo"
|
||||
)
|
||||
|
||||
func addEvent() {
|
||||
fmt.Println("--- Please press ctrl + shift + q ---")
|
||||
ok := robotgo.AddEvents("q", "ctrl", "shift")
|
||||
if ok {
|
||||
fmt.Println("add events...")
|
||||
}
|
||||
|
||||
fmt.Println("--- Please press w---")
|
||||
ok = robotgo.AddEvents("w")
|
||||
if ok {
|
||||
fmt.Println("add events")
|
||||
}
|
||||
|
||||
// start hook
|
||||
s := robotgo.Start()
|
||||
// end hook
|
||||
defer robotgo.End()
|
||||
|
||||
for ev := range s {
|
||||
fmt.Println("hook: ", ev)
|
||||
}
|
||||
}
|
||||
|
||||
func addMouse() {
|
||||
fmt.Println("--- Please press left mouse button ---")
|
||||
ok := robotgo.AddMouse("left")
|
||||
if ok {
|
||||
fmt.Println("add mouse...")
|
||||
}
|
||||
|
||||
fmt.Println("--- Please press left mouse button and move mosue to 100,100 ---")
|
||||
ok = robotgo.AddMouse("left", 100, 100)
|
||||
if ok {
|
||||
fmt.Println("add mouse and move to 100,100 ...")
|
||||
}
|
||||
|
||||
fmt.Println("--- Please move mosue to 100,100 ---")
|
||||
ok = robotgo.AddMousePos(100, 100)
|
||||
if ok {
|
||||
fmt.Println(" move mouse to 100,100 ...")
|
||||
}
|
||||
}
|
||||
|
||||
func add() {
|
||||
fmt.Println("--- Please press v---")
|
||||
eve := robotgo.AddEvent("v")
|
||||
|
||||
if eve {
|
||||
fmt.Println("--- You press v---", "v")
|
||||
}
|
||||
|
||||
fmt.Println("--- Please press k---")
|
||||
keve := robotgo.AddEvent("k")
|
||||
if keve {
|
||||
fmt.Println("--- You press k---", "k")
|
||||
}
|
||||
|
||||
fmt.Println("--- Please press f1---")
|
||||
feve := robotgo.AddEvent("f1")
|
||||
if feve {
|
||||
fmt.Println("You press...", "f1")
|
||||
}
|
||||
}
|
||||
|
||||
func event() {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Global event listener
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
add()
|
||||
|
||||
fmt.Println("--- Please press left mouse button---")
|
||||
mleft := robotgo.AddEvent("mleft")
|
||||
if mleft {
|
||||
fmt.Println("--- You press left mouse button---", "mleft")
|
||||
}
|
||||
|
||||
mright := robotgo.AddEvent("mright")
|
||||
if mright {
|
||||
fmt.Println("--- You press right mouse button---", "mright")
|
||||
}
|
||||
|
||||
// stop AddEvent
|
||||
// robotgo.StopEvent()
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("test begin...")
|
||||
|
||||
addEvent()
|
||||
|
||||
addMouse()
|
||||
|
||||
event()
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
hook "github.com/robotn/gohook"
|
||||
)
|
||||
|
||||
// hook listen and return values using detailed examples
|
||||
func add() {
|
||||
s := hook.Start()
|
||||
defer hook.End()
|
||||
|
||||
ct := false
|
||||
for {
|
||||
i := <-s
|
||||
|
||||
if i.Kind == hook.KeyHold && i.Rawcode == 59 {
|
||||
ct = true
|
||||
}
|
||||
|
||||
if ct && i.Rawcode == 12 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// base hook example
|
||||
func base() {
|
||||
evChan := hook.Start()
|
||||
defer hook.End()
|
||||
|
||||
for ev := range evChan {
|
||||
fmt.Println("hook: ", ev)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
base()
|
||||
|
||||
add()
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
// Copyright 2016 The cauefcr Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// https://github.com/cauefcr/robotgo/blob/master/LICENSE
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-vgo/robotgo"
|
||||
hook "github.com/robotn/gohook"
|
||||
)
|
||||
|
||||
func addEvent() {
|
||||
fmt.Println("--- Please press ctrl + shift + q to stop hook ---")
|
||||
robotgo.EventHook(hook.KeyDown, []string{"q", "ctrl", "shift"}, func(e hook.Event) {
|
||||
fmt.Println("ctrl-shift-q")
|
||||
robotgo.EventEnd()
|
||||
})
|
||||
|
||||
fmt.Println("--- Please press w---")
|
||||
robotgo.EventHook(hook.KeyDown, []string{"w"}, func(e hook.Event) {
|
||||
fmt.Println("w")
|
||||
})
|
||||
|
||||
s := robotgo.EventStart()
|
||||
<-robotgo.EventProcess(s)
|
||||
}
|
||||
|
||||
func addMouse() {
|
||||
fmt.Println("--- Please press left mouse button to see it's position and the right mouse button to exit ---")
|
||||
robotgo.EventHook(hook.MouseDown, []string{}, func(e hook.Event) {
|
||||
if e.Button == hook.MouseMap["left"] {
|
||||
fmt.Printf("mouse left @ %v - %v\n", e.X, e.Y)
|
||||
} else if e.Button == hook.MouseMap["right"] {
|
||||
robotgo.EventEnd()
|
||||
}
|
||||
})
|
||||
|
||||
s := robotgo.EventStart()
|
||||
<-robotgo.EventProcess(s)
|
||||
}
|
||||
|
||||
func lowLevel() {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Global event listener
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
fmt.Println("Press q to stop event gathering")
|
||||
evChan := robotgo.EventStart()
|
||||
for e := range evChan {
|
||||
fmt.Println(e)
|
||||
if e.Keychar == 'q' {
|
||||
robotgo.EventEnd()
|
||||
// break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("test begin...")
|
||||
addEvent()
|
||||
|
||||
addMouse()
|
||||
|
||||
lowLevel()
|
||||
}
|
195
hook.go
195
hook.go
@ -1,195 +0,0 @@
|
||||
// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// https://github.com/go-vgo/robotgo/blob/master/LICENSE
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
package robotgo
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
hook "github.com/robotn/gohook"
|
||||
)
|
||||
|
||||
/*
|
||||
___________ ____ _______ .__ __. .___________.
|
||||
| ____\ \ / / | ____|| \ | | | |
|
||||
| |__ \ \/ / | |__ | \| | `---| |----`
|
||||
| __| \ / | __| | . ` | | |
|
||||
| |____ \ / | |____ | |\ | | |
|
||||
|_______| \__/ |_______||__| \__| |__|
|
||||
*/
|
||||
|
||||
// EventStart start global event hook
|
||||
// return event channel
|
||||
func EventStart() chan hook.Event {
|
||||
return hook.Start()
|
||||
}
|
||||
|
||||
// EventEnd removes global event hook
|
||||
func EventEnd() {
|
||||
hook.End()
|
||||
}
|
||||
|
||||
// Deprecated: use the EventStart(),
|
||||
//
|
||||
// Start start global event hook
|
||||
// return event channel
|
||||
func Start() chan hook.Event {
|
||||
return hook.Start()
|
||||
}
|
||||
|
||||
// Deprecated: use the EventEnd(),
|
||||
//
|
||||
// End removes global event hook
|
||||
func End() {
|
||||
hook.End()
|
||||
}
|
||||
|
||||
// StopEvent stop event listener, use by AddEvent()
|
||||
func StopEvent() {
|
||||
hook.StopEvent()
|
||||
}
|
||||
|
||||
// EventProcess return go hook process
|
||||
func EventProcess(events chan hook.Event) chan bool {
|
||||
return hook.Process(events)
|
||||
}
|
||||
|
||||
// EventHook register gohook event
|
||||
func EventHook(when uint8, keysPressed []string, callback func(hook.Event)) {
|
||||
hook.Register(when, keysPressed, callback)
|
||||
}
|
||||
|
||||
// AddEvent add event listener,
|
||||
//
|
||||
// parameters for the string type,
|
||||
// the keyboard corresponding key parameters,
|
||||
//
|
||||
// mouse arguments: mleft, center, mright, wheelDown, wheelUp,
|
||||
// wheelLeft, wheelRight.
|
||||
//
|
||||
// Use "robotgo.AddEvents()" or "gohook" add asynchronous event listener
|
||||
func AddEvent(key string) bool {
|
||||
var (
|
||||
// cs *C.char
|
||||
mArr = []string{"mleft", "center", "mright", "wheelDown",
|
||||
"wheelUp", "wheelLeft", "wheelRight"}
|
||||
mouseBool bool
|
||||
)
|
||||
|
||||
for i := 0; i < len(mArr); i++ {
|
||||
if key == mArr[i] {
|
||||
mouseBool = true
|
||||
}
|
||||
}
|
||||
|
||||
if len(key) > 1 && !mouseBool {
|
||||
key = strconv.Itoa(int(Keycode[key]))
|
||||
}
|
||||
|
||||
geve := hook.AddEvent(key)
|
||||
// defer C.free(unsafe.Pointer(cs))
|
||||
return geve == 0
|
||||
}
|
||||
|
||||
// AddEvents add global event hook
|
||||
//
|
||||
// robotgo.AddEvents("q")
|
||||
// robotgo.AddEvents("q", "ctrl")
|
||||
// robotgo.AddEvents("q", "ctrl", "shift")
|
||||
func AddEvents(key string, arr ...string) bool {
|
||||
s := hook.Start()
|
||||
// defer hook.End()
|
||||
|
||||
ct := false
|
||||
k := 0
|
||||
for {
|
||||
e := <-s
|
||||
|
||||
l := len(arr)
|
||||
if l > 0 {
|
||||
for i := 0; i < l; i++ {
|
||||
ukey := Keycode[arr[i]]
|
||||
|
||||
if e.Kind == hook.KeyHold && e.Keycode == ukey {
|
||||
k++
|
||||
}
|
||||
|
||||
if k == l {
|
||||
ct = true
|
||||
}
|
||||
|
||||
if e.Kind == hook.KeyUp && e.Keycode == ukey {
|
||||
if k > 0 {
|
||||
k--
|
||||
}
|
||||
// time.Sleep(10 * time.Microsecond)
|
||||
ct = false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ct = true
|
||||
}
|
||||
|
||||
if ct && e.Kind == hook.KeyUp && e.Keycode == Keycode[key] {
|
||||
hook.End()
|
||||
// k = 0
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// AddMouse add mouse event hook
|
||||
//
|
||||
// mouse arguments: left, center, right, wheelDown, wheelUp,
|
||||
// wheelLeft, wheelRight.
|
||||
//
|
||||
// robotgo.AddMouse("left")
|
||||
// robotgo.AddMouse("left", 100, 100)
|
||||
func AddMouse(btn string, x ...int16) bool {
|
||||
s := hook.Start()
|
||||
ukey := MouseMap[btn]
|
||||
|
||||
ct := false
|
||||
for {
|
||||
e := <-s
|
||||
|
||||
if len(x) > 1 {
|
||||
if e.Kind == hook.MouseMove && e.X == x[0] && e.Y == x[1] {
|
||||
ct = true
|
||||
}
|
||||
} else {
|
||||
ct = true
|
||||
}
|
||||
|
||||
if ct && e.Kind == hook.MouseDown && e.Button == ukey {
|
||||
hook.End()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// AddMousePos add listen mouse event pos hook
|
||||
func AddMousePos(x, y int16) bool {
|
||||
s := hook.Start()
|
||||
|
||||
for {
|
||||
e := <-s
|
||||
if e.Kind == hook.MouseMove && e.X == x && e.Y == y {
|
||||
hook.End()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
Loading…
Reference in New Issue
Block a user