/** * Precompute GCD and bounds transformations */ static int diophantine_precompute(unsigned int n, diophantine_term_t *E, diophantine_term_t *Ep, npy_int64 *Gamma, npy_int64 *Epsilon) { npy_int64 a_gcd, gamma, epsilon, c1, c2; unsigned int j; char overflow = 0; assert(n >= 2); euclid(E[0].a, E[1].a, &a_gcd, &gamma, &epsilon); Ep[0].a = a_gcd; Gamma[0] = gamma; Epsilon[0] = epsilon; if (n > 2) { c1 = E[0].a / a_gcd; c2 = E[1].a / a_gcd; /* Ep[0].ub = E[0].ub * c1 + E[1].ub * c2; */ Ep[0].ub = safe_add(safe_mul(E[0].ub, c1, &overflow), safe_mul(E[1].ub, c2, &overflow), &overflow); if (overflow) { return 1; } } for (j = 2; j < n; ++j) { euclid(Ep[j-2].a, E[j].a, &a_gcd, &gamma, &epsilon); Ep[j-1].a = a_gcd; Gamma[j-1] = gamma; Epsilon[j-1] = epsilon; if (j < n - 1) { c1 = Ep[j-2].a / a_gcd; c2 = E[j].a / a_gcd; /* Ep[j-1].ub = c1 * Ep[j-2].ub + c2 * E[j].ub; */ Ep[j-1].ub = safe_add(safe_mul(c1, Ep[j-2].ub, &overflow), safe_mul(c2, E[j].ub, &overflow), &overflow); if (overflow) { return 1; } } } return 0; }
int main() { const double nums[][2] = { {1, 2}, {0.1, 0.2}, {1e100, 1e-100}, {1e308, 1e308}, }; double ival[2]; int i; for (i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) { /* * Calculate nums[i][0] + nums[i][1]. */ safe_add(ival, nums[i][0], nums[i][1]); /* * Print the result. %.17g gives the best output. * %.16g or plain %g gives not enough digits. */ printf("%.17g + %.17g =\n", nums[i][0], nums[i][1]); printf(" [%.17g, %.17g]\n", ival[0], ival[1]); printf(" size %.17g\n\n", ival[1] - ival[0]); } return 0; }
int __glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen) { __GLXdispatchConvolutionFilterHeader *hdr = (__GLXdispatchConvolutionFilterHeader *) pc; GLint image1size, image2size; GLenum format = hdr->format; GLenum type = hdr->type; GLint w = hdr->width; GLint h = hdr->height; GLint rowLength = hdr->rowLength; GLint alignment = hdr->alignment; if (swap) { format = SWAPL(format); type = SWAPL(type); w = SWAPL(w); h = SWAPL(h); rowLength = SWAPL(rowLength); alignment = SWAPL(alignment); } /* XXX Should rowLength be used for either or both image? */ image1size = __glXImageSize(format, type, 0, w, 1, 1, 0, rowLength, 0, 0, alignment); image2size = __glXImageSize(format, type, 0, h, 1, 1, 0, rowLength, 0, 0, alignment); return safe_add(safe_pad(image1size), image2size); }
/** * Simplify Diophantine decision problem. * * Combine identical coefficients, remove unnecessary variables, and trim * bounds. * * The feasible/infeasible decision result is retained. * * Returns: 0 (success), -1 (integer overflow). */ NPY_VISIBILITY_HIDDEN int diophantine_simplify(unsigned int *n, diophantine_term_t *E, npy_int64 b) { unsigned int i, j, m; char overflow = 0; /* Skip obviously infeasible cases */ for (j = 0; j < *n; ++j) { if (E[j].ub < 0) { return 0; } } if (b < 0) { return 0; } /* Sort vs. coefficients */ qsort(E, *n, sizeof(diophantine_term_t), diophantine_sort_A); /* Combine identical coefficients */ m = *n; i = 0; for (j = 1; j < m; ++j) { if (E[i].a == E[j].a) { E[i].ub = safe_add(E[i].ub, E[j].ub, &overflow); --*n; } else { ++i; if (i != j) { E[i] = E[j]; } } } /* Trim bounds and remove unnecessary variables */ m = *n; i = 0; for (j = 0; j < m; ++j) { E[j].ub = MIN(E[j].ub, b / E[j].a); if (E[j].ub == 0) { /* If the problem is feasible at all, x[i]=0 */ --*n; } else { if (i != j) { E[i] = E[j]; } ++i; } } if (overflow) { return -1; } else { return 0; } }
/* * Allocate and initialize a DexDataMap. Returns NULL on failure. */ DexDataMap* dexDataMapAlloc(u4 maxCount) { /* * Allocate a single chunk for the DexDataMap per se as well as the * two arrays. */ size_t size = 0; DexDataMap* map = NULL; /* * Avoiding pulling in safe_iop for safe_iopf. */ if (!safe_mul(&size, maxCount, sizeof(u4) + sizeof(u2)) || !safe_add(&size, size, sizeof(DexDataMap))) { return NULL; } map = (DexDataMap*) malloc(size); if (map == NULL) { return NULL; } map->count = 0; map->max = maxCount; map->offsets = (u4*) (map + 1); map->types = (u2*) (map->offsets + maxCount); return map; }
void Graphic_base::Color::add_color(Color& c, bool alpha_enabled) { if(alpha_enabled) for(int i = 0; i < 4; i++) comp[i] = alpha_mix(comp[i], c.comp[i], c.comp[3]); else for(int i = 0; i < 4; i++) comp[i] = safe_add(comp[i], c.comp[i]); }
void test_safe_add(){ int32_t a = INT_MAX; int32_t b = 1; // Should produce error int error; int result = safe_add(a, b, &error); print_result(result, error); // Should not result in error a = INT_MIN; error = 0; result = safe_add(a, b, &error); print_result(result, error); }
unsigned light_lt_manager::get_weight_core(expr const & e) { switch (e.kind()) { case expr_kind::Var: case expr_kind::Constant: case expr_kind::Sort: case expr_kind::Meta: case expr_kind::Local: return 1; case expr_kind::Lambda: case expr_kind::Pi: return safe_add(1, safe_add(get_weight(binding_domain(e)), get_weight(binding_body(e)))); case expr_kind::Macro: return safe_add(1, add_weight(macro_num_args(e), macro_args(e))); case expr_kind::App: buffer<expr> args; expr fn = get_app_args(e, args); if (is_constant(fn)) { unsigned const * light_arg = m_lrs.find(const_name(fn)); if (light_arg && args.size() > *light_arg) return get_weight(args[*light_arg]); } return safe_add(1, safe_add(get_weight(app_fn(e)), get_weight(app_arg(e)))); } lean_unreachable(); // LCOV_EXCL_LINE }
int __glXPrioritizeTexturesReqSize( const GLbyte * pc, Bool swap, int reqlen ) { GLsizei n = *(GLsizei *)(pc + 0); if (swap) { n = bswap_32(n); } return safe_pad(safe_add(safe_mul(n , 4), safe_mul(n , 4))); }
int Graphic_base::Color::add(int dst, int src, bool alpha_enabled, bool opaque_bg) { uint8_t* comp_dst = (uint8_t*)&dst; uint8_t* comp_src = (uint8_t*)&src; int result; uint8_t* comp_r = (uint8_t*)&result; if(alpha_enabled) for(int i = 0; i < 4; i++) comp_r[i] = alpha_mix(comp_dst[i], comp_src[i], comp_src[3]); else for(int i = 0; i < 4; i++) comp_r[i] = safe_add(comp_dst[i], comp_src[i]); return result; }
void test_safe_multiply(){ int32_t a = INT_MAX; int32_t b = 1; // Should not result in error int error; int result = safe_multiply(a, b, &error); print_result(result, error); // Should result in error b = 2; error = 0; result = safe_add(a, b, &error); print_result(result, error); }
UInt32 PollingManagerThread::calcSleepTime(bool& rightNow, bool doInit) { rightNow = false; DateTime dtm; dtm.setToCurrent(); time_t tm = dtm.get(); Int32 const int32_max = std::numeric_limits<Int32>::max(); time_t const time_t_max = std::numeric_limits<time_t>::max(); time_t leastTime = (time_t_max > int32_max ? int32_max : time_t_max); // leastTime is now a large positive time_t value that will fit into an // Int32, and hence into a UInt32. int checkedCount = 0; // LOOP INVARIANT: 0 <= leastTime <= int32_max for (size_t i = 0; i < m_triggerRunners.size(); i++) { if (m_triggerRunners[i]->m_isRunning || m_triggerRunners[i]->m_pollInterval == 0) { continue; } if (doInit) { m_triggerRunners[i]->m_nextPoll = safe_add(tm, m_triggerRunners[i]->m_pollInterval); } else if (m_triggerRunners[i]->m_nextPoll <= tm) { rightNow = true; return 0; } // GUARANTEED: m_triggerRunners[i]->m_nextPoll >= tm checkedCount++; time_t diff = m_triggerRunners[i]->m_nextPoll - tm; if (diff < leastTime) { leastTime = diff; } } return (checkedCount == 0) ? 0 : UInt32(leastTime); }
void PollingManagerThread::TriggerRunner::run() { Int32 nextInterval = 0; try { nextInterval = m_itp->poll(createProvEnvRef(m_env)); } catch(std::exception& e) { OW_LOG_ERROR(m_logger, Format("Caught Exception while running poll: %1", e.what())); } catch(ThreadCancelledException& e) { throw; } catch(...) { OW_LOG_ERROR(m_logger, "Caught Unknown Exception while running poll"); } NonRecursiveMutexLock l(m_pollMan->m_triggerGuard); if (nextInterval == 0 || m_pollInterval == 0) // m_pollInterval == 0 means this poller has been instructed to stop { m_pollInterval = 0; m_nextPoll = 0; } else { if (nextInterval > 0) { m_pollInterval = nextInterval; } DateTime dtm; dtm.setToCurrent(); m_nextPoll = safe_add(dtm.get(), m_pollInterval); } m_isRunning = false; m_pollMan->m_triggerCondition.notifyOne(); }
void PollingManagerThread::addPolledProvider(const PolledProviderIFCRef& p) { NonRecursiveMutexLock l(m_triggerGuard); if (m_shuttingDown) return; TriggerRunnerRef tr(new TriggerRunner(this, m_env)); tr->m_pollInterval = p->getInitialPollingInterval(createProvEnvRef(m_env)); OW_LOG_DEBUG(m_logger, Format("PollingManager poll interval for provider" " %1", tr->m_pollInterval)); if (!tr->m_pollInterval) { return; } DateTime dtm; dtm.setToCurrent(); time_t tm = dtm.get(); tr->m_nextPoll = safe_add(tm, tr->m_pollInterval); tr->m_itp = p; m_triggerRunners.append(tr); m_triggerCondition.notifyAll(); }
/** * Solve bounded Diophantine equation * * The problem considered is:: * * A[0] x[0] + A[1] x[1] + ... + A[n-1] x[n-1] == b * 0 <= x[i] <= U[i] * A[i] > 0 * * Solve via depth-first Euclid's algorithm, as explained in [1]. * * If require_ub_nontrivial!=0, look for solutions to the problem * where b = A[0]*(U[0]/2) + ... + A[n]*(U[n-1]/2) but ignoring * the trivial solution x[i] = U[i]/2. All U[i] must be divisible by 2. * The value given for `b` is ignored in this case. */ NPY_VISIBILITY_HIDDEN mem_overlap_t solve_diophantine(unsigned int n, diophantine_term_t *E, npy_int64 b, Py_ssize_t max_work, int require_ub_nontrivial, npy_int64 *x) { mem_overlap_t res; unsigned int j; for (j = 0; j < n; ++j) { if (E[j].a <= 0) { return MEM_OVERLAP_ERROR; } else if (E[j].ub < 0) { return MEM_OVERLAP_NO; } } if (require_ub_nontrivial) { npy_int64 ub_sum = 0; char overflow = 0; for (j = 0; j < n; ++j) { if (E[j].ub % 2 != 0) { return MEM_OVERLAP_ERROR; } ub_sum = safe_add(ub_sum, safe_mul(E[j].a, E[j].ub/2, &overflow), &overflow); } if (overflow) { return MEM_OVERLAP_ERROR; } b = ub_sum; } if (b < 0) { return MEM_OVERLAP_NO; } if (n == 0) { if (require_ub_nontrivial) { /* Only trivial solution for 0-variable problem */ return MEM_OVERLAP_NO; } if (b == 0) { return MEM_OVERLAP_YES; } return MEM_OVERLAP_NO; } else if (n == 1) { if (require_ub_nontrivial) { /* Only trivial solution for 1-variable problem */ return MEM_OVERLAP_NO; } if (b % E[0].a == 0) { x[0] = b / E[0].a; if (x[0] >= 0 && x[0] <= E[0].ub) { return MEM_OVERLAP_YES; } } return MEM_OVERLAP_NO; } else { Py_ssize_t count = 0; diophantine_term_t *Ep = NULL; npy_int64 *Epsilon = NULL, *Gamma = NULL; Ep = malloc(n * sizeof(diophantine_term_t)); Epsilon = malloc(n * sizeof(npy_int64)); Gamma = malloc(n * sizeof(npy_int64)); if (Ep == NULL || Epsilon == NULL || Gamma == NULL) { res = MEM_OVERLAP_ERROR; } else if (diophantine_precompute(n, E, Ep, Gamma, Epsilon)) { res = MEM_OVERLAP_OVERFLOW; } else { res = diophantine_dfs(n, n-1, E, Ep, Gamma, Epsilon, b, max_work, require_ub_nontrivial, x, &count); } free(Ep); free(Gamma); free(Epsilon); return res; } }
static int GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) { GLint compsize, compsize2; GLenum format, type, target; GLboolean swapBytes; __GLXcontext *cx; ClientPtr client = cl->client; int error; __GLX_DECLARE_SWAP_VARIABLES; char *answer, answerBuffer[200]; GLint width = 0, height = 0; xGLXSingleReply reply = { 0, }; cx = __glXForceCurrent(cl, tag, &error); if (!cx) { return error; } __GLX_SWAP_INT(pc + 0); __GLX_SWAP_INT(pc + 4); __GLX_SWAP_INT(pc + 8); format = *(GLenum *) (pc + 4); type = *(GLenum *) (pc + 8); target = *(GLenum *) (pc + 0); swapBytes = *(GLboolean *) (pc + 12); /* target must be SEPARABLE_2D, however I guess we can let the GL barf on this one.... */ glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width); glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height); /* * The two queries above might fail if we're in a state where queries * are illegal, but then width and height would still be zero anyway. */ compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1); if ((compsize = safe_pad(compsize)) < 0) return BadLength; if ((compsize2 = safe_pad(compsize2)) < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); __GLX_GET_ANSWER_BUFFER(answer, cl, safe_add(compsize, compsize2), 1); __glXClearErrorOccured(); glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8), answer, answer + compsize, NULL); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SWAP_REPLY_HEADER(); } else { __GLX_BEGIN_REPLY(compsize + compsize2); __GLX_SWAP_REPLY_HEADER(); __GLX_SWAP_INT(&width); __GLX_SWAP_INT(&height); ((xGLXGetSeparableFilterReply *) &reply)->width = width; ((xGLXGetSeparableFilterReply *) &reply)->height = height; __GLX_SEND_VOID_ARRAY(compsize + compsize2); } return Success; }
void* VectorImpl::_grow(size_t where, size_t amount) { // ALOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d", // this, (int)where, (int)amount, (int)mCount, (int)capacity()); ALOG_ASSERT(where <= mCount, "[%p] _grow: where=%d, amount=%d, count=%d", this, (int)where, (int)amount, (int)mCount); // caller already checked size_t new_size; LOG_ALWAYS_FATAL_IF(!safe_add(&new_size, mCount, amount), "new_size overflow"); if (capacity() < new_size) { // NOTE: This implementation used to resize vectors as per ((3*x + 1) / 2) // (sigh..). Also note, the " + 1" was necessary to handle the special case // where x == 1, where the resized_capacity will be equal to the old // capacity without the +1. The old calculation wouldn't work properly // if x was zero. // // This approximates the old calculation, using (x + (x/2) + 1) instead. size_t new_capacity = 0; LOG_ALWAYS_FATAL_IF(!safe_add(&new_capacity, new_size, (new_size / 2)), "new_capacity overflow"); LOG_ALWAYS_FATAL_IF(!safe_add(&new_capacity, new_capacity, static_cast<size_t>(1u)), "new_capacity overflow"); new_capacity = max(kMinVectorCapacity, new_capacity); size_t new_alloc_size = 0; LOG_ALWAYS_FATAL_IF(!safe_mul(&new_alloc_size, new_capacity, mItemSize), "new_alloc_size overflow"); // ALOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity); if ((mStorage) && (mCount==where) && (mFlags & HAS_TRIVIAL_COPY) && (mFlags & HAS_TRIVIAL_DTOR)) { const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage); SharedBuffer* sb = cur_sb->editResize(new_alloc_size); if (sb) { mStorage = sb->data(); } else { return NULL; } } else { SharedBuffer* sb = SharedBuffer::alloc(new_alloc_size); if (sb) { void* array = sb->data(); if (where != 0) { _do_copy(array, mStorage, where); } if (where != mCount) { const void* from = reinterpret_cast<const uint8_t *>(mStorage) + where*mItemSize; void* dest = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; _do_copy(dest, from, mCount-where); } release_storage(); mStorage = const_cast<void*>(array); } else { return NULL; } } } else { void* array = editArrayImpl(); if (where != mCount) { const void* from = reinterpret_cast<const uint8_t *>(array) + where*mItemSize; void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; _do_move_forward(to, from, mCount - where); } } mCount = new_size; void* free_space = const_cast<void*>(itemLocation(where)); return free_space; }
int __glXDrawArraysReqSize(const GLbyte * pc, Bool swap, int reqlen) { __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc; __GLXdispatchDrawArraysComponentHeader *compHeader; GLint numVertexes = hdr->numVertexes; GLint numComponents = hdr->numComponents; GLint arrayElementSize = 0; GLint x, size; int i; if (swap) { numVertexes = SWAPL(numVertexes); numComponents = SWAPL(numComponents); } pc += sizeof(__GLXdispatchDrawArraysHeader); reqlen -= sizeof(__GLXdispatchDrawArraysHeader); size = safe_mul(sizeof(__GLXdispatchDrawArraysComponentHeader), numComponents); if (size < 0 || reqlen < 0 || reqlen < size) return -1; compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc; for (i = 0; i < numComponents; i++) { GLenum datatype = compHeader[i].datatype; GLint numVals = compHeader[i].numVals; GLint component = compHeader[i].component; if (swap) { datatype = SWAPL(datatype); numVals = SWAPL(numVals); component = SWAPL(component); } switch (component) { case GL_VERTEX_ARRAY: case GL_COLOR_ARRAY: case GL_TEXTURE_COORD_ARRAY: break; case GL_SECONDARY_COLOR_ARRAY: case GL_NORMAL_ARRAY: if (numVals != 3) { /* bad size */ return -1; } break; case GL_FOG_COORD_ARRAY: case GL_INDEX_ARRAY: if (numVals != 1) { /* bad size */ return -1; } break; case GL_EDGE_FLAG_ARRAY: if ((numVals != 1) && (datatype != GL_UNSIGNED_BYTE)) { /* bad size or bad type */ return -1; } break; default: /* unknown component type */ return -1; } x = safe_pad(safe_mul(numVals, __glXTypeSize(datatype))); if ((arrayElementSize = safe_add(arrayElementSize, x)) < 0) return -1; pc += sizeof(__GLXdispatchDrawArraysComponentHeader); } return safe_add(size, safe_mul(numVertexes, arrayElementSize)); }
/** * Calculate the size of an image. * * The size of an image sent to the server from the client or sent from the * server to the client is calculated. The size is based on the dimensions * of the image, the type of pixel data, padding in the image, and the * alignment requirements of the image. * * \param format Format of the pixels. Same as the \c format parameter * to \c glTexImage1D * \param type Type of the pixel data. Same as the \c type parameter * to \c glTexImage1D * \param target Typically the texture target of the image. If the * target is one of \c GL_PROXY_*, the size returned is * always zero. For uses that do not have a texture target * (e.g, glDrawPixels), zero should be specified. * \param w Width of the image data. Must be >= 1. * \param h Height of the image data. Must be >= 1, even for 1D * images. * \param d Depth of the image data. Must be >= 1, even for 1D or * 2D images. * \param imageHeight If non-zero, defines the true height of a volumetric * image. This value will be used instead of \c h for * calculating the size of the image. * \param rowLength If non-zero, defines the true width of an image. This * value will be used instead of \c w for calculating the * size of the image. * \param skipImages Number of extra layers of image data in a volumtric * image that are to be skipped before the real data. * \param skipRows Number of extra rows of image data in an image that are * to be skipped before the real data. * \param alignment Specifies the alignment for the start of each pixel row * in memory. This value must be one of 1, 2, 4, or 8. * * \returns * The size of the image is returned. If the specified \c format and \c type * are invalid, -1 is returned. If \c target is one of \c GL_PROXY_*, zero * is returned. */ int __glXImageSize(GLenum format, GLenum type, GLenum target, GLsizei w, GLsizei h, GLsizei d, GLint imageHeight, GLint rowLength, GLint skipImages, GLint skipRows, GLint alignment) { GLint bytesPerElement, elementsPerGroup, groupsPerRow; GLint groupSize, rowSize, padding, imageSize; if (w == 0 || h == 0 || d == 0) return 0; if (w < 0 || h < 0 || d < 0 || (type == GL_BITMAP && (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX))) { return -1; } /* proxy targets have no data */ switch (target) { case GL_PROXY_TEXTURE_1D: case GL_PROXY_TEXTURE_2D: case GL_PROXY_TEXTURE_3D: case GL_PROXY_TEXTURE_4D_SGIS: case GL_PROXY_TEXTURE_CUBE_MAP: case GL_PROXY_TEXTURE_RECTANGLE_ARB: case GL_PROXY_HISTOGRAM: case GL_PROXY_COLOR_TABLE: case GL_PROXY_TEXTURE_COLOR_TABLE_SGI: case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE: case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE: case GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP: return 0; } /* real data has to have real sizes */ if (imageHeight < 0 || rowLength < 0 || skipImages < 0 || skipRows < 0) return -1; if (alignment != 1 && alignment != 2 && alignment != 4 && alignment != 8) return -1; if (type == GL_BITMAP) { if (rowLength > 0) { groupsPerRow = rowLength; } else { groupsPerRow = w; } rowSize = bits_to_bytes(groupsPerRow); if (rowSize < 0) return -1; padding = (rowSize % alignment); if (padding) { rowSize += alignment - padding; } return safe_mul(safe_add(h, skipRows), rowSize); } else { switch (format) { case GL_COLOR_INDEX: case GL_STENCIL_INDEX: case GL_DEPTH_COMPONENT: case GL_RED: case GL_GREEN: case GL_BLUE: case GL_ALPHA: case GL_LUMINANCE: case GL_INTENSITY: case GL_RED_INTEGER_EXT: case GL_GREEN_INTEGER_EXT: case GL_BLUE_INTEGER_EXT: case GL_ALPHA_INTEGER_EXT: case GL_LUMINANCE_INTEGER_EXT: elementsPerGroup = 1; break; case GL_422_EXT: case GL_422_REV_EXT: case GL_422_AVERAGE_EXT: case GL_422_REV_AVERAGE_EXT: case GL_DEPTH_STENCIL_NV: case GL_DEPTH_STENCIL_MESA: case GL_YCBCR_MESA: case GL_LUMINANCE_ALPHA: case GL_LUMINANCE_ALPHA_INTEGER_EXT: elementsPerGroup = 2; break; case GL_RGB: case GL_BGR: case GL_RGB_INTEGER_EXT: case GL_BGR_INTEGER_EXT: elementsPerGroup = 3; break; case GL_RGBA: case GL_BGRA: case GL_RGBA_INTEGER_EXT: case GL_BGRA_INTEGER_EXT: case GL_ABGR_EXT: elementsPerGroup = 4; break; default: return -1; } switch (type) { case GL_UNSIGNED_BYTE: case GL_BYTE: bytesPerElement = 1; break; case GL_UNSIGNED_BYTE_3_3_2: case GL_UNSIGNED_BYTE_2_3_3_REV: bytesPerElement = 1; elementsPerGroup = 1; break; case GL_UNSIGNED_SHORT: case GL_SHORT: bytesPerElement = 2; break; case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_SHORT_5_6_5_REV: case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_4_4_4_4_REV: case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT_1_5_5_5_REV: case GL_UNSIGNED_SHORT_8_8_APPLE: case GL_UNSIGNED_SHORT_8_8_REV_APPLE: case GL_UNSIGNED_SHORT_15_1_MESA: case GL_UNSIGNED_SHORT_1_15_REV_MESA: bytesPerElement = 2; elementsPerGroup = 1; break; case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: bytesPerElement = 4; break; case GL_UNSIGNED_INT_8_8_8_8: case GL_UNSIGNED_INT_8_8_8_8_REV: case GL_UNSIGNED_INT_10_10_10_2: case GL_UNSIGNED_INT_2_10_10_10_REV: case GL_UNSIGNED_INT_24_8_NV: case GL_UNSIGNED_INT_24_8_MESA: case GL_UNSIGNED_INT_8_24_REV_MESA: bytesPerElement = 4; elementsPerGroup = 1; break; default: return -1; } /* known safe by the switches above, not checked */ groupSize = bytesPerElement * elementsPerGroup; if (rowLength > 0) { groupsPerRow = rowLength; } else { groupsPerRow = w; } if ((rowSize = safe_mul(groupsPerRow, groupSize)) < 0) return -1; padding = (rowSize % alignment); if (padding) { rowSize += alignment - padding; } if (imageHeight > 0) h = imageHeight; h = safe_add(h, skipRows); imageSize = safe_mul(h, rowSize); return safe_mul(safe_add(d, skipImages), imageSize); } }
Graphic_base::Color& Graphic_base::Color::operator+=(Graphic_base::Color& c) { for(int i = 0; i < 4; i++) comp[i] = safe_add(comp[i], c.comp[i]); return *this; }