/* * To remove a leaf_node: * Search to the tree location appropriate for the given leaf_node's key: * - If location does not hold a matching entry, abort and do nothing. * - Replace the matching leaf_node with a NULL entry (and free the leaf_node). * - Consolidate int_nodes repeatedly, while walking up the tree towards root. */ static void note_tree_remove(struct notes_tree *t, struct int_node *tree, unsigned char n, struct leaf_node *entry) { struct leaf_node *l; struct int_node *parent_stack[20]; unsigned char i, j; void **p = note_tree_search(t, &tree, &n, entry->key_sha1); assert(GET_PTR_TYPE(entry) == 0); /* no type bits set */ if (GET_PTR_TYPE(*p) != PTR_TYPE_NOTE) return; /* type mismatch, nothing to remove */ l = (struct leaf_node *) CLR_PTR_TYPE(*p); if (hashcmp(l->key_sha1, entry->key_sha1)) return; /* key mismatch, nothing to remove */ /* we have found a matching entry */ free(l); *p = SET_PTR_TYPE(NULL, PTR_TYPE_NULL); /* consolidate this tree level, and parent levels, if possible */ if (!n) return; /* cannot consolidate top level */ /* first, build stack of ancestors between root and current node */ parent_stack[0] = t->root; for (i = 0; i < n; i++) { j = GET_NIBBLE(i, entry->key_sha1); parent_stack[i + 1] = CLR_PTR_TYPE(parent_stack[i]->a[j]); } assert(i == n && parent_stack[i] == tree); /* next, unwind stack until note_tree_consolidate() is done */ while (i > 0 && !note_tree_consolidate(parent_stack[i], parent_stack[i - 1], GET_NIBBLE(i - 1, entry->key_sha1))) i--; }
/*writes I16 as hex (no prefix). if tx buffer is full. blocks */ void usart0WriteI16( int16_t i16 ) { register char ch; #define GET_NIBBLE(_n) ch= ( i16 >>( 4 * _n ))& 0x0f ; #if 1 GET_NIBBLE(3) I_TO_CHR SEND_HEX GET_NIBBLE(2) I_TO_CHR SEND_HEX GET_NIBBLE(1) I_TO_CHR SEND_HEX GET_NIBBLE(0) I_TO_CHR SEND_HEX #endif #undef GET_NIBBLE return; }
/*writes I32 as hex (no prefix). if tx buffer is full. blocks */ void usart0WriteI32( int32_t i32 ) { register char ch; //if(ch<'A') *p_i16+=ch-'0';else *p_i16+=ch-'A'+10; /*retry if buffer is full. blocks background process*/ #define GET_NIBBLE(_n) ch=ch= ( i32 >>( 4 * _n ))& 0x0f ; #if 1 GET_NIBBLE(7) I_TO_CHR SEND_HEX GET_NIBBLE(6) I_TO_CHR SEND_HEX GET_NIBBLE(5) I_TO_CHR SEND_HEX GET_NIBBLE(4) I_TO_CHR SEND_HEX GET_NIBBLE(3) I_TO_CHR SEND_HEX GET_NIBBLE(2) I_TO_CHR SEND_HEX GET_NIBBLE(1) I_TO_CHR SEND_HEX GET_NIBBLE(0) I_TO_CHR SEND_HEX #endif #undef GET_NIBBLE return; }
/** @brief Applies palette index mapping for one or several indices on a 1-, 4- or 8-bit palletized image. This function maps up to <i>count</i> palette indices specified in <i>srcindices</i> to these specified in <i>dstindices</i>. Thereby, index <i>srcindices[N]</i>, if present in the image, will be replaced by index <i>dstindices[N]</i>. If parameter <i>swap</i> is TRUE, additionally all indices specified in <i>dstindices</i> are also mapped to these specified in <i>srcindices</i>.<br> The function returns the number of pixels changed or zero, if no pixels were changed. Both arrays <i>srcindices</i> and <i>dstindices</i> are assumed not to hold less than <i>count</i> indices.<br> <b>Note, that this behaviour is different from what FreeImage_ApplyColorMapping() does, which modifies the actual image data on palletized images.</b> @param dib Input/output image to be processed. @param srcindices Array of palette indices to be used as the mapping source. @param dstindices Array of palette indices to be used as the mapping destination. @param count The number of palette indices to be mapped. This is the size of both <i>srcindices</i> and <i>dstindices</i>. @param swap If TRUE, source and destination palette indices are swapped, that is, each destination index is also mapped to the corresponding source index. @return Returns the total number of pixels changed. */ unsigned DLL_CALLCONV FreeImage_ApplyPaletteIndexMapping(FIBITMAP *dib, BYTE *srcindices, BYTE *dstindices, unsigned count, BOOL swap) { unsigned result = 0; if ((!dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP)) { return 0; } // validate parameters if ((!srcindices) || (!dstindices)|| (count < 1)) { return 0; } unsigned height = FreeImage_GetHeight(dib); unsigned width = FreeImage_GetLine(dib); BYTE *a, *b; int bpp = FreeImage_GetBPP(dib); switch (bpp) { case 1: { return result; } case 4: { int skip_last = (FreeImage_GetWidth(dib) & 0x01); unsigned max_x = width - 1; for (unsigned y = 0; y < height; y++) { BYTE *bits = FreeImage_GetScanLine(dib, y); for (unsigned x = 0; x < width; x++) { int start = ((skip_last) && (x == max_x)) ? 1 : 0; for (int cn = start; cn < 2; cn++) { for (unsigned j = 0; j < count; j++) { a = srcindices; b = dstindices; for (int i = ((swap) ? 0 : 1); i < 2; i++) { if (GET_NIBBLE(cn, bits[x]) == (a[j] & 0x0F)) { SET_NIBBLE(cn, bits[x], b[j]); result++; j = count; break; } a = dstindices; b = srcindices; } } } } } return result; } case 8: { for (unsigned y = 0; y < height; y++) { BYTE *bits = FreeImage_GetScanLine(dib, y); for (unsigned x = 0; x < width; x++) { for (unsigned j = 0; j < count; j++) { a = srcindices; b = dstindices; for (int i = ((swap) ? 0 : 1); i < 2; i++) { if (bits[x] == a[j]) { bits[x] = b[j]; result++; j = count; break; } a = dstindices; b = srcindices; } } } } return result; } default: { return 0; } } }