bool ReadCubeCrossConstructor(FloatPixMapRef sourceImage, RenderFlags flags, SphericalPixelSourceFunction *source, void **context) { if (sourceImage == NULL || context == NULL) return false; ReadCubeContext *cx = malloc(sizeof (ReadCubeContext)); if (cx == NULL) return false; cx->pm = FPMRetain(sourceImage); FPMSize totalSize = FPMGetSize(sourceImage); if (totalSize.width % 4 != 0 || totalSize.height % 3 != 0) { fprintf(stderr, "Cross cube map width must be a multiple of four pixels and height must be a multiple of three pixels.\n"); return false; } cx->faceSize.width = totalSize.width / 4; cx->faceSize.height = totalSize.height / 3; cx->halfWidth = (float)cx->faceSize.width / 2.0; cx->halfHeight = (float)cx->faceSize.height / 2.0; cx->maxX = (float)cx->faceSize.width - 1.0f; cx->maxY = (float)cx->faceSize.height - 1.0f; cx->pxPos = (FPMPoint){ 2 * cx->faceSize.width, 1 * cx->faceSize.height }; cx->nxPos = (FPMPoint){ 0 * cx->faceSize.width, 1 * cx->faceSize.height }; cx->pyPos = (FPMPoint){ 1 * cx->faceSize.width, 0 * cx->faceSize.height }; cx->nyPos = (FPMPoint){ 1 * cx->faceSize.width, 2 * cx->faceSize.height }; cx->pzPos = (FPMPoint){ 1 * cx->faceSize.width, 1 * cx->faceSize.height }; cx->nzPos = (FPMPoint){ 3 * cx->faceSize.width, 1 * cx->faceSize.height }; *context = cx; *source = ReadCube; return true; }
bool ReadCubeConstructor(FloatPixMapRef sourceImage, RenderFlags flags, void **context) { if (sourceImage == NULL || context == NULL) return false; ReadCubeContext *cx = malloc(sizeof (ReadCubeContext)); if (cx == NULL) return false; cx->pm = FPMRetain(sourceImage); FPMSize totalSize = FPMGetSize(sourceImage); if (totalSize.height % 6 != 0) { fprintf(stderr, "Cube map height must be a multiple of six pixels.\n"); return false; } cx->faceSize.width = totalSize.width; cx->faceSize.height = totalSize.height / 6; cx->halfWidth = (float)cx->faceSize.width / 2.0f; cx->halfHeight = (float)cx->faceSize.height / 2.0f; cx->maxX = (float)cx->faceSize.width - 1.0f; cx->maxY = (float)cx->faceSize.height - 1.0f; cx->pxPos = (FPMPoint) { 0, 0 * cx->faceSize.height }; cx->nxPos = (FPMPoint) { 0, 1 * cx->faceSize.height }; cx->pyPos = (FPMPoint) { 0, 2 * cx->faceSize.height }; cx->nyPos = (FPMPoint) { 0, 3 * cx->faceSize.height }; cx->pzPos = (FPMPoint) { 0, 4 * cx->faceSize.height }; cx->nzPos = (FPMPoint) { 0, 5 * cx->faceSize.height }; *context = cx; return true; }
static FloatPixMapRef MakeFPM(FPMSize size, FPMDimension rowCount, FPMColor *pixels, FloatPixMapRef master) { FloatPixMapRef result = malloc(sizeof (FloatPixMap)); if (result != NULL) { FPM_INTERNAL_ASSERT(FPMSizeArea(size) == 0 || pixels != NULL); FPM_INTERNAL_ASSERT(size.width <= rowCount); result->retainCount = 1; result->width = size.width; result->height = size.height; result->rowCount = rowCount; result->pixels = pixels; result->master = FPMRetain(master); } return result; }
bool ReadLatLongConstructor(FloatPixMapRef sourceImage, RenderFlags flags, SphericalPixelSourceFunction *source, void **context) { if (sourceImage == NULL || context == NULL) return false; ReadLatLongContext *cx = malloc(sizeof (ReadLatLongContext)); if (cx == NULL) return false; cx->pm = FPMRetain(sourceImage); cx->pwidth = FPMGetWidth(sourceImage); cx->width = (float)cx->pwidth / (2.0f * kPiF); cx->height = (float)FPMGetHeight(sourceImage) / kPiF; if (flags & kRenderFast) *source = ReadLatLongFast; else *source = ReadLatLong; *context = cx; return true; }
FloatPixMapRef FPMCopy(FloatPixMapRef pm) { if (pm != NULL) { size_t byteCount = GetPixelCount(pm) * sizeof (FPMColor); if (byteCount == 0) { // One empty pixmap of a given size is the same as another, so we'll stick with the one instead of making another. assert(pm->pixels == NULL); return FPMRetain(pm); } assert(pm->pixels != NULL); void *pixels = malloc(byteCount); if (pixels == NULL) return NULL; if (pm->rowCount == pm->width) { // No padding to skip. memcpy(pixels, pm->pixels, byteCount); } else { // Original is padded, copy row by row. FPMColor *srcPx = pm->pixels; FPMColor *dstPx = pixels; size_t count = pm->height; do { memcpy(dstPx, srcPx, sizeof (FPMColor) * pm->width); srcPx += pm->rowCount; dstPx += pm->width; } while (--count); } return MakeFPM(FPMMakeSize(pm->width, pm->height), pm->width, pixels, NULL); } else { return NULL; } }