void image_normalize(const img_header_t* head, const int slice_size, uint8_t* data, int min, int max, int newMin, int newMax) { int i; int displ = DISPLACEMENT(head); int channels = head->channels; #pragma omp parallel for private(i) for(i = 0; i < slice_size; i+=displ) { if(channels == 1) data[i] = (data[i] - min) * (newMax - newMin) / (max - min) + newMin; else { rgb_point_t rgb; hsv_point_t hsv; rgb.r = data[i]; rgb.g = data[i+1]; rgb.b = data[i+2]; hsv = rgb2hsv(&rgb); hsv.v = (hsv.v - min) * (newMax - newMin) / (max - min) + newMin; rgb = hsv2rgb(&hsv); data[i] = rgb.r; data[i+1] = rgb.g; data[i+2] = rgb.b; } } }
bool Region::addrandomemptyconnection(Direction direction, Point location) { if (points[location] == Background::Door || points[location] == Background::MarkedDoor) return false; for (uint8_t i = (uint8_t)Direction::Up; i <= (uint8_t)Direction::Down; i++) { Point pd = PAIR_SUM(location, DISPLACEMENT((Direction)i)); if (points[pd] == Background::Door || points[pd] == Background::MarkedDoor) return false; } points[location] = Background::Door; Connection nConnection = { location, NULL, Point(0, 0), direction }; // connections.push_back(nConnection); connections[location] = nConnection; return true; }
void image_get_bounds(const img_header_t* head, const int slice_size, uint8_t* data, int* min, int* max) { int displ = DISPLACEMENT(head); int channels = head->channels; *min = 0; *max = 0; #pragma omp parallel { int i; int loc_min = 0; int loc_max = 0; #pragma omp for nowait for(i = 0; i < slice_size; i+=displ) { if(channels == 1) { loc_min = MIN(data[i], loc_min); loc_max = MAX(data[i], loc_max); } else { rgb_point_t rgb; hsv_point_t hsv; rgb.r = data[i]; rgb.g = data[i+1]; rgb.b = data[i+2]; hsv = rgb2hsv(&rgb); loc_min = MIN(hsv.v, loc_min); loc_max = MAX(hsv.v, loc_max); } } #pragma omp critical { *min = MIN(loc_min, *min); *max = MAX(loc_max, *max); } } }
Region::Region(int w, int h, RoomType type) { if (!initgen) { // Initialise probdist - but only once std::random_device rd; gen = std::mt19937(rd()); probdist = std::uniform_real_distribution<double>(0, 1); initgen = true; } width = w; height = h; this->type = type; switch (type) { case RoomType::Room: for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { Point tp = Point(x, y); points[tp] = Background::TiledFloor; if (probdist(gen) < GOLD_PROB) placeItem(tp, ItemType::Gold); if (probdist(gen) < STAFF_PROB) placeItem(tp, ItemType::Staff); if (probdist(gen) < CHEST_PROB) placeItem(tp, ItemType::Chest); } points[Point(x, -1)] = Background::StoneWall; points[Point(x, h)] = Background::StoneWall; } for (int y = -1; y <=h; y++) { points[Point(-1, y)] = Background::StoneWall; points[Point(w, y)] = Background::StoneWall; } // points[Point(5, 3)] = Background::DirtWall; { idist = std::uniform_int_distribution<int>(4, 4 + (w + h) / 2); int maxconnections = idist(gen); numConnections = 0; idist = std::uniform_int_distribution<int>(0, 4); for (uint8_t i = 0; i < 4; i++) { if (addrandomemptyconnection((Direction)(i))) numConnections++; } for (uint8_t i = 4; i < maxconnections; i++) { if (addrandomemptyconnection((Direction)(idist(gen)))) numConnections++; } // printf("%d->%d\n", maxconnections, numConnections); } break; case RoomType::Corridor: for (int x = -1; x <= w; x++) for (int y = -1; y <= h; y++) points[Point(x, y)] = Background::StoneWall; { std::uniform_int_distribution<int> ydist(0, h - 1); int y = ydist(gen); for (int x = 0; x < w; x++) points[Point(x, y)] = Background::TiledFloor; addrandomemptyconnection(Direction::Left, Point(-1, y)); addrandomemptyconnection(Direction::Right, Point(w, y)); } { std::uniform_int_distribution<int> xdist(0, w - 1); int x = xdist(gen); for (int y = 0; y < h; y++) points[Point(x, y)] = Background::TiledFloor; addrandomemptyconnection(Direction::Up, Point(x, -1)); addrandomemptyconnection(Direction::Down, Point(x, h)); } break; case RoomType::Spiral: for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { Point tp = Point(x, y); points[tp] = Background::TiledFloor; // if (probdist(gen) < GOLD_PROB) // placeItem(tp, ItemType::Gold); // if (probdist(gen) < STAFF_PROB) // placeItem(tp, ItemType::Staff); // if (probdist(gen) < CHEST_PROB) // placeItem(tp, ItemType::Chest); } points[Point(x, -1)] = Background::StoneWall; points[Point(x, h)] = Background::StoneWall; } for (int y = -1; y <=h; y++) { points[Point(-1, y)] = Background::StoneWall; points[Point(w, y)] = Background::StoneWall; } if (h >= 3 && w >= 3){ // Draw spiral int layers = (MIN(w, h) - 2) / 4; int layercount = 0; Point currentlyDrawing = {1,0}; Direction drawdir = Direction::Down; auto contLine = [layers, &layercount, w, h, &drawdir, this](Point pt) -> bool { // printf("%d\n", (layercount + 1) * 2); switch (drawdir) { case Direction::Down: return pt.second < h - (layercount + 1) * 2; case Direction::Up: return pt.second >= (layercount + 1) * 2; case Direction::Left: return pt.first >= (layercount + 2) * 2; // Because want to actually spiral case Direction::Right: // printf("%d\n", w - (layercount + 1) * 2); return pt.first < w - (layercount + 1) * 2; default: fprintf(stderr, "Direction weirdness here\n"); return false; } }; auto turnDir = [&layercount, &drawdir]() { switch (drawdir) { case Direction::Down: drawdir = Direction::Right; break; case Direction::Up: drawdir = Direction::Left; break; case Direction::Left: drawdir = Direction::Down; layercount++; break; case Direction::Right: drawdir = Direction::Up; break; default: fprintf(stderr, "Direction weirdness here\n"); break; } }; while (layercount < layers && currentlyDrawing.second >= 0 && currentlyDrawing.first >= 0) { // printf("Printing at %d:%d\n", currentlyDrawing.first, currentlyDrawing.second); points[currentlyDrawing] = Background::StoneWall; if (!contLine(currentlyDrawing)) { turnDir(); // printf("Turning to direction %d; layercount = %d\n", (int)drawdir, layercount); } currentlyDrawing = PAIR_SUM(currentlyDrawing, DISPLACEMENT(drawdir)); } points[Point(1, 3)] = Background::Door; } { addrandomemptyconnection(Direction::Up, {0, -1}); idist = std::uniform_int_distribution<int>(4, 4 + (w + h) / 2); int maxconnections = idist(gen); numConnections = 0; idist = std::uniform_int_distribution<int>(0, 4); for (uint8_t i = 0; i < 4 && i < maxconnections; i++) { if (addrandomemptyconnection((Direction)(i))) numConnections++; } for (uint8_t i = 4; i < maxconnections; i++) { if (addrandomemptyconnection((Direction)(idist(gen)))) numConnections++; } } break; default: fprintf(stderr, "Unimplemented RoomType\n"); break; } }