# Jacek 'jsxm' Szwaj (K3I3) -- 10/11/2008, projekt w MIPS
# p.s -- Program skaluje bitmapê
#
############################################################

.data
        powitanie:     .asciiz "Program do skalowania bitmapy.\n"
        nlinia:                .asciiz "\n"
        parametr_1:    .asciiz "Podaj nazwe pliku wejsciowego:]$ "
        parametr_2:    .asciiz "Powiekszanie/zmniejszanie [p/z]:]$ "
        parametr_3:    .asciiz "Ile razy :]$ "
        parametr_4:    .asciiz "Podaj nazwe pliku wyjsciowego:]$ "
        debug:         .asciiz "DEBUG"
        we_plik:       .space 128
        wy_plik:       .space 128
        rodzaj:                .space 4
        ile_razy:      .space 4
        naglowek:      .space 54
        bufor_2:       .space 64
        obrazek:       .space 8000
        nowy_obrazek:  .space 50000
        tmp_obrazek:   .space 50000
        wiersz:                .space 1000

############################################################

.text
.globl main

#################################################
                                                                                                #
powiel_wiersz:                                                                  # Powielanie wiersza
        la              $t5,        wiersz                                 # Za³adowanie zapisanego wiersza
        li              $t0,        0                                           # Zerowanie licznika
                                                                                                #
        petla_pow_pw:                                                   # Zapisywanie wiersza
                        lb           $s4,     ($t5)                               #
                        addi $t5,    1                                  #
                                                                                                #
                        sb           $s4,     ($t9)                               #
                        addi $t9,    1                                  #
                                                                                                #
                        addi $t0, 1                                          #
                        bne          $t0, $s0, petla_pow_pw          # Konic pêtli
                la            $t5,      wiersz                                       # Ponowne za³adowanie wiersza
        b wstawiony_wiersz                                              # Powrót do kodu powiekszajacego wysokosc

zmn_sz_zeeroo:                                                                  # Funkcje zapisujace zero
        sb             $zero,     ($t9)                                               #
        addi   $t9,      1                                                    #
        b      zmn_sz_zero_ok                                                       #
        
p_sz_min_zero:                                                                  #
        sb             $zero,     ($t9)                                               #
        addi   $t9,      1                                                    #
        b p_sz_min_zero_ok                                                     #
#################################################

main:

####### Pobranie parametrow.
#################################################
                                                                                                #
        li     $v0, 4                                                                      # Wyswietlenie powitania
        la     $a0, powitanie                                                      #
        syscall                                                                                #

        li     $v0, 4                                                                      # Pytanie o nazwe pliku wejsciowego
        la     $a0, parametr_1                                                     #
        syscall                                                                                #

        li     $v0, 8                                                                      # Wczytanie nazwy pliku wejsciowego
        la     $a0, we_plik                                                        #
        li     $a1, 128                                                            #
        syscall                                                                                #

        li     $v0, 4                                                                      # Pytanie o nazwe pliku wyjsciowego
        la     $a0, parametr_4                                                     #
        syscall                                                                                #
                                                
        li     $v0, 8                                                                      # Wczytanie nazwy pliku wyjsciowego
        la     $a0, wy_plik                                                        #
        li     $a1, 128                                                            #
        syscall                                                                                #

        li     $v0, 4                                                                      # Pytanie o rodzaj skalowania        
        la     $a0, parametr_2                                                     #
        syscall                                                                                #

        li     $v0, 8                                                                      # Wczytanie rodzaju skalowania
        la     $a0, rodzaj                                                         #
        li     $a1, 4                                                                      #
        syscall                                                                                #
        
        li     $v0, 4                                                                      # Pytanie o skale
        la     $a0, parametr_3                                                     #
        syscall                                                                                #

        li     $v0, 8                                                                      # Wczytanie skali
        la     $a0, ile_razy                                                       #
        li     $a1, 4                                                                      #
        syscall                                                                                #
#################################################
####Zapis parametrów                                                    ##kody ascii hex
                                                                                                #
        la     $t0, rodzaj                                                         #
        lb     $t1, ($t0)                                                          #
        move $s1, $t1                                                          #
                                                                                                #
        la     $t0, ile_razy                                                       #
        lb     $t1, ($t0)                                                          #
                                                                                                #
#################################################
#### Zapis dziesietnej wartosci skali do $s2    #
                                                                                                #
        li     $s2, 4                                                                      #
        beq $t1, 0x34, skala_gotowa                                    #
        li     $s2, 3                                                                      #
        beq $t1, 0x33, skala_gotowa                                    #
        li     $s2, 2                                                                      #
        beq $t1, 0x32, skala_gotowa                                    #
        li     $s2, 1                                                                      #
        beq $t1, 0x31, skala_gotowa                                    #
        skala_gotowa:                                                          #
                                                                                                #
#################################################
####### Przygotowanie nazw plikow                               #
                                                                                                #
        li     $t0, 10                                                                     # Wrzucamy do $t0 znak '\n'
        la     $t1, we_plik                                                        # Wrzucamy do $t1 nazwe pliku wejsciowego
                                                
znajdz_nl:                                                                              # Szukamy znaku nowej linii, aby zastapic go zerem
        lb     $t2, ($t1)                                                          #
        addi   $t1, 1                                                            #
        beq    $t0, $t2, wstaw_zero                                       # Je¿eli w $t2 jest znak nowej linii, skocz do zmiany
        b      znajdz_nl                                                            #
                                                
wstaw_zero:                                                                             #
        sb     $zero, -1($t1)                                                      # Zamiana '\n' na '\0'
        la     $t1, wy_plik                                                        # Zaladowanie nazwy pliku wyjsciowego do $t1
                                                
znajdz_nl_2:                                                                    # Szukamy znaku nowej linii, aby zastapic go zerem
        lb     $t2, ($t1)                                                          #
        addi   $t1, 1                                                            #
        beq    $t0, $t2, wstaw_zero_2                                     # Je¿eli w $t2 jest znak nowej linii, skocz do zmiany
        b      znajdz_nl_2                                                          #
                                                
wstaw_zero_2:                                                                   #
        sb     $zero, -1($t1)                                                      # Zamiana '\n' na '\0'
        
#################################################

    #otwieranie pliku do odczytu
    li      $v0,    13
    la      $a0,    we_plik
    li      $a1,    0
    li      $a2,    0
    syscall
    #ZAPIS FILEDESCRIPTORA W $s7
    move    $s7,    $v0

    #wczytanie BITMAPFILEHEADER i BITMAPINFOHEADER
    li      $v0,    14
    move    $a0,    $s7
    la      $a1,    naglowek
    li      $a2,    54
    syscall
    
    #otwieranie pliku do zapisu
    li      $v0,    13
    la      $a0,    wy_plik
    li      $a1,    0x8301  #65
    li      $a2,    438     #511
    syscall
    #ZAPIS FILEDESCRIPTORA W $s6
    move    $s6,    $v0
    
#################################################
                                                                                                # WCZYTANIE ilosci bajtow w pliku
        la      $t0,    naglowek                                       #
        lw             $t8,       2($t0)                                                #
########## POWIEKSZENIE CZY ZMNIEJSZENIE (p/z)###

        beq    $s1, 0x7a, zmniejszanie                                    # 0x7a = 'z'
                                                                                                # Obliczenia nowych wymiarów
        lb      $t5, 18($t0)                                           #
        lb      $t7, 22($t0)                                           #
        mul            $t5, $t5, $s2                                             #
        mul            $t7, $t7, $s2                                             #
    sb      $t5, 18($t0)                                                # Zapisanie nowej szerokosci
    move        $s3, $t7                                                       # zapis do s3  wysokosci, potrzebna do dalszych obliczen
    move        $s0, $t5                                                       # zapis do s0  szerokosci, potrzebna do dalszych obliczen
    mul         $s0, $s0, 3                                                    #
        sb      $t7, 22($t0)                                           # Zapisanie nowej wysokosci
                                                                                                #
#################################################
                                                                                                #
        li      $v0,    15                                                     # Zapisanie naglowka do pliku
    move    $a0,    $s6                                                 #
        la             $t6,       naglowek                                      #
        move    $a1,    $t6                                                    #
        li      $a2,    54                                                     #
    syscall                                                                             #
                                                                                                #
#################################################
                                                                                                # Zapisywanie obrazka do pamieci
    li      $v0, 14                                                             #
    move    $a0, $s7                                                    #
    la      $a1, obrazek                                                #
    move    $a2, $t8                                                    #
    syscall                                                                             #
                                                                                                #
#################################################
                                                                                                # SKOPIOWANIE BITMAPY, powiekszenie,szerokosc
        li             $t4,       0                                                 # zerowani licznika
        la             $t7,       obrazek                                               # nasz obrazek w $t7
        la             $t9,       nowy_obrazek                          # miejsce na szerszy obrazek
petla_pow:                                                                              #
        lb             $s4,       ($t7)                                         # Wczytanie piksela
        addi   $t7,      1                                                    #
        beq            $s4,      0, p_sz_min_zero                     # sprawdzenie czy nie koniec wiersza
        lb             $s5,       ($t7)                                         #
        addi   $t7,      1                                                    #
        lb             $s8,       ($t7)                                         #
        addi   $t7,      1                                                    #
                                                                                                #
        li     $t3, 0                                                                   # Zerowanie licznika
        p_wst_znak:                                                                    # Powielanie piksela
                sb            $s4,      ($t9)                                        #
                addi  $t9,     1                                           #
                sb            $s5,      ($t9)                                        #
                addi  $t9,     1                                           #
                sb            $s8,      ($t9)                                        #
                addi  $t9,     1                                           #
                                                                                                #
                addi  $t3,     1                                           #
                bne           $t3, $s2, p_wst_znak                     # Warunek zakoñczenia petli
                                                                                                #
p_sz_min_zero_ok:                                                               #
        addi   $t4, 1                                                            #
        bne            $t4, $t8, petla_pow                                       # Warunek zakonczenia petli
################################################# SKOPIOWANIE BITMAPY, powiekszenie,wysokosc
        mul    $t8, $t8, $s2                                                      # domno¿enie, nowa ilosc bajtow
                                                                                                #
        li             $t4,       0                                                 # Ustawianie parametrów poczatkowych petli
        la             $t5,       wiersz                                                #
        la             $t7,       nowy_obrazek                          #
        la             $t9,       tmp_obrazek                                   #
        addi   $s3,      1                                                    #
        li             $t3,       0                                                 # Zerowanie licznika
                                                                                                #
petla_sz_w:                                                                             # G³ówna pêtla 
                petla_sz_w_min_w:                                             #
                        lb           $s4,     ($t7)                               #
                        addi $t7,    1                                  #
                                                                                                #
                        sb           $s4,     ($t9)                               # Zapis bajtu do bufora z nowym plikiem
                        addi $t9,    1                                  #
                                                                                                #
                        sb           $s4,     ($t5)                               # Zapis bajtu do bufora z wierszem
                        addi $t5,    1                                  #
                                                                                                #
                        addi $t3, 1                                          #
                        bne          $t3, $s0, petla_sz_w_min_w      #
                                                                                                #
                        li   $t2, 1                                                    #
                        przeskakuj_sz:                                               # Petla powielajaca wiersz $s2-razy
                                addi        $t2, 1                                 #
                                b powiel_wiersz                                     # Skok do funkcji powielajacej wiersz
                                wstawiony_wiersz:                           # Powrót z tej funkcji
                                bne         $t2, $s2, przeskakuj_sz        # Warunek zakoñczenia pêtli
                        li   $t3, 0                                               # Zerowanie licznika
                                                                                                #      
        addi   $t4, 1                                                            #
        bne            $t4, $s3, petla_sz_w                              #
                                                                                                #
mul     $t8, $t8, $s2                                                               # Domna¿anie o kolejny wymiar
                                                                                                #
b zapis_do_plik                                                                 ## KONIEC ROBOTY ZAPISUJEMY
#################################################
##### ZMNIEJSZANIE PLIKU
#################################################
zmniejszanie:                                                                   #
                                                                                                #Obliczenia nowych wymiarów
        lb      $t5,    18($t0)                                                #
        lb      $t7,    22($t0)                                                #
        div            $t5,$t5,  $s2                                              #
        div            $t7,$t7,  $s2                                              #
    sb      $t5,    18($t0)                                             #
    move        $s3,   $t7                                                       # zapis do s3  wysokosci, potrzebna do dalszych obliczen
    move        $s0,   $t5                                                       # zapis do s0  szerokosci, potrzebna do dalszych obliczen
    mul         $s0, $s0, 3                                                    #
        sb      $t7,    22($t0)                                                #
                                                                                                #
        li      $v0,    15                                                     # Zapisanie naglowka
    move    $a0,    $s6                                                 #
        la             $t6,       naglowek                                      #
        move    $a1,    $t6                                                    #
        li      $a2,    54                                                     #
    syscall                                                                             #
                                                                                                #
                                                                                                ### Zapisywanie zawartosci do pamieci
    li      $v0,    14                                                  #
    move    $a0,    $s7                                                 #
    la      $a1,    obrazek                                             #
    move      $a2,    $t8                                               #
    syscall                                                                             #
                                                                                                #
################################################# ZMNIEJSZENIE BITMAPY, zmniejszenie szerokosci
                                                                                                #
        li             $t4,       0                                                 #
        la             $t7,       obrazek                                               # Standardowno ustawiamy rejestry przed wykonaniem petli
        la             $t9,       nowy_obrazek                          #
        li     $t3, 1                                                                      # "Zerowanie" licznika, 1 bo petla while
petla_zmn_sz:                                                                   #
        lb             $s4,       ($t7)                                         # Wczytanie piksela
        addi   $t7,      1                                                    #
        beq            $s4,      0,   zmn_sz_zeeroo                     # Sprawdzenie czy nie koniec wiersza
        lb             $s5,       ($t7)                                         #
        addi   $t7,      1                                                    #
        lb             $s8,       ($t7)                                         #
        addi   $t7,      1                                                    #
                                                                                                #
        bne            $t3, $s2, p_zmn_znak                              # Miniecie $s2 pikseli
                sb            $s4,      ($t9)                                        #
                addi  $t9,     1                                           #
                sb            $s5,      ($t9)                                        #
                addi  $t9,     1                                           #
                sb            $s8,      ($t9)                                        #
                addi  $t9,     1                                           #
                li    $t3, 1                                                             #
                b omin_incr                                                           #
        p_zmn_znak:                                                                    #
                addi  $t3,     1                                           #
        omin_incr:                                                                     #
        zmn_sz_zero_ok:                                                                #
        addi   $t4, 1                                                            #
        bne            $t4, $t8, petla_zmn_sz                            #
                                                                                                #
################################################# ZMNIEJSZENIE BITMAPY, zmniejszenie wysokosci
        div    $t8, $t8, $s2                                                      # Podzielenie w celu uzyskania nowej wielkosci
                                                                                                #
        li             $t4,       0                                                 # Parametry poczatkowe analogicznie jak wczesniej
        la             $t7,       nowy_obrazek                          #
        la             $t9,       tmp_obrazek                                   #
        addi   $s3, 1                                                            #
        li     $t3, 1                                                                      #
petla_zmn_w:                                                                    # G³ówna petal
                petla_zmn_w_min_w:                                            #
                        lb           $s4,     ($t7)                               # Przepisanie liczby pikseli odpowiadajacej szerokosci
                        addi $t7,    1                                  #
                                                                                                #
                        sb           $s4,     ($t9)                               #
                        addi $t9,    1                                  #
                                                                                                #
                        addi $t3, 1                                          #
                        bne          $t3, $s0, petla_zmn_w_min_w     #
                                                                                                #
                        li   $t2, 1                                                    #
                        przeskakuj_w:                                                # Przeskoczenie $s2 wierszy
                                addi        $t2, 1                                 #
                                add         $t7, $t7, $s0                  #
                                bne         $t2, $s2, przeskakuj_w #
                                                                                                #
                        li   $t3, 1                                                    #
                                                                                                #
        addi   $t4, 1                                                            #
        bne            $t4, $s3, petla_zmn_w                             #      
                                                                                                #
div     $t8, $t8, $s2                                                               # Podzielenie w celu uzyskania nowej wielkosci
################################################# Zapisywanie zawartosci do pliku
                                                                                                #
zapis_do_plik:                                                                  #
    li      $v0,    15                                                  #
    move    $a0,    $s6                                                 #
        la             $t6, tmp_obrazek                                   #
        move    $a1,    $t6                                                    #
        move      $a2,    $t8                                          #
    syscall                                                                             #
                                                                                                #
#################################################  
end:                                                                                    #
                                                                                                # zamykanie pliku
        li      $v0,    16                                              #
        move    $a0,    $s7                                             #
        syscall                                                                 #
                                                                                                # zamykanie pliku
        li      $v0,    16                                              #
        move    $a0,    $s6                                             #
        syscall                                                                 #
                                                                                                #
                                                                                                #
                                                                                                #
#################################################
koniec:                                                                                 #
        li     $v0, 10                                                                    # Zakonczenie programu
        syscall                                                                                #
                                                                                                #
#################################################
####### koniec p.s