void genFillTileWithNAN(struct KgenContext *ctx, const Tile *tile) { char tmp[1024]; Kstring elem; unsigned int incRows, incCols; unsigned int i, j, v; if (!tile->trans) { incRows = 1; v = incCols = umin(tile->vecLen, tile->nrCols); } else { v = incRows = umin(tile->vecLen, tile->nrRows); incCols = 1; } for (i = 0; i < tile->nrRows; i += incRows) { for (j = 0; j < tile->nrCols; j += incCols) { sprintfTileElement(&elem, tile, i, j, v); sprintf(tmp, "%s = NAN;\n", elem.buf); kgenAddStmt(ctx, tmp); } } kgenAddBlankLine(ctx); }
//////////////////////////////////////////////////////////////////////////////// // Merge step 1: find sample ranks in each segment //////////////////////////////////////////////////////////////////////////////// static void generateSampleRanks( uint *ranksA, uint *ranksB, uint *srcKey, uint stride, uint N, uint sortDir ){ uint lastSegmentElements = N % (2 * stride); uint sampleCount = (lastSegmentElements > stride) ? (N + 2 * stride - lastSegmentElements) / (2 * SAMPLE_STRIDE) : (N - lastSegmentElements) / (2 * SAMPLE_STRIDE); for(uint pos = 0; pos < sampleCount; pos++){ const uint i = pos & ( (stride / SAMPLE_STRIDE) - 1 ); const uint segmentBase = (pos - i) * (2 * SAMPLE_STRIDE); const uint lenA = stride; const uint lenB = umin(stride, N - segmentBase - stride); const uint nA = stride / SAMPLE_STRIDE; const uint nB = getSampleCount(lenB); if(i < nA){ ranksA[(segmentBase + 0) / SAMPLE_STRIDE + i] = i * SAMPLE_STRIDE; ranksB[(segmentBase + 0) / SAMPLE_STRIDE + i] = binarySearchExclusive(srcKey[segmentBase + i * SAMPLE_STRIDE], srcKey + segmentBase + stride, lenB, sortDir); } if(i < nB){ ranksB[(segmentBase + stride) / SAMPLE_STRIDE + i] = i * SAMPLE_STRIDE; ranksA[(segmentBase + stride) / SAMPLE_STRIDE + i] = binarySearchInclusive(srcKey[segmentBase + stride + i * SAMPLE_STRIDE], srcKey + segmentBase, lenA, sortDir); } } }
bool BitmapFloat_copy_linear_over_srgb(Context * context, BitmapFloat * src, const uint32_t from_row, BitmapBgra * dest, const uint32_t dest_row, const uint32_t row_count, const uint32_t from_col, const uint32_t col_count, const bool transpose) { const uint32_t dest_bytes_pp = BitmapPixelFormat_bytes_per_pixel (dest->fmt); const uint32_t dest_row_stride = transpose ? dest_bytes_pp : dest->stride; const uint32_t dest_pixel_stride = transpose ? dest->stride : dest_bytes_pp; const uint32_t srcitems = umin(from_col + col_count, src->w) *src->channels; const uint32_t ch = src->channels; const bool copy_alpha = dest->fmt == Bgra32 && src->channels == 4 && src->alpha_meaningful; const bool clean_alpha = !copy_alpha && dest->fmt == Bgra32; for (uint32_t row = 0; row < row_count; row++) { float * src_row = src->pixels + (row + from_row) * src->float_stride; uint8_t * dest_row_bytes = dest->pixels + (dest_row + row) * dest_row_stride + (from_col * dest_pixel_stride); for (uint32_t ix = from_col * ch; ix < srcitems; ix += ch) { dest_row_bytes[0] = Context_floatspace_to_srgb (context, src_row[ix]); dest_row_bytes[1] = Context_floatspace_to_srgb (context, src_row[ix + 1]); dest_row_bytes[2] = Context_floatspace_to_srgb (context, src_row[ix + 2]); if (copy_alpha) { dest_row_bytes[3] = uchar_clamp_ff (src_row[ix + 3] * 255.0f); } if (clean_alpha) { dest_row_bytes[3] = 0xff; } dest_row_bytes += dest_pixel_stride; } } return true; }
//////////////////////////////////////////////////////////////////////////////// // Merge step 2: merge ranks and indices to derive elementary intervals //////////////////////////////////////////////////////////////////////////////// static void mergeRanksAndIndices( uint *limits, uint *ranks, uint stride, uint N ){ uint lastSegmentElements = N % (2 * stride); uint sampleCount = (lastSegmentElements > stride) ? (N + 2 * stride - lastSegmentElements) / (2 * SAMPLE_STRIDE) : (N - lastSegmentElements) / (2 * SAMPLE_STRIDE); for(uint pos = 0; pos < sampleCount; pos++){ const uint i = pos & ( (stride / SAMPLE_STRIDE) - 1 ); const uint segmentBase = (pos - i) * (2 * SAMPLE_STRIDE); const uint lenA = stride; const uint lenB = umin(stride, N - segmentBase - stride); const uint nA = stride / SAMPLE_STRIDE; const uint nB = getSampleCount(lenB); if(i < nA){ uint dstPosA = binarySearchExclusive(ranks[(segmentBase + 0) / SAMPLE_STRIDE + i], ranks + (segmentBase + stride) / SAMPLE_STRIDE, nB, 1) + i; assert( dstPosA < nA + nB ); limits[(segmentBase / SAMPLE_STRIDE) + dstPosA] = ranks[(segmentBase + 0) / SAMPLE_STRIDE + i]; } if(i < nB){ uint dstPosA = binarySearchInclusive(ranks[(segmentBase + stride) / SAMPLE_STRIDE + i], ranks + (segmentBase + 0) / SAMPLE_STRIDE, nA, 1) + i; assert( dstPosA < nA + nB ); limits[(segmentBase / SAMPLE_STRIDE) + dstPosA] = ranks[(segmentBase + stride) / SAMPLE_STRIDE + i]; } } }
unsigned int tileLineSegmentLen(const Tile *tile) { unsigned int pitch; unsigned int len; pitch = tilePitch(tile); len = umin(pitch, tile->vecLen); if (tile->trans) { len = umin(len, tile->nrRows); } else { len = umin(len, tile->nrCols); } return len; }
/* * Common line segment length of 2 tiles being arguments in tile multiplication */ static unsigned int commonTileSegmentLen(const Tile *tile1, const Tile *tile2) { unsigned int u1, u2; u1 = tileLineSegmentLen(tile1); u2 = tileLineSegmentLen(tile2); return umin(u1, u2); }
static NTSTATUS DDKAPI finaread(PDEVICE_OBJECT d, PIRP i) { NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION sl = IoGetCurrentIrpStackLocation(i); unsigned sz = umin(sl->Parameters.Read.Length, g_outcurr); RtlCopyMemory(i->AssociatedIrp.SystemBuffer, g_outbuf, sz); g_outcurr = 0; i->IoStatus.Status = status; i->IoStatus.Information = sz; IoCompleteRequest(i, IO_NO_INCREMENT); return status; }
static size_t r_stats( struct uufile *f, void *dest, size_t bytes) { struct kernel_stats out; errno_t rc = get_stats_record( f->pos++, &out ); if( rc ) return 0; int nc = umin( bytes, sizeof(out) ); memcpy( dest, &out, nc ); return nc; }
// TODO are we sure we can give it all out? static size_t r_threads( struct uufile *f, void *dest, size_t bytes) { phantom_thread_t out; tid_t t = get_next_tid( f->pos, &out); f->pos = t; if( t < 0 ) return 0; int nc = umin( bytes, sizeof(out) ); memcpy( dest, &out, nc ); return nc; }
static uint binarySearchExclusive(uint val, uint *data, uint L, uint sortDir){ if(L == 0) return 0; uint pos = 0; for(uint stride = nextPowerOfTwo(L); stride > 0; stride >>= 1){ uint newPos = umin(pos + stride, L); if( (sortDir && (data[newPos - 1] < val)) || (!sortDir && (data[newPos - 1] > val)) ) pos = newPos; } return pos; }
static bool BitmapFloat_compose_linear_over_srgb(Context * context, BitmapFloat * src, const uint32_t from_row, BitmapBgra * dest, const uint32_t dest_row, const uint32_t row_count, const uint32_t from_col, const uint32_t col_count, const bool transpose) { const uint32_t dest_bytes_pp = BitmapPixelFormat_bytes_per_pixel (dest->fmt); const uint32_t dest_row_stride = transpose ? dest_bytes_pp : dest->stride; const uint32_t dest_pixel_stride = transpose ? dest->stride : dest_bytes_pp; const uint32_t srcitems = umin(from_col + col_count, src->w) *src->channels; const uint32_t ch = src->channels; const bool dest_alpha = dest->fmt == Bgra32 && dest->alpha_meaningful; const uint8_t dest_alpha_index = dest_alpha ? 3 : 0; const float dest_alpha_to_float_coeff = dest_alpha ? 1.0f / 255.0f : 0.0f; const float dest_alpha_to_float_offset = dest_alpha ? 0.0f : 1.0f; for (uint32_t row = 0; row < row_count; row++) { //const float * const __restrict src_row = src->pixels + (row + from_row) * src->float_stride; float * src_row = src->pixels + (row + from_row) * src->float_stride; uint8_t * dest_row_bytes = dest->pixels + (dest_row + row) * dest_row_stride + (from_col * dest_pixel_stride); for (uint32_t ix = from_col * ch; ix < srcitems; ix += ch) { const uint8_t dest_b = dest_row_bytes[0]; const uint8_t dest_g = dest_row_bytes[1]; const uint8_t dest_r = dest_row_bytes[2]; const uint8_t dest_a = dest_row_bytes[dest_alpha_index]; const float src_b = src_row[ix + 0]; const float src_g = src_row[ix + 1]; const float src_r = src_row[ix + 2]; const float src_a = src_row[ix + 3]; const float a = (1.0f - src_a) * (dest_alpha_to_float_coeff * dest_a + dest_alpha_to_float_offset); const float b = Context_srgb_to_floatspace (context, dest_b) * a + src_b; const float g = Context_srgb_to_floatspace (context, dest_g) * a + src_g; const float r = Context_srgb_to_floatspace (context, dest_r) * a + src_r; const float final_alpha = src_a + a; dest_row_bytes[0] = Context_floatspace_to_srgb (context, b / final_alpha); dest_row_bytes[1] = Context_floatspace_to_srgb (context,g / final_alpha); dest_row_bytes[2] = Context_floatspace_to_srgb (context,r / final_alpha); if (dest_alpha) { dest_row_bytes[3] = uchar_clamp_ff(final_alpha * 255); } dest_row_bytes += dest_pixel_stride; } } return true; }
//============================================================================== bool LRBSpline2D::overlaps(Element2D *el) const //============================================================================== { // Does it make sense to include equality? if (el->umin() >= umax()) return false; if (el->umax() <= umin()) return false; if (el->vmin() >= vmax()) return false; if (el->vmax() <= vmin()) return false; return true; }
//============================================================================== bool LRBSpline2D::overlaps(double domain[]) const //============================================================================== { // Does it make sense to include equality? if (domain[0] >= umax()) return false; if (domain[1] <= umin()) return false; if (domain[2] >= vmax()) return false; if (domain[3] <= vmin()) return false; return true; }
static void mergeElementaryIntervals( uint *dstKey, uint *dstVal, uint *srcKey, uint *srcVal, uint *limitsA, uint *limitsB, uint stride, uint N, uint sortDir ){ uint lastSegmentElements = N % (2 * stride); uint mergePairs = (lastSegmentElements > stride) ? getSampleCount(N) : (N - lastSegmentElements) / SAMPLE_STRIDE; for(uint pos = 0; pos < mergePairs; pos++){ uint i = pos & ( (2 * stride) / SAMPLE_STRIDE - 1 ); uint segmentBase = (pos - i) * SAMPLE_STRIDE; const uint lenA = stride; const uint lenB = umin(stride, N - segmentBase - stride); const uint nA = stride / SAMPLE_STRIDE; const uint nB = getSampleCount(lenB); const uint n = nA + nB; const uint startPosA = limitsA[pos]; const uint endPosA = (i + 1 < n) ? limitsA[pos + 1] : lenA; const uint startPosB = limitsB[pos]; const uint endPosB = (i + 1 < n) ? limitsB[pos + 1] : lenB; const uint startPosDst = startPosA + startPosB; assert( startPosA <= endPosA && endPosA <= lenA); assert( startPosB <= endPosB && endPosB <= lenB); assert( (endPosA - startPosA) <= SAMPLE_STRIDE); assert( (endPosB - startPosB) <= SAMPLE_STRIDE); merge( dstKey + segmentBase + startPosDst, dstVal + segmentBase + startPosDst, (srcKey + segmentBase + 0) + startPosA, (srcVal + segmentBase + 0) + startPosA, (srcKey + segmentBase + stride) + startPosB, (srcVal + segmentBase + stride) + startPosB, endPosA - startPosA, endPosB - startPosB, sortDir ); } }
bool BitmapBgra_convert_srgb_to_linear(Context * context, BitmapBgra * src, uint32_t from_row, BitmapFloat * dest, uint32_t dest_row, uint32_t row_count) { if (src->w != dest->w || BitmapPixelFormat_bytes_per_pixel(src->fmt) < dest->channels) { CONTEXT_error(context, Invalid_internal_state); return false; } if (!(from_row + row_count <= src->h && dest_row + row_count <= dest->h)) { CONTEXT_error(context, Invalid_internal_state); return false; } const uint32_t w = src->w; const uint32_t units = w * BitmapPixelFormat_bytes_per_pixel(src->fmt); const uint32_t from_step = BitmapPixelFormat_bytes_per_pixel(src->fmt); const uint32_t to_step = dest->channels; const uint32_t copy_step = umin(from_step, to_step); for (uint32_t row = 0; row < row_count; row++) { uint8_t* src_start = src->pixels + (from_row + row)*src->stride; float* buf = dest->pixels + (dest->float_stride * (row + dest_row)); if (copy_step == 3) { for (uint32_t to_x = 0, bix = 0; bix < units; to_x += to_step, bix += from_step) { buf[to_x] = Context_srgb_to_floatspace(context, src_start[bix]); buf[to_x + 1] = Context_srgb_to_floatspace (context, src_start[bix + 1]); buf[to_x + 2] = Context_srgb_to_floatspace (context, src_start[bix + 2]); } //We're only working on a portion... dest->alpha_premultiplied = false; } else if (copy_step == 4) { for (uint32_t to_x = 0, bix = 0; bix < units; to_x += to_step, bix += from_step) { { const float alpha = ((float)src_start[bix + 3]) / 255.0f; buf[to_x] = alpha * Context_srgb_to_floatspace (context, src_start[bix]); buf[to_x + 1] = alpha * Context_srgb_to_floatspace (context, src_start[bix + 1]); buf[to_x + 2] = alpha * Context_srgb_to_floatspace (context, src_start[bix + 2]); buf[to_x + 3] = alpha; } } //We're only working on a portion... dest->alpha_premultiplied = true; } else { CONTEXT_error (context, Unsupported_pixel_format); return false; } } return true; }
int _GrViDrvVESAsetVirtualSize(GrVideoMode *md,int w,int h,GrVideoMode *result) { Int86Regs r; sttzero(&r); IREG_AX(r) = VESA_FUNC + VESA_SCAN_LNLEN; IREG_BX(r) = 0; IREG_CX(r) = w; int10(&r); if(IREG_AX(r) == VESA_SUCCESS) { result->lineoffset = IREG_BX(r); result->width = IREG_CX(r); result->height = umin(IREG_DX(r),h); return(TRUE); } return(FALSE); }
bool BitmapFloat_scale_rows(Context * context, BitmapFloat * from, uint32_t from_row, BitmapFloat * to, uint32_t to_row, uint32_t row_count, PixelContributions * weights) { const uint32_t from_step = from->channels; const uint32_t to_step = to->channels; const uint32_t dest_buffer_count = to->w; const uint32_t min_channels = umin(from_step, to_step); uint32_t ndx; if (min_channels > 4) { CONTEXT_error(context, Invalid_internal_state); return false; } float avg[4]; // if both have alpha, process it if (from_step == 4 && to_step == 4) { for (uint32_t row = 0; row < row_count; row++) { const float* __restrict source_buffer = from->pixels + ((from_row + row) * from->float_stride); float* __restrict dest_buffer = to->pixels + ((to_row + row) * to->float_stride); for (ndx = 0; ndx < dest_buffer_count; ndx++) { float r = 0, g = 0, b = 0, a = 0; const int left = weights[ndx].Left; const int right = weights[ndx].Right; const float* __restrict weightArray = weights[ndx].Weights; int i; /* Accumulate each channel */ for (i = left; i <= right; i++) { const float weight = weightArray[i - left]; b += weight * source_buffer[i * from_step]; g += weight * source_buffer[i * from_step + 1]; r += weight * source_buffer[i * from_step + 2]; a += weight * source_buffer[i * from_step + 3]; } dest_buffer[ndx * to_step] = b; dest_buffer[ndx * to_step + 1] = g; dest_buffer[ndx * to_step + 2] = r; dest_buffer[ndx * to_step + 3] = a; } } } else if (from_step == 3 && to_step == 3) {
void check_branch_relocation( void* fromArg, void* toArg, int32 countArg) { inst_t *from = (inst_t*)fromArg, *to = (inst_t*)toArg; int32 count = countArg / sizeof(inst_t); if ( umax((uint32)from, (uint32)to) < umin((uint32)from + count, (uint32) to + count)) return; // overlapping, too hard to check for ( int32 i = 0; i < count; ++i) { inst_t* f = (inst_t*)get_target_of_branch_instruction(&from[i]); inst_t* t = (inst_t*)get_target_of_branch_instruction(& to[i]); if (f == NULL) ; else if (from <= f && f < from+count) f += to - from; if (f != t) fatal2("check_branch_relocation: branch at 0x%x moved to 0x%x but is wrong", &from[i], &to[i]); } }
bool BitmapBgra_flip_vertical(Context * context, BitmapBgra * b) { void* swap = CONTEXT_malloc(context,b->stride); if (swap == NULL) { CONTEXT_error(context, Out_of_memory); return false; } //Dont' copy the full stride (padding), it could be windowed! uint32_t row_length = umin (b->stride, b->w * BitmapPixelFormat_bytes_per_pixel (b->fmt)); for (uint32_t i = 0; i < b->h / 2; i++) { void* top = b->pixels + (i * b->stride); void* bottom = b->pixels + ((b->h - 1 - i) * b->stride); memcpy (swap, top, row_length); memcpy(top, bottom, row_length); memcpy (bottom, swap, row_length); } CONTEXT_free(context,swap); return true; }
int forEachTile(Kstring *kstr, unsigned int row, unsigned int col, unsigned int num, Tile *first, ...) { unsigned int minVecLen = first->vecLen; unsigned int valRow = first->nrRows; unsigned int valCol = first->nrCols; va_list argptr; unsigned int i; va_start(argptr, first); for (i = 1; i < num; i++) { Tile * cur = va_arg( argptr, Tile * ); minVecLen = umin(minVecLen, cur->vecLen); } va_end(argptr); if (first->trans) { valRow /= minVecLen; } else { valCol /= minVecLen; } if (row >= valRow || col >= valCol /*|| row < 0 || col < 0*/) { //would be signed return 0; } if (kstr) { va_start(argptr, first); for (i = 0; i < num; i++) { Tile * cur = i ? va_arg( argptr, Tile * ) : first; if (cur->baseName) { unsigned int vRow = (cur->trans ? row * minVecLen : row); unsigned int vCol = (cur->trans ? col : col * minVecLen); sprintfTileElement(&kstr[i], cur, vRow, vCol, minVecLen); } } va_end(argptr); } return first->trans ? valRow : valCol; }
void initTile( Tile *tile, const char *baseName, unsigned int nrRows, unsigned int nrCols, unsigned int vecLen, DataType dtype, PrivateStorageType storType, bool trans, bool packed) { assert(baseName == NULL || strlen(baseName) <= MAX_TILE_BASE_NAMELEN); tile->baseName = baseName; tile->nrRows = nrRows; tile->nrCols = nrCols; tile->vecLen = umin(MAX_TILE_VECLEN, vecLen); tile->dtype = dtype; tile->storType = storType; tile->trans = trans; tile->packed = packed; }
void genTileCopy( struct KgenContext *ctx, const Tile *dst, const Tile *src, TileCopyOps op) { char tmp[1024]; Kstring el1, el2; unsigned int nrRows, nrCols; unsigned int incRows, incCols; unsigned int vlen; unsigned int i, j; nrRows = umin(dst->nrRows, src->nrRows); nrCols = umin(dst->nrCols, src->nrCols); if (dst->trans != src->trans) { vlen = 1; incRows = incCols = 1; } else { vlen = umin(dst->vecLen, src->vecLen); if (!dst->trans) { incRows = 1; incCols = umin(dst->nrCols, src->nrCols); incCols = umin(incCols, vlen); } else { incRows = umin(dst->nrRows, src->nrRows); incRows = umin(incRows, vlen); incCols = 1; } } for (i = 0; i < nrRows; i += incRows) { for (j = 0; j < nrCols; j += incCols) { sprintfTileElement(&el1, dst, i, j, vlen); sprintfTileElement(&el2, src, i, j, vlen); switch( op ) { case TILECOPY_ASSIGN: sprintf(tmp, "%s = %s;\n", el1.buf, el2.buf); break; case TILECOPY_ADD_ASSIGN: sprintf(tmp, "%s += %s;\n", el1.buf, el2.buf); break; case TILECOPY_SUB_ASSIGN: sprintf(tmp, "%s -= %s;\n", el1.buf, el2.buf); break; case TILECOPY_MUL_ASSIGN: sprintf(tmp, "%s *= %s;\n", el1.buf, el2.buf); break; case TILECOPY_DIV_ASSIGN: sprintf(tmp, "%s /= %s;\n", el1.buf, el2.buf); break; case TILECOPY_MOD_ASSIGN: sprintf(tmp, "%s %%= %s;\n", el1.buf, el2.buf); break; default: break; } kgenAddStmt(ctx, tmp); } } kgenAddBlankLine(ctx); }
static void initTiles( BlasGenSettings* gset, TileSet* tileSet, const struct SubproblemDim *subdims, KernelExtraFlags kflags, DataType dtype, PrivateStorageType storType) { unsigned int rowsA; unsigned int rowsB; unsigned int rowsC; unsigned int colsA; unsigned int colsB; unsigned int colsC; bool transA; bool transB; unsigned int vecLenA; unsigned int vecLenB; unsigned int vecLenC; rowsA = (unsigned int)subdims[1].y; colsA = (unsigned int)szmax(subdims[1].y, subdims[1].bwidth); rowsB = (unsigned int)szmax(subdims[1].y, subdims[1].bwidth); colsB = (unsigned int)szmax(subdims[1].x, subdims[1].y); rowsC = (unsigned int)subdims[1].y; colsC = (unsigned int)subdims[1].x; transA = isMatrixAccessColMaj(CLBLAS_TRSM, kflags, MATRIX_A); transB = isMatrixAccessColMaj(CLBLAS_TRSM, kflags, MATRIX_B); vecLenA = (unsigned int)((transA) ? subdims[1].y : subdims[1].bwidth); vecLenA = umin(vecLenA, MAX_TILE_VECLEN); vecLenB = (unsigned int)((transB) ? subdims[1].x : subdims[1].bwidth); vecLenB = umin(vecLenB, MAX_TILE_VECLEN); vecLenC = (transB) ? vecLenB : vecLenA; initTile(&tileSet->rectA, "a", (unsigned int)subdims[1].y, (unsigned int)subdims[1].bwidth, vecLenA, dtype, storType, transA, false); initTile(&tileSet->squareA, "a", (unsigned int)subdims[1].y, (unsigned int)subdims[1].y, vecLenA, dtype, storType, transA, false); initTile(&tileSet->origB, "b", (unsigned int)subdims[1].bwidth, (unsigned int)subdims[1].x, vecLenB, dtype, storType, !transB, false); initTile(&tileSet->bStage2, "b", (unsigned int)subdims[1].y, (unsigned int)subdims[1].x, vecLenB, dtype, storType, !transB, false); initTile(&tileSet->bAsSqA, "b", (unsigned int)subdims[1].y, (unsigned int)subdims[1].y, vecLenB, dtype, storType, transA, false); initTile(&tileSet->bAsC, "b", (unsigned int)subdims[1].y, (unsigned int)subdims[1].x, vecLenB, dtype, storType, gset->tileCY.trans, false); initTile(&gset->tileA, "a", rowsA, colsA, vecLenA, dtype, storType, transA, false); initTile(&gset->tileBX, "b", rowsB, colsB, vecLenB, dtype, storType, !transB, false); initTile(&gset->tileCY, "c", rowsC, colsC, vecLenC, dtype, storType, !transB, false); tileSet->A = gset->tileA; tileSet->B = gset->tileBX; }
int DjVuPalette::compute_palette(int maxcolors, int minboxsize) { if (!hist) G_THROW( ERR_MSG("DjVuPalette.no_color") ); if (maxcolors<1 || maxcolors>MAXPALETTESIZE) G_THROW( ERR_MSG("DjVuPalette.many_colors") ); // Paul Heckbert: "Color Image Quantization for Frame Buffer Display", // SIGGRAPH '82 Proceedings, page 297. (also in ppmquant) // Collect histogram colors int sum = 0; int ncolors = 0; GTArray<PData> pdata; { // extra nesting for windows for (GPosition p = *hist; p; ++p) { pdata.touch(ncolors); PData &data = pdata[ncolors++]; int k = hist->key(p); data.p[0] = (k>>16) & 0xff; data.p[1] = (k>>8) & 0xff; data.p[2] = (k) & 0xff; data.w = (*hist)[p]; sum += data.w; } } // Create first box GList<PBox> boxes; PBox newbox; newbox.data = pdata; newbox.colors = ncolors; newbox.boxsize = 256; newbox.sum = sum; boxes.append(newbox); // Repeat spliting boxes while (boxes.size() < maxcolors) { // Find suitable box GPosition p; for (p=boxes; p; ++p) if (boxes[p].colors>=2 && boxes[p].boxsize>minboxsize) break; if (! p) break; // Find box boundaries PBox &splitbox = boxes[p]; unsigned char pmax[3]; unsigned char pmin[3]; pmax[0] = pmin[0] = splitbox.data->p[0]; pmax[1] = pmin[1] = splitbox.data->p[1]; pmax[2] = pmin[2] = splitbox.data->p[2]; { // extra nesting for windows for (int j=1; j<splitbox.colors; j++) { pmax[0] = umax(pmax[0], splitbox.data[j].p[0]); pmax[1] = umax(pmax[1], splitbox.data[j].p[1]); pmax[2] = umax(pmax[2], splitbox.data[j].p[2]); pmin[0] = umin(pmin[0], splitbox.data[j].p[0]); pmin[1] = umin(pmin[1], splitbox.data[j].p[1]); pmin[2] = umin(pmin[2], splitbox.data[j].p[2]); } } // Determine split direction and sort int bl = pmax[0]-pmin[0]; int gl = pmax[1]-pmin[1]; int rl = pmax[2]-pmin[2]; splitbox.boxsize = (bl>gl ? (rl>bl ? rl : bl) : (rl>gl ? rl : gl)); if (splitbox.boxsize <= minboxsize) continue; if (gl == splitbox.boxsize) qsort(splitbox.data, splitbox.colors, sizeof(PData), gcomp); else if (rl == splitbox.boxsize) qsort(splitbox.data, splitbox.colors, sizeof(PData), rcomp); else qsort(splitbox.data, splitbox.colors, sizeof(PData), bcomp); // Find median int lowercolors = 0; int lowersum = 0; while (lowercolors<splitbox.colors-1 && lowersum+lowersum<splitbox.sum) lowersum += splitbox.data[lowercolors++].w; // Compute new boxes newbox.data = splitbox.data + lowercolors; newbox.colors = splitbox.colors - lowercolors; newbox.sum = splitbox.sum - lowersum; splitbox.colors = lowercolors; splitbox.sum = lowersum; // Insert boxes at proper location GPosition q; for (q=p; q; ++q) if (boxes[q].sum < newbox.sum) break; boxes.insert_before(q, newbox); for (q=p; q; ++q) if (boxes[q].sum < splitbox.sum) break; boxes.insert_before(q, boxes, p); } // Fill palette array ncolors = 0; palette.empty(); palette.resize(0,boxes.size()-1); { // extra nesting for windows for (GPosition p=boxes; p; ++p) { PBox &box = boxes[p]; // Compute box representative color float bsum = 0; float gsum = 0; float rsum = 0; for (int j=0; j<box.colors; j++) { float w = (float)box.data[j].w; bsum += box.data[j].p[0] * w; gsum += box.data[j].p[1] * w; rsum += box.data[j].p[2] * w; } PColor &color = palette[ncolors++]; color.p[0] = (unsigned char) fmin(255, bsum/box.sum); color.p[1] = (unsigned char) fmin(255, gsum/box.sum); color.p[2] = (unsigned char) fmin(255, rsum/box.sum); color.p[3] = ( color.p[0]*BMUL + color.p[1]*GMUL + color.p[2]*RMUL) / SMUL; } } // Save dominant color PColor dcolor = palette[0]; // Sort palette colors in luminance order qsort((PColor*)palette, ncolors, sizeof(PColor), lcomp); // Clear invalid data colordata.empty(); delete pmap; pmap = 0; // Return dominant color return color_to_index_slow(dcolor.p); }
static bool Render1D(Context * context, const Renderer * r, BitmapBgra * pSrc, BitmapBgra * pDst, const RenderDetails * details, bool transpose, int call_number) { bool success= true; //How many rows to buffer and process at a time. uint32_t buffer_row_count = 4; //using buffer=5 seems about 6% better than most other non-zero values. //How many bytes per pixel are we scaling? BitmapPixelFormat scaling_format = (pSrc->fmt == Bgra32 && !pSrc->alpha_meaningful) ? Bgr24 : pSrc->fmt; BitmapFloat * buf = BitmapFloat_create(context,pSrc->w, buffer_row_count, scaling_format, false); if (buf == NULL) { return false; } buf->alpha_meaningful = pSrc->alpha_meaningful; buf->alpha_premultiplied = buf->channels == 4; /* Scale each set of lines */ for (uint32_t source_start_row = 0; source_start_row < pSrc->h; source_start_row += buffer_row_count) { const uint32_t row_count = umin(pSrc->h - source_start_row, buffer_row_count); if (!BitmapBgra_convert_srgb_to_linear(context, pSrc, source_start_row, buf, 0, row_count)) { CONTEXT_add_to_callstack (context); success=false; goto cleanup; } if (!ApplyConvolutionsFloat1D(context, r, buf, 0, row_count, 0)) { CONTEXT_add_to_callstack (context); success=false; goto cleanup; } if (details->apply_color_matrix && call_number == 2) { if (!ApplyColorMatrix(context, r, buf, row_count)) { CONTEXT_add_to_callstack (context); success=false; goto cleanup; } } if (!BitmapFloat_pivoting_composite_linear_over_srgb(context, buf, 0, pDst, source_start_row, row_count, transpose)) { CONTEXT_add_to_callstack (context); success=false; goto cleanup; } } //sRGB sharpening //Color matrix cleanup: BitmapFloat_destroy(context,buf); return success; }
static bool ScaleAndRender1D(Context * context, const Renderer * r, BitmapBgra * pSrc, BitmapBgra * pDst, const RenderDetails * details, bool transpose, int call_number) { LineContributions * contrib = NULL; BitmapFloat * source_buf = NULL; BitmapFloat * dest_buf = NULL; uint32_t from_count = pSrc->w; uint32_t to_count = transpose ? pDst->h : pDst->w; bool success = true; if (details->interpolation->window == 0) { CONTEXT_error(context, Invalid_argument); return false; } //How many rows to buffer and process at a time. const uint32_t buffer_row_count = 4; //using buffer=5 seems about 6% better than most other non-zero values. //How many bytes per pixel are we scaling? BitmapPixelFormat scaling_format = (pSrc->fmt == Bgra32 && !pSrc->alpha_meaningful) ? Bgr24 : pSrc->fmt; prof_start(context,"contributions_calc", false); contrib = LineContributions_create(context, to_count, from_count, details->interpolation); if (contrib == NULL) { CONTEXT_add_to_callstack (context); success = false; goto cleanup; } prof_stop(context,"contributions_calc", true, false); prof_start(context,"create_bitmap_float (buffers)", false); source_buf = BitmapFloat_create(context, from_count, buffer_row_count, scaling_format, false); if (source_buf == NULL) { CONTEXT_add_to_callstack (context); success = false; goto cleanup; } dest_buf = BitmapFloat_create(context, to_count, buffer_row_count, scaling_format, false); if (dest_buf == NULL) { CONTEXT_add_to_callstack (context); success = false; goto cleanup; } source_buf->alpha_meaningful = pSrc->alpha_meaningful; dest_buf->alpha_meaningful = source_buf->alpha_meaningful; source_buf->alpha_premultiplied = source_buf->channels == 4; dest_buf->alpha_premultiplied = source_buf->alpha_premultiplied; prof_stop(context,"create_bitmap_float (buffers)", true, false); /* Scale each set of lines */ for (uint32_t source_start_row = 0; source_start_row < pSrc->h; source_start_row += buffer_row_count) { const uint32_t row_count = umin(pSrc->h - source_start_row, buffer_row_count); prof_start(context,"convert_srgb_to_linear", false); if (!BitmapBgra_convert_srgb_to_linear(context,pSrc, source_start_row, source_buf, 0, row_count)) { CONTEXT_add_to_callstack (context); success=false; goto cleanup; } prof_stop(context,"convert_srgb_to_linear", true, false); prof_start(context,"ScaleBgraFloatRows", false); if (!BitmapFloat_scale_rows(context, source_buf, 0, dest_buf, 0, row_count, contrib->ContribRow)) { CONTEXT_add_to_callstack (context); success=false; goto cleanup; } prof_stop(context,"ScaleBgraFloatRows", true, false); if (!ApplyConvolutionsFloat1D(context, r, dest_buf, 0, row_count, contrib->percent_negative)) { CONTEXT_add_to_callstack (context); success=false; goto cleanup; } if (details->apply_color_matrix && call_number == 2) { if (!ApplyColorMatrix(context, r, dest_buf, row_count)) { CONTEXT_add_to_callstack (context); success=false; goto cleanup; } } prof_start(context,"pivoting_composite_linear_over_srgb", false); if (!BitmapFloat_pivoting_composite_linear_over_srgb(context, dest_buf, 0, pDst, source_start_row, row_count, transpose)) { CONTEXT_add_to_callstack (context); success=false; goto cleanup; } prof_stop(context,"pivoting_composite_linear_over_srgb", true, false); } //sRGB sharpening //Color matrix cleanup: //p->Start("Free Contributions,FloatBuffers", false); if (contrib != NULL) LineContributions_destroy(context, contrib); if (source_buf != NULL) BitmapFloat_destroy(context, source_buf); if (dest_buf != NULL) BitmapFloat_destroy(context, dest_buf); ///p->Stop("Free Contributions,FloatBuffers", true, false); return success; }
void GrMouseSetAccel(int thresh, int accel) { MOUINFO->thresh = umin(64, umax(1, thresh)); MOUINFO->accel = umin(16, umax(1, accel)); }
void GrMouseSetSpeed(int spmult, int spdiv) { MOUINFO->spmult = umin(16, umax(1, spmult)); MOUINFO->spdiv = umin(16, umax(1, spdiv)); }
afs_int32 UDP_GetTicket(int ksoc, struct packet *pkt, afs_int32 kvno, char *authDomain, char *ticket, int ticketLen, char *auth, int authLen) { afs_int32 code; struct ktc_encryptionKey tgskey; char name[MAXKTCNAMELEN]; char inst[MAXKTCNAMELEN]; char cell[MAXKTCREALMLEN]; struct ktc_encryptionKey authSessionKey; afs_int32 host; Date start; Date authEnd; Date now = time(0); int celllen; int import; char *packet; int slen; int byteOrder = pkt->byteOrder; char sname[MAXKTCNAMELEN]; char sinst[MAXKTCNAMELEN]; afs_int32 time_ws; unsigned char life; struct ubik_trans *tt; afs_int32 to; struct kaentry caller; struct kaentry server; Date reqEnd; struct ktc_encryptionKey sessionKey; int newTicketLen; char newTicket[MAXKTCTICKETLEN]; char cipher[2 * MAXKTCTICKETLEN]; /* put encrypted part of answer here */ int cipherLen; struct packet ans; COUNT_REQ(UGetTicket); if ((code = InitAuthServ(&tt, LOCKREAD, this_op))) goto fail; code = ka_LookupKvno(tt, KA_TGS_NAME, ((strlen(authDomain) > 0) ? authDomain : lrealm), kvno, &tgskey); if (code) goto abort; code = tkt_DecodeTicket(ticket, ticketLen, &tgskey, name, inst, cell, &authSessionKey, &host, &start, &authEnd); pkt->name = name; pkt->inst = inst; pkt->realm = cell; if (code) { code = KERB_ERR_AUTH_EXP; /* was KANOAUTH */ goto abort; } save_principal(udptgsPrincipal, name, inst, cell); code = tkt_CheckTimes(start, authEnd, now); if (code <= 0) { if (code == -1) { code = KERB_ERR_SERVICE_EXP; /* was RXKADEXPIRED */ goto abort; } code = KERB_ERR_AUTH_EXP; /* was KANOAUTH */ goto abort; } celllen = strlen(cell); import = 0; if ((strlen(authDomain) > 0) && (strcmp(authDomain, lrealm) != 0)) import = 1; if (import && (celllen == 0)) { code = KERB_ERR_PKT_VER; /* was KABADTICKET */ goto abort; } if (celllen == 0) { strncpy(cell, lrealm, MAXKTCREALMLEN - 1); cell[MAXKTCREALMLEN - 1] = 0; }; if (!krb4_cross && strcmp(lrealm, cell) != 0) { code = KERB_ERR_PRINCIPAL_UNKNOWN; goto abort; } if (krb_udp_debug) { printf("UGetTicket: got ticket from '%s'.'%s'@'%s'\n", name, inst, cell); } code = check_auth(pkt, auth, authLen, &authSessionKey, name, inst, cell); if (code) goto abort; /* authenticator and all is OK so read actual request */ packet = pkt->rest; getint(time_ws); life = *(unsigned char *)packet++; getstr(sname); getstr(sinst); start = now; reqEnd = life_to_time(start, life); if (krb_udp_debug) { printf("UGetTicket: request for server '%s'.'%s'\n", sname, sinst); } save_principal(udptgsServerPrincipal, sname, sinst, 0); if (import) { strcpy(caller.userID.name, name); strcpy(caller.userID.instance, inst); caller.max_ticket_lifetime = htonl(MAXKTCTICKETLIFETIME); } else { code = FindBlock(tt, name, inst, &to, &caller); if (code) goto abort; if (to == 0) { ka_PrintUserID("GetTicket: User ", name, inst, " unknown.\n"); code = KERB_ERR_PRINCIPAL_UNKNOWN; /* KANOENT */ goto abort; } if (ntohl(caller.flags) & KAFNOTGS) { code = KERB_ERR_AUTH_EXP; /* was KABADUSER */ goto abort; } } code = FindBlock(tt, sname, sinst, &to, &server); /* get server's entry */ if (code) goto abort; if (to == 0) { /* entry not found */ ka_PrintUserID("GetTicket: Server ", sname, sinst, " unknown.\n"); code = KERB_ERR_PRINCIPAL_UNKNOWN; /* KANOENT */ goto abort; } code = ubik_EndTrans(tt); if (code) goto fail; if (ntohl(server.flags) & KAFNOSEAL) return KABADSERVER; code = DES_new_random_key(ktc_to_cblock(&sessionKey)); if (code) { code = KERB_ERR_NULL_KEY; /* was KANOKEYS */ goto fail; } reqEnd = umin(umin(reqEnd, authEnd), umin(start + ntohl(caller.max_ticket_lifetime), start + ntohl(server.max_ticket_lifetime))); code = tkt_MakeTicket(newTicket, &newTicketLen, &server.key, caller.userID.name, caller.userID.instance, cell, start, reqEnd, &sessionKey, htonl(pkt->from.sin_addr.s_addr), server.userID.name, server.userID.instance); if (code) goto fail; cipherLen = sizeof(cipher); code = create_cipher(cipher, &cipherLen, &sessionKey, sname, sinst, start, reqEnd, ntohl(server.key_version), newTicket, newTicketLen, &authSessionKey); if (code) goto fail; code = create_reply(&ans, name, inst, start, reqEnd, 0, cipher, cipherLen); if (code) goto fail; code = sendto(ksoc, ans.data, ans.len, 0, (struct sockaddr *)&pkt->from, sizeof(pkt->from)); if (code != ans.len) { perror("calling sendto"); code = -1; goto fail; } if (cipherLen != 0) { KALOG(name, inst, sname, sinst, NULL, host, LOG_GETTICKET); } osi_audit(UDPGetTicketEvent, 0, AUD_STR, name, AUD_STR, inst, AUD_STR, cell, AUD_STR, sname, AUD_STR, sinst, AUD_END); return 0; abort: ubik_AbortTrans(tt); fail: osi_audit(UDPGetTicketEvent, code, AUD_STR, name, AUD_STR, inst, AUD_STR, NULL, AUD_STR, NULL, AUD_STR, NULL, AUD_END); return code; }
afs_int32 UDP_Authenticate(int ksoc, struct sockaddr_in *client, char *name, char *inst, Date startTime, Date endTime, char *sname, char *sinst) { struct ubik_trans *tt; afs_int32 to; /* offset of block */ struct kaentry tentry; afs_int32 tgskvno; /* key version of service key */ struct ktc_encryptionKey tgskey; /* service key for encrypting ticket */ int tgt; Date now = time(0); afs_int32 code; char ticket[MAXKTCTICKETLEN]; /* our copy of the ticket */ int ticketLen; struct ktc_encryptionKey sessionKey; /* we have to invent a session key */ char cipher[2 * MAXKTCTICKETLEN]; /* put encrypted part of answer here */ int cipherLen; struct packet ans; COUNT_REQ(UAuthenticate); if (!name_instance_legal(name, inst)) return KERB_ERR_NAME_EXP; /* KABADNAME */ if ((code = InitAuthServ(&tt, LOCKREAD, this_op))) return code; code = FindBlock(tt, name, inst, &to, &tentry); if (code) goto abort; if (to) { /* if user exists check other stuff */ afs_int32 sto; struct kaentry sentry; save_principal(udpAuthPrincipal, name, inst, 0); tgt = ((strcmp(sname, KA_TGS_NAME) == 0) && (strcmp(sinst, lrealm) == 0)); if ((ntohl(tentry.user_expiration) < now) || (tgt && (ntohl(tentry.flags) & KAFNOTGS))) { code = KERB_ERR_NAME_EXP; /* KABADUSER */ goto abort; } code = FindBlock(tt, KA_TGS_NAME, lrealm, &sto, &sentry); if (code) goto abort; if (sto == 0) { code = KANOENT; goto abort; } if ((ntohl(sentry.user_expiration) < now)) { code = KERB_ERR_NAME_EXP; /* XXX Could use another error code XXX */ goto abort; } if (abs(startTime - now) > KTC_TIME_UNCERTAINTY) { code = KERB_ERR_SERVICE_EXP; /* was KABADREQUEST */ goto abort; } if (tentry.misc_auth_bytes) { unsigned char misc_auth_bytes[4]; afs_uint32 temp; /* unsigned for safety */ afs_uint32 pwexpires; memcpy(&temp, tentry.misc_auth_bytes, sizeof(afs_uint32)); temp = ntohl(temp); unpack_long(temp, misc_auth_bytes); pwexpires = misc_auth_bytes[0]; if (pwexpires) { pwexpires = ntohl(tentry.change_password_time) + 24 * 60 * 60 * pwexpires; if (pwexpires < now) { code = KERB_ERR_AUTH_EXP; /* was KAPWEXPIRED */ goto abort; } } } /* make the ticket */ code = DES_new_random_key(ktc_to_cblock(&sessionKey)); if (code) { code = KERB_ERR_NULL_KEY; /* was KANOKEYS */ goto abort; } endTime = umin(endTime, startTime + ntohl(tentry.max_ticket_lifetime)); if ((code = ka_LookupKey(tt, sname, sinst, &tgskvno, &tgskey)) || (code = tkt_MakeTicket(ticket, &ticketLen, &tgskey, name, inst, lrealm, startTime, endTime, &sessionKey, htonl(client->sin_addr.s_addr), sname, sinst))) goto abort; cipherLen = sizeof(cipher); code = create_cipher(cipher, &cipherLen, &sessionKey, sname, sinst, startTime, endTime, tgskvno, ticket, ticketLen, &tentry.key); if (code) goto abort; } else { /* no such user */ cipherLen = 0; tentry.key_version = 0; } code = ubik_EndTrans(tt); if (code) goto fail; code = create_reply(&ans, name, inst, startTime, endTime, ntohl(tentry.key_version), cipher, cipherLen); if (code) goto fail; if (krb_udp_debug) { printf("Sending %d bytes ending in: ", ans.len); ka_PrintBytes(ans.data + ans.len - 8, 8); printf("\n"); } code = sendto(ksoc, ans.data, ans.len, 0, (struct sockaddr *)client, sizeof(*client)); if (code != ans.len) { perror("calling sendto"); code = -1; goto fail; } KALOG(name, inst, sname, sinst, NULL, client->sin_addr.s_addr, LOG_AUTHENTICATE); if (cipherLen != 0) { KALOG(name, inst, sname, sinst, NULL, client->sin_addr.s_addr, LOG_TGTREQUEST); } osi_audit(UDPAuthenticateEvent, 0, AUD_STR, name, AUD_STR, inst, AUD_END); return 0; abort: COUNT_ABO; ubik_AbortTrans(tt); fail: osi_audit(UDPAuthenticateEvent, code, AUD_STR, name, AUD_STR, inst, AUD_END); return code; }