entry #1
written by olus2000
submitted at
3 likes
guesses
- Olivia (by Tæmt modʒiɹæ)
- Palaiologos (by Olivia)
- Palaiologos (by razetime)
- Palaiologos (by Edgex42)
- Palaiologos (by LyricLy)
- olus2000 (by Palaiologos)
comments 0
line_draw.asm magic text fragment for file(1) cmd, 1st line "#-------------------------------------------------------------------------------", 2nd line "#author: SoundOfSpouting#6980 (UID: 151149148639330304)"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 | #-------------------------------------------------------------------------------
#author: SoundOfSpouting#6980 (UID: 151149148639330304)
#date : 2022.08.12
#description : example RISC V program for drawing a line on a BMP file
#-------------------------------------------------------------------------------
# Recommended use with RARS simulator
# Assumes a simple RGB 24bpp .bmp image
# Coordinates originate from bottom left
# for purpose of this example I define structure which will contain important
# bitmap data for image read from the bmp file. Its C definition could be:
# struct {
# char* filename; // pointer to file name
# unsigned char* hdrData; // pointer to BMP header buffer
# unsigned char* imgData; // pointer to the first picture pixel in memory
# int width, height; // width and height in pixels
# int linebytes; // size of a line (in bytes)
# } imgInfo;
.eqv ImgInfo_fname 0
.eqv ImgInfo_hdrdat 4
.eqv ImgInfo_imdat 8
.eqv ImgInfo_width 12
.eqv ImgInfo_height 16
.eqv ImgInfo_lbytes 20
.eqv MAX_IMG_SIZE 230400 # 320 x 240 x 3 (pixels)
# more information about bmp format: https://en.wikipedia.org/wiki/BMP_file_format
.eqv BMPHeader_Size 54
.eqv BMPHeader_width 18
.eqv BMPHeader_height 22
# line is a structure which contains coordinaes of the line's ends and its color:
# struct {
# int x1, y1, x2, y2;
# char r, g, b;
# } line
.eqv Line_x1 0
.eqv Line_y1 4
.eqv Line_x2 8
.eqv Line_y2 12
.eqv Line_0rgb 16
.eqv Line_b 16
.eqv Line_g 17
.eqv Line_r 18
.eqv Line_0 19
.eqv system_OpenFile 1024
.eqv system_ReadFile 63
.eqv system_WriteFile 64
.eqv system_CloseFile 57
.eqv system_Exit 10
.eqv system_PrintChar 11
.eqv system_ReadInt 5
.eqv system_ReadStr 8
.eqv system_PrintStr 4
.macro exit
li a7, system_Exit
ecall
.end_macro
.macro print (%string_addr)
la a0, %string_addr
li a7, system_PrintStr
ecall
.end_macro
.macro input (%buff_addr, %buff_size)
la a0, %buff_addr
li a1, %buff_size
li a7, system_ReadStr
ecall
li a3, 10
find_endl:
lb a2, (a0)
beq a2, a3, found_endl
addi a0, a0, 1
addi a1, a1, -1
bgt a1, zero, find_endl
j end_input
found_endl:
sb zero, (a0)
end_input:
.end_macro
.macro int_input
li a7, system_ReadInt
ecall
.end_macro
.macro error (%message_addr)
print %message_addr
exit
.end_macro
.data
imgInfo: .space 24 # image descriptor
.align 2
dummy: .space 2
bmpHeader: .space BMPHeader_Size
.align 2
imgData: .space MAX_IMG_SIZE
.align 2
line: .space 20 # One 0 byte to make loading 0RGB values possible
ifname: .space 64
ofname: .space 64
iprompt: .asciz "Input file > "
oprompt: .asciz "Output file > "
lineprompt: .asciz "coordinates of line in separate lines (x1, y1, x2, y2):\n"
colorprompt: .asciz "color of the line in separate lines (r, g, b):\n"
openError: .asciz "Error reading file\n"
.text
main:
# Getting the input file name
print iprompt
input ifname 64
# filling the image descriptor
la a0, imgInfo
la t0, ifname
sw t0, ImgInfo_fname(a0)
la t0, bmpHeader
sw t0, ImgInfo_hdrdat(a0)
la t0, imgData
sw t0, ImgInfo_imdat(a0)
jal read_bmp
beqz a0, read_success
print openError
j main
read_success:
# Get the output file name and line
print oprompt
input ofname 64
la a1, line
print lineprompt
int_input
sw a0, Line_x1(a1)
int_input
sw a0, Line_y1(a1)
int_input
sw a0, Line_x2(a1)
int_input
sw a0, Line_y2(a1)
print colorprompt
sb zero, Line_0(a1)
int_input
sb a0, Line_r(a1)
int_input
sb a0, Line_g(a1)
int_input
sb a0, Line_b(a1)
la a0, imgInfo
la a1, line
jal draw_line
la a0, imgInfo
la t0, ofname
sw t0, ImgInfo_fname(a0)
jal save_bmp
exit
#============================================================================
# read_bmp:
# reads the content of a bmp file into memory
# arguments:
# a0 - address of image descriptor structure
# input filename pointer, header and image buffers should be set
# return value:
# a0 - 0 if successful, error code in other cases
read_bmp:
mv t0, a0 # preserve imgInfo structure pointer
#open file
li a7, system_OpenFile
lw a0, ImgInfo_fname(t0) #file name
li a1, 0 #flags: 0-read file
ecall
blt a0, zero, rb_error
mv t1, a0 # save file handle for the future
#read header
li a7, system_ReadFile
lw a1, ImgInfo_hdrdat(t0)
li a2, BMPHeader_Size
ecall
#extract image information from header
lw a0, BMPHeader_width(a1)
sw a0, ImgInfo_width(t0)
# compute line size in bytes - bmp line has to be multiple of 4
add a2, a0, a0
add a0, a2, a0 # pixelbytes = width * 3
addi a0, a0, 3
srai a0, a0, 2
slli a0, a0, 2 # linebytes = ((pixelbytes + 3) / 4 ) * 4
sw a0, ImgInfo_lbytes(t0)
lw a0, BMPHeader_height(a1)
sw a0, ImgInfo_height(t0)
#read image data
li a7, system_ReadFile
mv a0, t1
lw a1, ImgInfo_imdat(t0)
li a2, MAX_IMG_SIZE
ecall
#close file
li a7, system_CloseFile
mv a0, t1
ecall
mv a0, zero
jr ra
rb_error:
li a0, 1 # error opening file
jr ra
# ============================================================================
# save_bmp - saves bmp file stored in memory to a file
# arguments:
# a0 - address of ImgInfo structure containing description of the image`
# return value:
# a0 - zero if successful, error code in other cases
save_bmp:
mv t0, a0 # preserve imgInfo structure pointer
#open file
li a7, system_OpenFile
lw a0, ImgInfo_fname(t0) #file name
li a1, 1 #flags: 1-write file
ecall
blt a0, zero, wb_error
mv t1, a0 # save file handle for the future
#write header
li a7, system_WriteFile
lw a1, ImgInfo_hdrdat(t0)
li a2, BMPHeader_Size
ecall
#write image data
li a7, system_WriteFile
mv a0, t1
# compute image size (linebytes * height)
lw a2, ImgInfo_lbytes(t0)
lw a1, ImgInfo_height(t0)
mul a2, a2, a1
lw a1, ImgInfo_imdat(t0)
ecall
#close file
li a7, system_CloseFile
mv a0, t1
ecall
mv a0, zero
jr ra
wb_error:
li a0, 2 # error writing file
jr ra
# ============================================================================
# set_pixel - sets the color of specified pixel
#arguments:
# a0 - address of ImgInfo image descriptor
# a1 - x coordinate
# a2 - y coordinate - (0,0) - bottom left corner
# a3 - 0RGB - pixel color
#return value: none
#remarks - a0, a1, a2 values are left unchanged
set_pixel:
lw t1, ImgInfo_lbytes(a0)
mul t1, t1, a2 # t1 = y * linebytes
add t0, a1, a1
add t0, t0, a1 # t0 = x * 3
add t0, t0, t1 # t0 is offset of the pixel
lw t1, ImgInfo_imdat(a0) # address of image data
add t0, t0, t1 # t0 is address of the pixel
#set new color
sb a3,(t0) #store B
srli a3, a3, 8
sb a3, 1(t0) #store G
srli a3, a3, 8
sb a3, 2(t0) #store R
jr ra
# ============================================================================
.macro swap (%line_reg, %t1, %t2)
lw %t1, Line_x1(%line_reg)
lw %t2, Line_x2(%line_reg)
sw %t1, Line_x2(%line_reg)
sw %t2, Line_x1(%line_reg)
lw %t1, Line_y1(%line_reg)
lw %t2, Line_y2(%line_reg)
sw %t1, Line_y2(%line_reg)
sw %t2, Line_y1(%line_reg)
.end_macro
# ============================================================================
# draw_line - draws a line of a given color between two points
# arguments:
# a0 - address of ImgInfo image descriptor
# a1 - addres of Line descriptor
# return values:
# none
# remarks:
# assumes that line coords are within the image
# uses the fact that set_pixel only changes t0 and t1
draw_line:
addi sp, sp, -8
sw ra, 4(sp)
sw s1, 0(sp)
mv s1, a1
lw t4, Line_x1(s1)
lw t2, Line_x2(s1)
sub t4, t2, t4
lw t5, Line_y1(s1)
lw t2, Line_y2(s1)
sub t5, t2, t5
sltz t2, t4
add t2, t2, t2
addi t2, t2, -1
sub t4, t4, t2 # Actually aim for one pixel off diagonally
mul t2, t2, t4
sltz t3, t5
add t3, t3, t3
addi t3, t3, -1
sub t5, t5, t3 # This will make the line have nicer shape
mul t3, t3, t5
bgt t2, t3, along_y
along_x:
bgtz t4, along_x_after_swap
swap s1, t0, t1
sub t4, zero, t4
sub t5, zero, t5
along_x_after_swap:
lw a1, Line_x1(s1)
lw t2, Line_y1(s1)
li t3, 0
along_x_loop:
mul a2, t5, t3
div a2, a2, t4
add a2, a2, t2
lw a3, Line_0rgb(s1)
jal set_pixel
addi a1, a1, 1
addi t3, t3, 1
blt t3, t4, along_x_loop
j line_ret
along_y:
bgtz t5, along_y_after_swap
swap s1, t2, t3
sub t4, zero, t4
sub t5, zero, t5
along_y_after_swap:
lw t2, Line_x1(s1)
lw a2, Line_y1(s1)
li t3, 0
along_y_loop:
mul a1, t4, t3
div a1, a1, t5
add a1, a1, t2
lw a3, Line_0rgb(s1)
jal set_pixel
addi a2, a2, 1
addi t3, t3, 1
blt t3, t5, along_y_loop
line_ret:
lw s1, 0(sp)
lw ra, 4(sp)
addi sp, sp, 8
jr ra
|

post a comment