PageRenderTime 56ms CodeModel.GetById 14ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 0ms

/MedianaElka/main.asm

http://github.com/fiedukow/MedianaElka
Assembly | 546 lines | 499 code | 47 blank | 0 comment | 16 complexity | eb2e69466da668a6b5e766368019f1d3 MD5 | raw file
  1.data
  2#filename:	.asciiz "qt.bmp"
  3#new_filename:	.asciiz "output.bmp"
  4#.align 2
  5filename:	.space 64
  6new_filename:	.space 64
  7#.align 2
  8thanks:		.asciiz "\nProgram zakonczyl dzialanie, wynik dzialania zapisano w pliku "
  9question_s: 	.asciiz "Nazwa pliku do przerobienia (max. 64 znaki) > "
 10question_t:	.asciiz "Nazwa pliku do zapisania wyniku (max. 64 znaki; UPRAWNIENIA ZAPISU!) > "
 11newline: 	.asciiz "\n"
 12processing: 	.asciiz "Processing.."
 13dot:		.asciiz "."
 14
 15.align 2
 16fl: .space 4 # current 1st line pointer
 17sl: .space 4 # current 2nd line pointer
 18tl: .space 4 # current 3rd line pointer
 19pl: .space 4 # current proccesed line result
 20
 21.text
 22main:	
 23
 24# Register once set keep their value till the end:
 25# s1 - file descriptor of source
 26# s2 - width (same for both files) 
 27# s3 - height (same for both files) 
 28# s5 - file descriptor of result
 29# s6 - bytes in one line with complement
 30	
 31##################################################################################		
 32## ASKING USER FOR FILENAMES AND PROGRESSING IT
 33##################################################################################
 34
 35	## SYSCALL (print first question)
 36	li $v0,4 # print_string service
 37	la $a0,question_s # show place where the string is
 38	syscall # printf(question_s)
 39	
 40	## SYSCALL (take filename of file to process)
 41	li $v0, 8 # read_string service
 42	la $a0, filename #show place for source filename (global variable)
 43	li $a1, 64 # max. filename size is 64
 44	syscall # scanf(source_filename, 64)
 45
 46	## SYSCALL (print second question)				
 47	li $v0,4 # print_string service
 48	la $a0,question_t # show place where the string is
 49	syscall # printf(question_t)
 50	
 51	## SYSCALL (take filename of file for output)
 52	li $v0, 8 # read-string service
 53	la $a0, new_filename #show place for target filename (global variable)
 54	li $a1, 64 # max. filename size is 64
 55	syscall # scanf(target_filename, 64)
 56	
 57	#for(i=0;l[i]!='\n';++i);
 58	#l[i]='\0';
 59	# Change first \n to \0 in loaded filenames
 60	
 61	# changing in source_file
 62	li $t0, 0
 63	la $t1, filename
 64	no_nl:
 65	 	addu $t2,$t1,$t0
 66	 	lb $t3,0($t2)
 67	 	bne $t3,10,skip_nl
 68	 	sb $0, 0($t2)
 69	 	j no_nl_end
 70	 	skip_nl:
 71	 	addiu $t0,$t0,1
 72		j no_nl
 73	no_nl_end:
 74
 75	
 76	# changing in target_file	
 77	li $t0, 0
 78	la $t1, new_filename
 79	no_nln:
 80	 	addu $t2,$t1,$t0
 81	 	lb $t3,0($t2)
 82	 	bne $t3,10,skip_nln
 83	 	sb $0, 0($t2)
 84	 	j no_nl_endn
 85	 	skip_nln:
 86	 	addiu $t0,$t0,1
 87		j no_nln
 88	no_nl_endn:
 89	
 90	# Filenames are now valid (without \n in the end).
 91	# All register FREE
 92
 93
 94##################################################################################		
 95## OPENING FILES WITH AND FOR DATA
 96##################################################################################
 97
 98	## SYSCALL (open file for reading, $s1 is file descriptor)
 99	li $v0, 13 # open-file service
100	la $a0, filename # 0($s0) # set filename to read
101	li $a1, 0 # read-only flag
102	li $a2, 0 # ignore mode
103	syscall # open file, $v0 gets file-descriptior	
104	move $s1, $v0 # let s1 be file descriptor for old file
105	
106	## SYSCALL (open file for writing (for save the result of program))
107	li $v0, 13 # open-file service
108	la $a0, new_filename # show file to write to
109	li $a1, 1 # write flag
110	li $a2, 0 # ignore mode
111	syscall # open result file for writing, $v0 gets descriptor
112	move $s5, $v0 # let s5 be file descriptor for new file
113	
114	# Now needed files are opened
115	# For now:
116	# $s1 is source file descriptor
117	# $s5 is target file descriptor
118
119
120##################################################################################		
121## LOADING PROCESSING AND SAVING HEADER OF BITMAP
122##################################################################################
123
124	addiu $sp,$sp,-54 # make place for header (from old bmp)		
125	
126	## SYSCALL (read 54B of file to $t0 (place on stack))
127	li $v0, 14 # read-from-file service
128	move $a0,$s1 # give system file descriptor
129	la $a1,0($sp) # show place to write ($t0)
130	li $a2,54 # set 54B limit to read (header size)
131	syscall # read header of bmp
132
133	# Read bmp dimensions from header just read
134	lhu $s2,0x12($sp) # read width (stored on 2B)
135	lhu $s3,0x16($sp) # read height (stored on 2B)
136	
137	## SYSCALL (write 54B from stack to result file (header without any changes))
138	li $v0, 15 # write-to-file service
139	move $a0, $s5 # give system file dscriptor
140	la $a1, 0($sp) # show place to write from ($t0)
141	li $a2, 54 #set 54B as number of bytes to write to file
142	syscall # write header to reslut file
143	
144	addiu $sp,$sp,54 # free stack of header information
145	
146	# Now header is written to target file
147	# For now:
148	# $s2 is width of image
149	# $s3 is height of image
150	
151
152##################################################################################		
153## JUST END UP PROGRAM IF FILE IS TO SMALL FOR THIS FILTER
154##################################################################################
155
156	blt $s2,3,exit # if file is to small
157	blt $s3,3,exit # just do nothing about it
158	#@todo: probably it should rewrite image without any changes
159	
160	# Now program ends if file is smaller then 3x3 in at least one dimension
161	
162##################################################################################		
163## CALCULATING LINE SIZE IN BYTES
164##################################################################################
165
166	## $t1 - 3 constans
167	li $t1,3
168	mult $s2,$t1 # 3 bytes describing one pixel in BMP (R,G,B)
169	mflo $s6 # assuming 32 bits is enough for line size in bytes
170		
171	## $t1 - FREE
172		
173	## $t1 - width mod 4, with is number of bytes in complement
174	andi $t1,$s2,0x00000003 # $t4 = width % 4
175	addu $s6,$t1,$s6 # $s6 - is actual number of bytes in line now
176	
177	## $t1 - FREE
178	
179	# For now:
180	# $s6 is number of bytes in line with complement
181	
182##################################################################################		
183## READING FIRST LINES (SAVING ONE OF THEM), PREPARING STACK FOR 4 LINES (3 readed, 1 for progress)
184##################################################################################
185		
186	subu $sp,$sp,$s6 # prepare stack to store the line 1
187	sw $sp,tl #save 3rd line pointer
188		
189	subu $sp,$sp,$s6 # prepare stack to store the line 2
190	sw $sp,sl #save 2nd line pointer
191	
192	subu $sp,$sp,$s6 # prepare stack to store the line 3
193	sw $sp,fl #save 1st line pointer
194	
195	subu $sp,$sp,$s6 # prepare stack to store the result line
196	sw $sp,pl #save result (processing) line pointer
197
198	
199	## SYSCALL (read first line from source file)
200	li $v0, 14 # read-from-file service
201	move $a0, $s1 # show system file descriptor
202	lw $t0, fl
203	la $a1, 0($t0) # show system place for writing
204	move $a2, $s6 # limit is the line size
205	syscall # read whole line	
206	
207	## SYSCALL (read second line from source file)		
208	## $t0 - place to write to next line
209	li $v0, 14 # read-from-file service
210	lw $t0, sl
211	la $a1, 0($t0)
212	syscall # read whole line
213	
214	## SYSCALL (read third line from source file)
215	li $v0, 14 # read-from-file service	
216	lw $t0, tl
217	la $a1, 0($t0)
218	syscall # read whole line	
219	## $t0 - FREE	
220	
221	
222	## SYSCALL (write first line to file (it dosn't change anyway)
223	li $v0, 15 # write-to-file service
224	move $a0, $s5 # show system file descriptor 
225	lw $t0, fl
226	la $a1, 0($t0) # show system place to read from
227	move $a2, $s6 # write a line size from showed pointer
228	syscall # write whole line
229	
230	# Now there is place on stack for 4 lines
231	# 3 lines are loaded
232	# first line is already in target file
233	# There are adresses of begining of first, second, third & processing line in memory under fl,sl,th,pl
234	
235	
236##################################################################################		
237## LOOPING THROUGH THE LINES
238##################################################################################
239			
240	## $s7 - loop marker for a while
241	move $s7, $s3	
242	addu $s7, $s7, -3 #3 lines already loaded
243	
244	# SYSCALL (printf info about begining of progressing)
245	li $v0,4 # print_string service
246	la $a0,processing # show adres to read from
247	syscall # printf(Processing..)
248	
249		
250p3l_loop: #process 3 lines loops	
251	
252	# SYSCALL (printf dot for every line you progress)
253	li $v0,4 # print_string service
254	la $a0,dot # show adress to read from
255	syscall # printf(.)
256	
257##################################################################################		
258## NOW 3 LINES ARE ON STACK (showed by fl,sl,tl) ACCTUAL PROCESSING HERE, LOOPING THROUGH BLOCKS IN LINE
259##################################################################################
260
261	li $t7, 1 # t7 is acctual pixel (from 1 to width-1)
262	addu $sp,$sp,-36 # make place on stack for brightness & pixel id
263
264prl: 
265
266	# WRITE TO RESULT LINE FIRST AND LAST PIXEL (UGLY BUT PROBABLY BETTER THEN LOOP)
267	lw $t1, sl
268	lw $t2, pl
269	lb $t3, 0($t1)
270	sb $t3, 0($t2)
271	lb $t3, 1($t1)
272	sb $t3, 1($t2) 
273	lb $t3, 2($t1)
274	sb $t3, 2($t2)
275	mul $t4,$s2,3
276	addu $t1, $t1, $t4
277	addu $t2, $t2, $t4
278	lb $t3, -3($t1)
279	sb $t3, -3($t2)
280	lb $t3, -2($t1)
281	sb $t3, -2($t2)
282	lb $t3, -1($t1)
283	sb $t3, -1($t2)
284	# WRITE TO RESULT LINE FIRST AND LAST PIXEL - END
285	
286	# Loading brightness with ids of acctual block		
287	beq $t7,$s2,prl_end
288	li $t9,0
289	lbl:	
290		bge $t9,9,lbl_end # only ids 0-8 will be loaded
291		move $a0,$t9 # show the procedure id of pixel to load
292		jal take_pixel_b #call procedure, there is result in $a0
293		mul $t8,$t9,4 # calculete place on stack for becomed value
294		addu $t8,$t8,$sp
295		sw $a0, 0($t8) # store becomed pair id, brightness
296		addiu $t9,$t9,1 # progress next pixel in block
297		j lbl
298	lbl_end:
299	
300	
301	# Brightness with ids on stack now! sort and change center now.
302	
303	# Sorting brightnesses with ids (quick buble)
304	li $t0,0
305	li $t9,1
306	sort:
307		beq $t0, 5, sort_end
308		beqz $t9, sort_end
309		li $t1,0
310		li $t9, 0
311		sort_in:
312			li $t8,8
313			subu $t8, $t8, $t0
314			beq $t1, $t8, sort_in_end
315			mul $t2,$t1,4
316			addu $t2, $sp, $t2
317			lh $t3, 0($t2)
318			lh $t4, 4($t2)
319			bge $t4,$t3,skip_swap
320			li $t9,1
321			lw $t3, 0($t2)
322			lw $t4, 4($t2)
323			sw $t4, 0($t2)
324			sw $t3, 4($t2)
325			skip_swap:
326			addiu $t1,$t1,1
327			j sort_in
328		sort_in_end:
329		addiu $t0,$t0,1
330		j sort
331	sort_end:	
332	
333	#brightness sorted here, just change pixel to valid value now
334	lw $a0, 16($sp) # show procedure id to take for writing (pair id, brightness in $a0 now)
335	srl $a0,$a0,16 #show procedure id to take for writing (only id in $a0 now)
336	jal write_pixel # call procedure - it will do rest of things needed
337	# now $t0 is valid pixel id
338	
339	
340				
341	addiu $t7,$t7,1 # progress next block
342	j prl
343prl_end:
344
345	addu $sp,$sp,36 # free place on stack needed for brightnesses with ids
346
347	# Now whole line is processed and the result is on place showed by pl
348
349##################################################################################		
350## Saving acctual line if it isnt end						
351##################################################################################		
352
353	beqz $s7, end_p3l_loop #when no more lines, end loop
354	
355	## SYSCALL (write line to file)
356	li $v0, 15 # write-to-file service
357	move $a0, $s5 # show system file descriptor 
358	lw $t0, pl
359	la $a1, 0($t0) # show system place to read from
360	move $a2, $s6 # write a line size from showed pointer
361	syscall # write whole line (processed, with is next in order)
362	
363	## SYSCALL (read next line from source file)
364	li $v0, 14 # read-from-file service
365	move $a0, $s1 # show system file descriptor
366	lw $t0, fl
367	la $a1, 0($t0) # show system place for writing
368	move $a2, $s6 # limit is the line size
369	syscall # read whole line (next in order)
370	
371	# swap fl,sl,tl (new order)
372	## t0,$t1,$t2 - tmp value for swap
373	lw $t0,fl
374	lw $t1,sl
375	lw $t2,tl	
376	sw $t1,fl
377	sw $t2,sl
378	sw $t0,tl
379	## t0,$t1,$t2 - free
380
381	addiu $s7,$s7,-1 # process next line
382	j p3l_loop # }
383end_p3l_loop: 
384
385	# Now all lines are processed and all without last 2 are saved in target file
386
387##################################################################################		
388## Saving last two lines, free stack
389##################################################################################
390
391	## SYSCALL (write line to file)
392	li $v0, 15 # write-to-file service
393	move $a0, $s5 # show system file descriptor 
394	lw $t0, pl
395	la $a1, 0($t0) # show system place to read from
396	move $a2, $s6 # write a line size from showed pointer
397	syscall # write whole line
398
399	## SYSCALL (write next line to result file)
400	li $v0, 15 # write-to-file service
401	lw $t0, tl
402	la $a1, 0($t0)
403	syscall # write whole line
404
405	## $s7 - FREE
406	# free stack of line information
407	addu $sp,$sp,$s6
408	addu $sp,$sp,$s6
409	addu $sp,$sp,$s6
410	addu $sp,$sp,$s6
411	
412	# Now all lines are saved and stack is free, its about the end
413
414	
415exit:
416	## SYSCALL (close source file)
417	li $v0, 16 # file-close service
418	la $a0, 0($s1) # show system source file descirptor
419	syscall # close fd1 (source file)
420	
421	## SYSCALL (close result file)
422	li $v0, 16 # file-close service
423	la $a0, 0($s5) # show system result file descriptor
424	syscall # close fd2 (result file)
425	
426	## SYSCALL (print exit msg)
427	li $v0, 4 # print_string
428	la $a0, thanks # show adress of end msg
429	syscall # print(thanks)
430	la $a0, new_filename # show adress of end msg param
431	syscall # print(thanks_param)
432	la $a0, newline # show adress of new line symbol
433	syscall # print(nl)
434	
435	
436	## SYSCALL (end program)
437	li $v0, 10
438	syscall # exit program
439	
440take_pixel_b: # calculate $a0 pixel in block brightness and save in $a0 with id on more imporant 4 bits, need $t7 (acctual block offset) & fl,sl,tl to be set
441	# now sl+t1*pixel_size is acctual block center
442	# where pixel_size is 3bytes (R,G,B)	
443	ble $a0,2,rfl
444	ble $a0,5,rsl
445	 
446	#read from 3rd line
447	lw $t2, tl
448	addiu $t6,$a0,-6
449	j end_read
450	
451	rsl:
452	#read from 2nd line
453	lw $t2, sl 
454	addiu $t6,$a0,-3	
455	j end_read
456	
457	rfl:
458	#read from 1st line
459	lw $t2, fl 	
460	move $t6,$a0
461	 
462	end_read:
463	# now $t2 is begin of needed line counter
464	# and $t6 is pixel number in this line (with offset in $t0)
465	
466	mul $t3, $t7, 3
467	mul $t6, $t6, 3
468	addiu $t3, $t3, -3
469	addu $t3, $t3, $t6
470	addu $t3, $t3, $t2
471	# now $t3 shows needed pixel adress
472	
473	lb $t4,0($t3)
474	andi $t4,$t4,0x000000ff
475	lb $t5,1($t3)
476	andi $t5,$t5,0x000000ff
477	addu $t4,$t4,$t5
478	lb $t5,2($t3)
479	andi $t5,$t5,0x000000ff
480	addu $t4,$t4,$t5
481	# t4 is calculated brightness now
482	
483	sll $a0,$a0,16   #make pair id brightness
484	addu $a0,$a0,$t4 #..
485	
486	jr $ra
487
488
489write_pixel: # write $a0 pixel to 4pixel in block, need $t7 (acctual block offset) & fl,sl,tl to be set
490	# now sl+t1*pixel_size is acctual block center
491	# where pixel_size is 3bytes (R,G,B)	
492	ble $a0,2,rflw
493	ble $a0,5,rslw
494	
495	#read from 3rd line
496	lw $t2, tl
497	addiu $t6,$a0,-6
498	j end_readw
499	
500	rslw:
501	#read from 2nd line
502	lw $t2, sl 
503	addiu $t6,$a0,-3	
504	j end_readw
505	
506	rflw:
507	#read from 1st line
508	lw $t2, fl 	
509	move $t6,$a0
510	
511	end_readw:
512	# now $t2 is begin of needed line counter
513	# and $t6 is pixel number in this line (with offset in $t0)
514	
515	mul $t3, $t7, 3
516	
517	lw $t5,pl
518	addu $t5,$t5,$t3
519	
520	mul $t6, $t6, 3
521	addiu $t3, $t3, -3
522	addu $t3, $t3, $t6
523	addu $t3, $t3, $t2
524	# now $t3 shows needed pixel adress
525	
526
527	
528	lb $t4,0($t3)
529	andi $t4,$t4,0x000000ff
530	sb $t4,0($t5)
531	
532	#write new R
533	
534	lb $t4,1($t3)
535	andi $t4,$t4,0x000000ff
536	sb $t4,1($t5)
537	
538	#write new G
539	
540	lb $t4,2($t3)
541	andi $t4,$t4,0x000000ff
542	sb $t4,2($t5)
543	
544	#write new B
545	
546	jr $ra