remove bitmap and hook code [ci skip]

This commit is contained in:
vcaesar 2022-01-02 17:19:49 -04:00
parent 6c249c12a3
commit 48f1adce7e
49 changed files with 0 additions and 14865 deletions

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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));
}

View File

@ -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 */
}

View File

@ -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 */

View File

@ -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 */
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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";
}
}

View File

@ -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";
}
}

View File

@ -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 */

View File

@ -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;
}
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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
View File

@ -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
}

View File

@ -1 +0,0 @@
C language dependent package, better to compilation. ( zlib and libpng )

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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.

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

File diff suppressed because it is too large Load Diff

View File

@ -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)
}

View File

@ -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
}

View File

@ -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

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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
View File

@ -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
}