/* calc_x_contrib() Calculates the filter weights for a single target column. contribX->p must be freed afterwards. Returns -1 if error, 0 otherwise. */ int calc_x_contrib( CLIST *contribX, double xscale, double fwidth, int dstwidth, int srcwidth, double (*filterf)(double), int i) { double width; double fscale; double center, left, right; double weight; int j, k, n; if(xscale < 1.0) { /* Shrinking image */ width = fwidth / xscale; fscale = 1.0 / xscale; contribX->n = 0; contribX->p = (CONTRIB *)icalloc((int) (width * 2 + 1), sizeof(CONTRIB)); if (contribX->p == NULL) { return -1; } center = (double) i / xscale; left = ceil(center - width); right = floor(center + width); for(j = (int)left; j <= right; ++j) { weight = center - (double) j; weight = (*filterf)(weight / fscale) / fscale; n = wrap_filter_sample(j, srcwidth); k = contribX->n++; contribX->p[k].pixel = n; contribX->p[k].weight = weight; } } else { /* Expanding image */ contribX->n = 0; contribX->p = (CONTRIB*)icalloc((int) (fwidth * 2 + 1), sizeof(CONTRIB)); if (contribX->p == NULL) { return -1; } center = (double) i / xscale; left = ceil(center - fwidth); right = floor(center + fwidth); for(j = (int)left; j <= right; ++j) { weight = center - (double) j; weight = (*filterf)(weight); n = wrap_filter_sample(j, srcwidth); k = contribX->n++; contribX->p[k].pixel = n; contribX->p[k].weight = weight; } } return 0; } /* calc_x_contrib */
ILboolean iCopySubImages(ILimage *Dest, ILimage *Src) { if (Src->Layers) { Dest->Layers = (ILimage*)icalloc(1, sizeof(ILimage)); if (!Dest->Layers) { return IL_FALSE; } if (!iCopySubImage(Dest->Layers, Src->Layers)) return IL_FALSE; } Dest->NumLayers = Src->NumLayers; if (Src->Mipmaps) { Dest->Mipmaps = (ILimage*)icalloc(1, sizeof(ILimage)); if (!Dest->Mipmaps) { return IL_FALSE; } if (!iCopySubImage(Dest->Mipmaps, Src->Mipmaps)) return IL_FALSE; } Dest->NumMips = Src->NumMips; if (Src->Next) { Dest->Next = (ILimage*)icalloc(1, sizeof(ILimage)); if (!Dest->Next) { return IL_FALSE; } if (!iCopySubImage(Dest->Next, Src->Next)) return IL_FALSE; } Dest->NumNext = Src->NumNext; return IL_TRUE; }
ILboolean iCopySubImage(ILimage *Dest, ILimage *Src) { ILimage *DestTemp, *SrcTemp; DestTemp = Dest; SrcTemp = Src; do { ilCopyImageAttr(DestTemp, SrcTemp); DestTemp->Data = (ILubyte*)ialloc(SrcTemp->SizeOfData); if (DestTemp->Data == NULL) { return IL_FALSE; } memcpy(DestTemp->Data, SrcTemp->Data, SrcTemp->SizeOfData); if (SrcTemp->Next) { DestTemp->Next = (ILimage*)icalloc(1, sizeof(ILimage)); if (!DestTemp->Next) { return IL_FALSE; } } else { DestTemp->Next = NULL; } DestTemp = DestTemp->Next; SrcTemp = SrcTemp->Next; } while (SrcTemp); return IL_TRUE; }
ERR ilCreateWS_File(struct WMPStream** ppWS, const char* szFilename, const char* szMode) { ERR err = WMP_errSuccess; struct WMPStream* pWS = NULL; *ppWS = icalloc(1, sizeof(**ppWS)); if (*ppWS == NULL) return WMP_errOutOfMemory; pWS = *ppWS; pWS->Close = iCloseWS_File; pWS->EOS = iEOSWS_File; pWS->Read = iReadWS_File; pWS->Write = iWriteWS_File; //pWS->GetLine = GetLineWS_File; pWS->SetPos = iSetPosWS_File; pWS->GetPos = iGetPosWS_File; //pWS->state.file.pFile = fopen(szFilename, szMode); pWS->state.file.pFile = NULL; //FailIf(NULL == pWS->state.file.pFile, WMP_errFileIO); Cleanup: return err; }
ILAPI ILimage* ILAPIENTRY iluScale_(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth) { ILimage *Scaled, *CurImage, *ToScale; ILenum Format, PalType; CurImage = ilGetCurImage(); Format = Image->Format; if (Format == IL_COLOUR_INDEX) { ilSetCurImage(Image); PalType = Image->Pal.PalType; ToScale = iConvertImage(iluCurImage, ilGetPalBaseType(Image->Pal.PalType), iluCurImage->Type); } else { ToScale = Image; } // So we don't replicate this 3 times (one in each iluScalexD_() function. Scaled = (ILimage*)icalloc(1, sizeof(ILimage)); if (ilCopyImageAttr(Scaled, ToScale) == IL_FALSE) { ilCloseImage(Scaled); if (ToScale != Image) ilCloseImage(ToScale); ilSetCurImage(CurImage); return NULL; } if (ilResizeImage(Scaled, Width, Height, Depth, ToScale->Bpp, ToScale->Bpc) == IL_FALSE) { ilCloseImage(Scaled); if (ToScale != Image) ilCloseImage(ToScale); ilSetCurImage(CurImage); return NULL; } if (Height <= 1 && Image->Height <= 1) { iluScale1D_(ToScale, Scaled, Width); } if (Depth <= 1 && Image->Depth <= 1) { iluScale2D_(ToScale, Scaled, Width, Height); } else { iluScale3D_(ToScale, Scaled, Width, Height, Depth); } if (Format == IL_COLOUR_INDEX) { //ilSetCurImage(Scaled); //ilConvertImage(IL_COLOUR_INDEX); ilSetCurImage(CurImage); ilCloseImage(ToScale); } return Scaled; }
ILAPI ILimage* ILAPIENTRY iluRotate_(ILimage *Image, ILfloat Angle) { ILimage *Rotated = NULL; ILuint x, y, c; ILfloat x0, y0, x1, y1; ILfloat HalfRotW, HalfRotH, HalfImgW, HalfImgH, Cos, Sin; ILuint RotOffset, ImgOffset; ILint XCorner[4], YCorner[4], MaxX, MaxY; ILushort *ShortPtr; ILuint *IntPtr; Rotated = (ILimage*)icalloc(1, sizeof(ILimage)); if (Rotated == NULL) return NULL; if (ilCopyImageAttr(Rotated, Image) == IL_FALSE) { ilCloseImage(Rotated); return NULL; } // Precalculate shit HalfImgW = Image->Width / 2.0f; HalfImgH = Image->Height / 2.0f; Cos = ilCos(Angle); Sin = ilSin(Angle); // Find where edges are in new image (origin in center). XCorner[0] = ilRound(-HalfImgW * Cos - -HalfImgH * Sin); YCorner[0] = ilRound(-HalfImgW * Sin + -HalfImgH * Cos); XCorner[1] = ilRound(HalfImgW * Cos - -HalfImgH * Sin); YCorner[1] = ilRound(HalfImgW * Sin + -HalfImgH * Cos); XCorner[2] = ilRound(HalfImgW * Cos - HalfImgH * Sin); YCorner[2] = ilRound(HalfImgW * Sin + HalfImgH * Cos); XCorner[3] = ilRound(-HalfImgW * Cos - HalfImgH * Sin); YCorner[3] = ilRound(-HalfImgW * Sin + HalfImgH * Cos); MaxX = 0; MaxY = 0; for (x = 0; x < 4; x++) { if (XCorner[x] > MaxX) MaxX = XCorner[x]; if (YCorner[x] > MaxY) MaxY = YCorner[x]; } if (ilResizeImage(Rotated, MaxX * 2, MaxY * 2, 1, Image->Bpp, Image->Bpc) == IL_FALSE) { ilCloseImage(Rotated); return IL_FALSE; } HalfRotW = Rotated->Width / 2.0f; HalfRotH = Rotated->Height / 2.0f; ilClearImage_(Rotated); ShortPtr = (ILushort*)iluCurImage->Data; IntPtr = (ILuint*)iluCurImage->Data; //if (iluFilter == ILU_NEAREST) { switch (iluCurImage->Bpc) { case 1: for (y = 0; y < Rotated->Height; y++) { y0 = y - HalfRotH; for (x = 0; x < Rotated->Width; x++) { x0 = x - HalfRotW; x1 = x0 * Cos - y0 * Sin; y1 = x0 * Sin + y0 * Cos; x1 += HalfImgW; y1 += HalfImgH; if (x1 < Image->Width && x1 >= 0 && y1 < Image->Height && y1 >= 0) { RotOffset = y * Rotated->Bps + x * Rotated->Bpp; ImgOffset = (ILuint)y1 * Image->Bps + (ILuint)x1 * Image->Bpp; for (c = 0; c < Image->Bpp; c++) { Rotated->Data[RotOffset + c] = Image->Data[ImgOffset + c]; } } } } break; case 2: Image->Bps /= 2; Rotated->Bps /= 2; for (y = 0; y < Rotated->Height; y++) { y0 = y - HalfRotH; for (x = 0; x < Rotated->Width; x++) { x0 = x - HalfRotW; x1 = x0 * Cos - y0 * Sin; y1 = x0 * Sin + y0 * Cos; x1 += HalfImgW; y1 += HalfImgH; if (x1 < Image->Width && x1 >= 0 && y1 < Image->Height && y1 >= 0) { RotOffset = y * Rotated->Bps + x * Rotated->Bpp; ImgOffset = (ILuint)y1 * Image->Bps + (ILuint)x1 * Image->Bpp; for (c = 0; c < Image->Bpp; c++) { ((ILushort*)(Rotated->Data))[RotOffset + c] = ShortPtr[ImgOffset + c]; } } } } Image->Bps *= 2; Rotated->Bps *= 2; break; case 4: Image->Bps /= 4; Rotated->Bps /= 4; for (y = 0; y < Rotated->Height; y++) { y0 = y - HalfRotH; for (x = 0; x < Rotated->Width; x++) { x0 = x - HalfRotW; x1 = x0 * Cos - y0 * Sin; y1 = x0 * Sin + y0 * Cos; x1 += HalfImgW; y1 += HalfImgH; if (x1 < Image->Width && x1 >= 0 && y1 < Image->Height && y1 >= 0) { RotOffset = y * Rotated->Bps + x * Rotated->Bpp; ImgOffset = (ILuint)y1 * Image->Bps + (ILuint)x1 * Image->Bpp; for (c = 0; c < Image->Bpp; c++) { ((ILuint*)(Rotated->Data))[RotOffset + c] = IntPtr[ImgOffset + c]; } } } } Image->Bps *= 4; Rotated->Bps *= 4; break; } //} return Rotated; }
//--------------------------------------------------------------------------------------------- // memory allocation; data must be zeroed //--------------------------------------------------------------------------------------------- mng_ptr MNG_DECL mymngalloc(mng_size_t size) { return (mng_ptr)icalloc(1, size); }
/* zoom() Resizes bitmaps while resampling them. Returns -1 if error, 0 if success. */ int zoom( ILimage *dst, ILimage *src, double (*filterf)(double), double fwidth) { ILubyte* tmp; double xscale, yscale; /* zoom scale factors */ int xx; int i, j, k; /* loop variables */ int n; /* pixel number */ double center, left, right; /* filter calculation variables */ double width, fscale, weight; /* filter calculation variables */ ILubyte pel, pel2; int bPelDelta; CLIST *contribY; /* array of contribution lists */ CLIST contribX; int nRet = -1; /* create intermediate column to hold horizontal dst column zoom */ tmp = (ILubyte*)ialloc(src->Height * sizeof(ILubyte)); if (tmp == NULL) { return 0; } xscale = (double) dst->Width / (double) src->Width; /* Build y weights */ /* pre-calculate filter contributions for a column */ contribY = (CLIST*)icalloc(dst->Height, sizeof(CLIST)); if (contribY == NULL) { ifree(tmp); return -1; } yscale = (double) dst->Height / (double) src->Height; if(yscale < 1.0) { width = fwidth / yscale; fscale = 1.0 / yscale; for(i = 0; i < (ILint)dst->Height; ++i) { contribY[i].n = 0; contribY[i].p = (CONTRIB*)icalloc((int) (width * 2 + 1), sizeof(CONTRIB)); if(contribY[i].p == NULL) { ifree(tmp); ifree(contribY); return -1; } center = (double) i / yscale; left = ceil(center - width); right = floor(center + width); for(j = (int)left; j <= right; ++j) { weight = center - (double) j; weight = (*filterf)(weight / fscale) / fscale; n = wrap_filter_sample(j, src->Height); k = contribY[i].n++; contribY[i].p[k].pixel = n; contribY[i].p[k].weight = weight; } } } else { for(i = 0; i < (ILint)dst->Height; ++i) { contribY[i].n = 0; contribY[i].p = (CONTRIB*)icalloc((int) (fwidth * 2 + 1), sizeof(CONTRIB)); if (contribY[i].p == NULL) { ifree(tmp); ifree(contribY); return -1; } center = (double) i / yscale; left = ceil(center - fwidth); right = floor(center + fwidth); for(j = (int)left; j <= right; ++j) { weight = center - (double) j; weight = (*filterf)(weight); n = wrap_filter_sample(j, src->Height); k = contribY[i].n++; contribY[i].p[k].pixel = n; contribY[i].p[k].weight = weight; } } } for(xx = 0; xx < (ILint)dst->Width; xx++) { if(0 != calc_x_contrib(&contribX, xscale, fwidth, dst->Width, src->Width, filterf, xx)) { goto __zoom_cleanup; } /* Apply horz filter to make dst column in tmp. */ for(k = 0; k < (ILint)src->Height; ++k) { weight = 0.0; bPelDelta = IL_FALSE; // Denton: Put get_pixel source here //pel = get_pixel(src, contribX.p[0].pixel, k); pel = src->Data[k * src->Bps + contribX.p[0].pixel * src->Bpp + c]; for(j = 0; j < contribX.n; ++j) { // Denton: Put get_pixel source here //pel2 = get_pixel(src, contribX.p[j].pixel, k); pel2 = src->Data[k * src->Bps + contribX.p[j].pixel * src->Bpp + c]; if(pel2 != pel) bPelDelta = IL_TRUE; weight += pel2 * contribX.p[j].weight; } weight = bPelDelta ? roundcloser(weight) : pel; tmp[k] = (ILubyte)CLAMP(weight, BLACK_PIXEL, WHITE_PIXEL); } /* next row in temp column */ ifree(contribX.p); /* The temp column has been built. Now stretch it vertically into dst column. */ for(i = 0; i < (ILint)dst->Height; ++i) { weight = 0.0; bPelDelta = IL_FALSE; pel = tmp[contribY[i].p[0].pixel]; for(j = 0; j < contribY[i].n; ++j) { pel2 = tmp[contribY[i].p[j].pixel]; if(pel2 != pel) bPelDelta = IL_TRUE; weight += pel2 * contribY[i].p[j].weight; } weight = bPelDelta ? roundcloser(weight) : pel; // Denton: Put set_pixel source here //put_pixel(dst, xx, i, (ILubyte)CLAMP(weight, BLACK_PIXEL, WHITE_PIXEL)); dst->Data[i * dst->Bps + xx * dst->Bpp + c] = (ILubyte)CLAMP(weight, BLACK_PIXEL, WHITE_PIXEL); } /* next dst row */ } /* next dst column */ nRet = 0; /* success */ __zoom_cleanup: ifree(tmp); // Free the memory allocated for vertical filter weights for (i = 0; i < (ILint)dst->Height; ++i) ifree(contribY[i].p); ifree(contribY); return nRet; } /* zoom */
EXPORT void* IAcalloc( size_t nmemb, size_t size, UINT attr ) { return icalloc(nmemb, size, SelIMACB(attr)); }
ILboolean iSaveRleSgi(ILubyte *Data, ILuint w, ILuint h, ILuint numChannels, ILuint bps) { //works only for sgi files with only 1 bpc ILuint c, i, y, j; ILubyte *ScanLine = NULL, *CompLine = NULL; ILuint *StartTable = NULL, *LenTable = NULL; ILuint TableOff, DataOff = 0; ScanLine = (ILubyte*)ialloc(w); CompLine = (ILubyte*)ialloc(w * 2 + 1); // Absolute worst case. StartTable = (ILuint*)ialloc(h * numChannels * sizeof(ILuint)); LenTable = (ILuint*)icalloc(h * numChannels, sizeof(ILuint)); if (!ScanLine || !CompLine || !StartTable || !LenTable) { ifree(ScanLine); ifree(CompLine); ifree(StartTable); ifree(LenTable); return IL_FALSE; } // These just contain dummy values at this point. TableOff = itellw(); iwrite(StartTable, sizeof(ILuint), h * numChannels); iwrite(LenTable, sizeof(ILuint), h * numChannels); DataOff = itellw(); for (c = 0; c < numChannels; c++) { for (y = 0; y < h; y++) { i = y * bps + c; for (j = 0; j < w; j++, i += numChannels) { ScanLine[j] = Data[i]; } ilRleCompressLine(ScanLine, w, 1, CompLine, LenTable + h * c + y, IL_SGICOMP); iwrite(CompLine, 1, *(LenTable + h * c + y)); } } iseekw(TableOff, IL_SEEK_SET); j = h * numChannels; for (y = 0; y < j; y++) { StartTable[y] = DataOff; DataOff += LenTable[y]; #ifdef __LITTLE_ENDIAN__ iSwapUInt(&StartTable[y]); iSwapUInt(&LenTable[y]); #endif } iwrite(StartTable, sizeof(ILuint), h * numChannels); iwrite(LenTable, sizeof(ILuint), h * numChannels); ifree(ScanLine); ifree(CompLine); ifree(StartTable); ifree(LenTable); return IL_TRUE; }