1. C++ / Говнокод #3973

    +155

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    91. 91
    typedef unsigned char byte;
    
    byte masks[] =
    {
    	0,
    	0x1,
    	0x3,
    	0x7,
    	0xF,
    	0x1F,
    	0x3F,
    	0x7F,
    	0xFF
    };
    
    class RegionBool
    {
    public:
    	RegionBool(unsigned int width, unsigned int height) : w_(width), h_(height), arr_(0), lineLenBytes_(0)
    	{
    		double lineLenBytes = 0;	// байт на строку
    		byte strLenAddBits = static_cast<byte>(modf(static_cast<double>(w_) / 8, &lineLenBytes) * 8);
    		lineLenBytes_ = static_cast<long>(lineLenBytes) + ((strLenAddBits > 0) ? 1 : 0);
    
    		long bytes = lineLenBytes_ * h_;
    		arr_ = new byte[bytes];
    		memset(arr_, 0, bytes);
    	}
    
    	virtual ~RegionBool()
    	{
    		delete[] arr_;
    	}
    
    	inline byte* createLineMask(int x, int w)
    	{
    		// Hey! Attention, animal! Me is you. Listen: you can replace "masks[i]" with "(0xFF >> (8-i))". ХЗ, хав ит фастер.
    
    		byte* mask = new byte[lineLenBytes_];
    		memset(mask, 0, lineLenBytes_);
    
    		double skipBytes = 0;
    		byte startSkipBits = static_cast<byte>(modf(static_cast<double>(x) / 8, &skipBytes) * 8);
    		byte* pmask = mask + static_cast<int>(skipBytes);
    
    
    		byte before = (startSkipBits) ? (8 - startSkipBits) : 0;
    		if (before > w)
    			*pmask |= (masks[w] << startSkipBits);
    		else
    		{
    			if (before)
    				*pmask++ |= (masks[before] << startSkipBits);
    
    			double fillBytes = 0;
    			byte after = static_cast<byte>(modf(static_cast<double>(w - before) / 8, &fillBytes) * 8);
    			
    			if (fillBytes)
    			{
    				memset(pmask, 0xFF, static_cast<int>(fillBytes));
    				pmask += static_cast<int>(fillBytes);
    			}
    
    			if (after)
    				*pmask |= masks[after];
    		}
    
    		return mask;
    	}
    
    	virtual void OR(int x, int y, unsigned int w, unsigned int h)
    	{
    		byte* mask = createLineMask(x,w);
    
    		unsigned int lim = y + h;
    		byte* cur = arr_ + (y * lineLenBytes_);
    		for (unsigned int ty = y; ty < lim; ty++)
    		{
    			byte* m = mask;
    			for (int i = 0; i < lineLenBytes_; i++)
    				*cur++ |= *m++;
    		}
    		delete[] mask;
    	}
    
    private:
    	long lineLenBytes_;
    	unsigned int w_;
    	unsigned int h_;
    	unsigned char* arr_;
    };

    Простите, что много букв.
    Подобие региона, в котором пиксель представлен битом. Операции предполагаются только с прямоугольниками, подразумевается, что прямоугольники вмещаются в регион.
    Рассказывайте мне про меня))

    Запостил: Altravert, 13 Августа 2010

    Комментарии (15) RSS

    • мигающий
      Ответить
    • И давно стало проще обратиться к памяти, чем вычислить (1<<n)-1?
      Ответить
    • Это просто тут все вымерли вечером или этот код так уныл?
      Ответить
    • Оказалось, я не знал раньше о банальной функции div, которая оказалась заметно шустрее здесь (вместо modf).
      Ответить
    • это круто. просто круто.

      double + modf() - гениально. а я как тормоз все еще "(n + (w-1)) % w" делаю...
      а в С++ как идиот std::bitset'ом пользуюсь...
      Ответить
      • У меня есть жесткое условие здесь: не использовать std вообще.
        Ну и с производительностью у меня туго бывает) не учили)
        Ответить
    • Ваще говно. Оно теперь и не подходит.
      Ответить

    Добавить комментарий