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

    +164

    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
    void load(char *file)
    	{
    		reader = fopen((const char*)file, "r+b");
    		if(reader)
    		{
    			byte *b = (byte*)malloc(sizeof(byte));
    			fread(b, sizeof(byte), 1, reader);
    			if(b == 0x0)
    			{
    				int *wh_val = (int*)malloc(sizeof(int) * 2);
    				fread(wh_val, sizeof(int), 2, reader);
    				width = *wh_val;
    				height = *(wh_val + 1);
    				pixels = (Color**)malloc(sizeof(Color*) * width);
    				for (int i = 0; i < width; ++i)
    				{
    					*(pixels + i) = (Color*)malloc(sizeof(Color) * height);
    					for (int j = 0; j < height; ++j)
    					{
    						byte *rgb = (byte*)malloc(sizeof(byte) * 3);
    						fread(rgb, sizeof(byte), 3, reader);
    						Color c = Color(0);
    						c.red = *(rgb) / 255.0;
    						c.green = *(rgb + 1) / 255.0;
    						c.blue = *(rgb + 2) / 255.0;
    						*(*(pixels + i) + j) = c;
    					}
    				}
    			}
    		}
    	}

    Пишу я код ни о чем не задумываясь, а когда задумался, уже было это.
    ЗЫ. эта ф-ция читает картинку из спец. файла.

    Запостил: psina-from-ua, 28 Августа 2010

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

    • Какой-то c-style для с++
      Ответить
      • Ага, изначально там было смешано и ifstream'ы, и FILE* (reader это FILE*), но потом дошло до такого варианта.
        ЗЫ. Color это клас.
        Ответить
    • как говорится -- где тут)
      Ответить
    • а что за формат такой с сигнатурой 0x0 ?

      строки 10..13 бездельничают
      Ответить
      • 0x0 - это запись числа в 16-тиричной системе счисления.
        Ответить
        • отличненько, везде в dex'е, а там где Ноль, реши в hex'е записать, для наглядности небось... чтобы показать что там производится работа с битами? ;)
          Ответить
          • «dex», щито? угу, wannabe bitmap, хотя это тоже и так понятно :-) 0x0 намекает на применение в офтальмологии
            Ответить
        • ээ, спасибо, кэп, конечно, но я о другом спрашивал
          Ответить
          • А, просто не сразу понял что Вы о файле говорите. Файл прост как пень, первый байт означает что изображение в формате RGB(Red,Green,Blue) - 0x0 или ARGB(Alpha, Red, Green, Blue) - 0x1, потом идут два 32-ух битных числа(4 байта) - ширина и высота, а потом пиксели изображения в формате 0xRRGGBB или 0xAARRGGBB.
            Ответить
            • а, понял, я-то подумал что этот байт - сигнатура формата, и сразу стало интересно, кто додумался узнавать «свои» файлы по нулевому байту :-)
              Ответить
    • Вот ведь любители задвинуть код подальше! Или любители лиспа?
      Ответить
      • скорее любители питона
        Ответить
        • Какой же я любитель ПХП, или питона? Я тольк она С-Решотка до этого проги писал.
          Ответить
    • жесть. в универе преподы били по рукам за operator[] ?

      тем более, что статические массивы - это безусловное зло.

      а что за хрень:
      if(b == 0x0)
      ведь <b> есть указатель, т.е. если
      b == NULL
      или другими словами malloc() не смог выделить байт памяти, то юзать malloc() опять? хитро
      Ответить
    • Не понимаю зачем в c++ коде использовать функции из Си?
      И не понятно что делает эта функция. Вернее что делает понятно, но результаты её так и остаются внутри. Не отдаваясь не через return, и нн неявно. А если изменяется какой-то глобальный метод, то это уже сильно, так как не вижу что функция в классе, а хранить и изменят глобальные переменные это слишком. Ладно если бы изменялись члены класса, но не так же.
      + когда это в cpp был сборщик мусора? Наверно нужно очищать всё что намусорили, а не оставлять все на съедение стёка.
      Ответить
      • Код на C++ с функциями из C в стиле C# :)
        Зачем там в цикле *rgb = malloc() каждый раз делается? Если уж хочется скушать памяти, можно это сделать как-то так:
        byte *rgb = (byte*)malloc(sizeof(byte) * 3 * width * height);
        fread(rgb, sizeof(byte), 3 * width * height, reader);
        , а уже циклами по массиву бегать.
        Ответить
        • показать все, что скрытоВ конечном итоге ф-ция приняла такой вид:
          void load(char *file)
          	{
          		reader = fopen((const char*)file, "r+b");
          		if(reader)
          		{
          			fseek(reader, 0L, SEEK_END);
          			long length = ftell(reader);
          			fseek(reader, 0L, SEEK_SET);
          			BYTE *buf = (BYTE*)malloc(sizeof(BYTE) * length);
          			fread(buf, sizeof(BYTE), length, reader);
          			
          			if(*buf == 0x0)
          			{
          				buf++;
          				BYTE *ibuf = (BYTE*)malloc(sizeof(BYTE) * sizeof(int));
          				for (int i = 0; i < sizeof(int); ++i)
          					*(ibuf + i) = *(buf + i);
          				width = (*(ibuf + sizeof(int) - 1) << (8 * 3)) | (*(ibuf + sizeof(int) - 2) << (8 * 2)) | (*(ibuf + sizeof(int) - 3) << 8) | (*ibuf);
          				buf += sizeof(int);	
          				for (int i = 0; i <sizeof(int); ++i)
          					*(ibuf + i) = *(buf + i);
          				height = (*(ibuf + sizeof(int) - 1) << (8 * 3)) | (*(ibuf + sizeof(int) - 2) << (8 * 2)) | (*(ibuf + sizeof(int) - 3) << 8) | (*ibuf);
          				buf += sizeof(int);
          				pixels = (Color**)malloc(sizeof(Color*) * width);
          				BYTE *rgb = (BYTE*)malloc(sizeof(BYTE) * 3);
          				for (int i = 0; i < width; ++i)
          				{
          					*(pixels + i) = (Color*)malloc(sizeof(Color) * height);
          					for (int j = 0; j < height; ++j)
          					{
          						for (int i = 0; i < 3; ++i)
          							*(rgb + i) = *(buf + i);
          						buf += sizeof(BYTE) * 3;
          						Color c = Color(0);
          						c.red = *(rgb) / 255.0;
          						c.green = *(rgb + 1) / 255.0;
          						c.blue = *(rgb + 2) / 255.0;
          						*(*(pixels + i) + j) = c;
          					}
          				}
          			}
          		}
          	}
          Ответить
          • суровый добротный говнокод

            чувак, мой тебе искренний совет: пожалей своих будущих пользователей и тех, кто будет потом твой код ковырять: смени профессию
            Ответить
            • Если бы все так сразу меняли профессию, никто бы вообще не работал.
              Учиться надо, а не рубить на корню.
              Ответить
            • Будущие пользователи у меня еще не скоро буду, для этого как минимум нужно кончить учиться, и на работу устроиться. И к тому же в этом проекте так много говна изза того что до этого я писал исключительно на C#, вот с непривычки и наговнокодил.
              Ответить
              • Странно как-то начинать с шарпов.
                Бейсику и Паскалю совсем не учили?
                Ответить
                • Ну конечно же все начиналось в кью-байсика, потом был ВБ, и уже потом был шарп.
                  ЗЫ. Меня никто не учил, сам все делал.
                  Ответить
          • хыхы пиздеееец
            Ответить
          • вот если бы в этом коде не было такого огроменного количества копипасты (иногда тормозной, а игногда просто противной) и было бы по-меньше вольшебных чисел -- кого был бы впринципе читаем.
            Ответить
            • Копипаста там нет(вообще ненавижу копипастить). Весь код из моей головы взялся. И учусь я исключительно на своих ошибках, а не на чужих.
              Ответить
              • >Копипаста там нет
                Копипастить можно и в пределах одной функции.
                >учусь я исключительно на своих ошибках
                Лучше всё же на чужих, их больше.
                Ответить
                • >Лучше всё же на чужих, их больше.
                  У каждого свое мнение. Я считаю что лучше на своих ошибках учиться.
                  Ответить
              • >>Копипаста там нет
                Сколько раз у Вас написана эта строчка "(*(ibuf + sizeof(int) - 1) << (8 * 3))" ?
                И такого там очень-очень много.
                Ответить
                • Два раза. И, то только потому что это еще не конечный вариант сейчас, это выделено в ф-цию.
                  Ответить
                  • ну так вынесте их в дефайны или в функции.

                    Кроме того между открывающей и закрывающей скобкой не должно быть более 20 строк.

                    //плохо:
                    if (someExpression) {
                    //тут 100500 строк
                    }
                    
                    //даже так уже лучше: 
                    if (! someExpression) { 
                    return; 
                    }
                    //тут 100500 строк


                    Уберите волшебные числа типа 3.

                    Я на сях давно не писал, и глаз у меня уже не тот, но мне кажется что не всю память, забранную у кучи mallocом Вы ей возвращаете.

                    В сях нет гарбич коллектора, и рано или поздно память утечет.
                    Ответить
                    • Плюс 1 за скобки.
                      Но вот давеча поговорил с тимлидером, он приверженец одной точки выхода.
                      Но завтра если не забуду, запощу, что у нас есть на эту тему.
                      Ответить
                      • тогда нужно выносить в функции:
                        if (someExpression) {
                        someOperationFor100500Lines();
                        } else {
                        otherOperationFor100500Lines();
                        }
                        Ответить
                        • 100500 строк полюбасу надо выводить куда-нибудь. В идеале КЕМ!
                          Ответить
                          • лучшее что можно сделать с кодом -- удалить его:)
                            лучший рефактроинг тот -- в результате которого файлы только удалились
                            Ответить
              • тогда учись: твой говнокод страдает от двух вещей: нет никого вывода об ошибках и подход "напролом"

                собственно мой вариант

                [spoiler]
                enum {
                		NO_ERROR = 0, 
                		CANNOT_OPEN_FILE = -1, 
                		INVALID_FORMAT = -2, 
                		HEADER_DATA_TRUNCATED = -3, 
                		PIXEL_DATA_TRUNCATED = -4
                };
                
                struct header_t {
                	enum signature_types { RGB = 0x0, ARGB = 0x1 };
                
                	byte signature;
                	int width;
                	int height;
                };
                
                struct pixel_t {
                	byte red;
                	byte green;
                	byte blue;
                };
                
                inline const int make_index(const header_t *header, const int w, const int h)
                {
                	return header->width * w + h;
                }
                
                int load(const char *file)
                {
                	/* WARNING: <fopen()> is unsafe */
                	reader = fopen(file, "r+b");
                	if(!reader)
                		return CANNOT_OPEN_FILE;
                
                	header_t header;
                	size_t bytes = fread(&header, sizeof(header), 1, reader);
                			
                	if(bytes < sizeof(header))
                		return HEADER_DATA_TRUNCATED;
                	
                	if(header.signature != header_t::RGB)
                		return INVALID_FORMAT;
                
                	if(header.height < 0 || header.width < 0)
                		return INVALID_FORMAT;
                	
                	pixel_t *pixel_data = (pixel_t *)malloc(sizeof(pixel_t) * header.width * header.height);
                	
                	bytes = fread(pixel_data, sizeof(pixel_t), header.width * header.height, reader);
                	
                	if(bytes < sizeof(pixel_t) * header.width * header.height)
                		return PIXEL_DATA_TRUNCATED;
                	
                	for(int w = 0; w < header.width; ++w)
                		for(int h = 0; h < header.height; ++h) {
                			
                			const pixel_t *pixel = &pixel_data[make_index(&header, w, h)];
                			pixels[w][h] = COLOR(pixel->red / 255.0, pixel->green / 255.0, pixel->blue / 255.0);
                		}
                	
                	free(pixel_data);
                	
                	return NO_ERROR;
                }

                [/spoiler]
                Ответить
                • и да если выделяешь память динамически, то ее как бэ и освобождать надо
                  Ответить
                • Вот нахуя в комментах такую какашню разводить?
                  Эй, Создатель, нужен тег СПОЙЛЕР срочно!
                  Ответить
                  • вот тебе спойлер pastebin.com
                    Ответить
                    • Я не для себя прошу, а чтобы не было комментов которые даже на мой рабочий экран не влезают.
                      Ответить
                      • Так у Вас рабочий экран не govnokod ready, небось?
                        Ответить
                        • Видимо покупавшие его и не подозревали, что я на говносайт пойду)
                          Ответить
                          • Скоро узнают по возросшему трафику и будет экран использоваться для истинных целей. Рабочих :)
                            Ответить
                • Ух бля, ебать говно - это призвание. man pitch aka stride, nomoar header->width * w + h;
                  Размеры могут быть и 0-ми в хедере, не советуй больше.
                  Ответить

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